从Google工作表添加事件到Google日历使用Excel CSV模板到Google日历导入格式和提醒

nwo49xxi  于 2023-07-31  发布在  Go
关注(0)|答案(2)|浏览(132)

使用来自这个answer的@Tanaike的第二个模型脚本,如何重新构造它,使其适合Excel CSV模板以Google Calendar导入格式?
例如,使用Excel CSV格式输入:
| 开始日期|开始时间|结束日期|结束时间|全天活动|项目名称|所在地|私人的|提醒|创建| Created |
| --|--|--|--|--|--|--|--|--|--| ------------ |
| 2019 - 07 - 19 00:00:00|十点整|2019 - 07 - 19 00:00:00|十点零三分|假的|MyDesc1|我的位置1|假的|三个|||
| 2019 - 07 - 19 00:00:00|下午4点|2019 - 07 - 19 00:00:00| 14:03:00|假的|MyDesc2| MyLocation2|真||||
| 2019 - 07 - 19 00:00:00| 18点15分|2019 - 07 - 19 00:00:00| 18点18分|假的|MyDesc3|我的位置3|假的|三个|||
Tanaike的代码与我的修改遇到困难的阶段:

/*
  var subj = ss.getRange("A2:A" + lr).getValues(); // data[i][1]
  var stad = ss.getRange("B2:B" + lr).getValues(); // data[i][2]
  var Stat = ss.getRange("C2:C" + lr).getValues(); // data[i][3]
  var endd = ss.getRange("D2:D" + lr).getValues(); // data[i][4]
  var endt = ss.getRange("E2:E" + lr).getValues(); // data[i][5]
  var alde = ss.getRange("F2:F" + lr).getValues(); // data[i][6]
  var desc = ss.getRange("J2:J" + lr).getValues(); // data[i][7]
  var loca = ss.getRange("H2:H" + lr).getValues(); // data[i][8]
  var priv = ss.getRange("I2:I" + lr).getValues(); // data[i][9]
  var remi = ss.getRange("J2:J" + lr).getValues(); // data[i][10]
  var crea = ss.getRange("K2:K" + lr).getValues(); // data[i][11]
 */

function addEvents() {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var lr = ss.getLastRow();
  var cal = CalendarApp.getCalendarById("c_fe882662e583725f15fd4faa8c8fdf5124f3affe543778ecdcf0838d6eb17f26@group.calendar.google.com");
  var data = ss.getRange("A2:K" + lr).getValues();
  while (data[data.length - 1][0] == '') data.pop();
  var rangeList = [];
  for (var i = 0; i < data.length; i++) {
    if (data[i][11] == "created") continue;
    cal.createEvent(data[i][2]*data[i][3], data[i][4]*data[i][5], data[i][6], { location: data[i][8], description: data[i][7] }); // not sure about boolean logic use to combine date and time
    // ? cal.addPrivate(data[i][9]); // How do we add the private data?
    cal.addPopupReminder(data[i][10]);
    rangeList.push(`R${i + 3}`); // not sure about that line (It seems to add to the empty list at i +3 https://spreadsheet.dev/array-method-push-in-apps-script
  }
  if (rangeList.length == 0) return;
  ss.getRangeList(rangeList).setValue("created");
}

字符串
Google日历的人似乎没有在Excel CSV模板中包含简单的提醒要求。
我们如何解决这个问题?这个想法是有一个CSV像谷歌工作表工作表导入11列的例子到谷歌日历上。
我发现了多个类似的问题,旧的和最近的,但没有可行的建议:
发现了两个最相关的问题:
https://webapps.stackexchange.com/questions/112517/importing-reminders-to-google-calendar-using-csv-file
Add events from Google sheets to google calendar
和教程材料:
https://wafflebytes.blogspot.com/2017/06/google-script-setting-up-reminder-dates.html
提醒:
Google Script All Day Calendar Event with Notification On The Day
https://developers.google.com/apps-script/reference/calendar/calendar-event-series#addPopupReminder(Integer)
防止重复:
Create Google Calendar Events from Spreadsheet but prevent duplicates
Excel CSV格式:
https://www.reddit.com/r/excel/comments/k38xsf/comment/ge19zu6/?utm_source=share&utm_medium=web2x&context=3
班级日历:
https://developers.google.com/apps-script/reference/calendar/calendar

编辑:

@Tanaike - Can I ask you about the detail of your input and output situation?,@SputnikDrunk2 - How do you use the Excel CSV file in your use case?Do you upload it to your Drive, or do you view it in a spreadsheet file?
当然,谢谢你们的澄清,对不起我的糟糕的提法。
我将使用修改后的/ @Tanaike脚本直接从Google表格导入Google表格输入,而不是从CSV文件导入,但我想使用与the default Excel CSV file sample相同的格式,并从下表中增加11列:
| 开始日期|开始时间|结束日期|结束时间|全天活动|项目名称|所在地|私人的|提醒|创建| Created |
| --|--|--|--|--|--|--|--|--|--| ------------ |
| 2019 - 07 - 19 00:00:00|十点整|2019 - 07 - 19 00:00:00|十点零三分|假的|MyDesc1|我的位置1|假的|三个|||
| 2019 - 07 - 19 00:00:00|下午4点|2019 - 07 - 19 00:00:00| 14:03:00|假的|MyDesc2| MyLocation2|真||||
| 2019 - 07 - 19 00:00:00| 18点15分|2019 - 07 - 19 00:00:00| 18点18分|假的|MyDesc3|我的位置3|假的|三个|||
我用Andres Duarte's suggestion help更正并修改了我以前版本的@Tanaike代码,如下所示:

/*
  var subj = ss.getRange("A2:A" + lr).getValues(); // data[i][0]
  var stad = ss.getRange("B2:B" + lr).getValues(); // data[i][1]
  var stat = ss.getRange("C2:C" + lr).getValues(); // data[i][2]
  var endd = ss.getRange("D2:D" + lr).getValues(); // data[i][3]
  var endt = ss.getRange("E2:E" + lr).getValues(); // data[i][4]
  var alde = ss.getRange("F2:F" + lr).getValues(); // data[i][5]
  var desc = ss.getRange("J2:J" + lr).getValues(); // data[i][6]
  var loca = ss.getRange("H2:H" + lr).getValues(); // data[i][7]
  var priv = ss.getRange("I2:I" + lr).getValues(); // data[i][8]
  var remi = ss.getRange("J2:J" + lr).getValues(); // data[i][9]
  var crea = ss.getRange("K2:K" + lr).getValues(); // data[i][10]
 */

function addEvents() {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var lr = ss.getLastRow();
  var cal = CalendarApp.getCalendarById("YOURGOOGLECALENDARIDHERE");

  var data = ss.getRange("A2:K" + lr).getValues();

  var dateANDTimeArr = ss.getRange("A2:K" + lr).getDisplayValues(); // getDisplayValues is needed for the .substring() methods below to work

  while (data[data.length - 1][0] == '') data.pop();
  var rangeList = [];
  for (var i = 0; i < data.length; i++) {
    if (data[i][11] == "created") continue;

    var theEventStartDate = dateANDTimeArr[i][1]; // Extract the Date values from Column B
    var startHour = dateANDTimeArr[i][2].substring(0, 2); // Extract The Hour values from Column C
    var startMin = dateANDTimeArr[i][2].substring(3, 5); // Extract The Minutes values from Column C
    
    var theEventEndDate = dateANDTimeArr[i][3]; // Extract the Date values in Column D
    var endHour = dateANDTimeArr[i][4].substring(0, 2); // Extract The Hour values from Column E
    var endMin = dateANDTimeArr[i][4].substring(3, 5); // Extract The Minutes values from Column E

    Logger.log("theEventStartDate : " + theEventStartDate);
    Logger.log("startHour : " + startHour);
    Logger.log("startMin : " + startMin);

    Logger.log("theEventEndDate : " + theEventEndDate);
    Logger.log("endHour : " + endHour);
    Logger.log("endMin : " + endMin);

    var startDate = new Date(theEventStartDate + " " + startHour + ":" + startMin + ":00"); // Combine the Dates and The Times values from Columns B and C into one value as needed by createEvent() method
    var endDate = new Date(theEventEndDate + " " + endHour + ":" + endMin + ":00"); // Combine the Dates and The Times from Columns D and E into one value as needed by createEvent() method

    // Logger.log("startDate : " + startDate);
    // Logger.log("endDate : " + endDate);

    cal.createEvent(data[i][0], startDate, endDate, { location: data[i][7], description: data[i][6] });
    
    cal.isAllDayEvent(data[i][5]); // need to set it according to Column 5 input
    
    // Logger.log("cal.setVisibility(CalendarApp.Visibility.PRIVATE)(data[i][8]) : " + cal.setVisibility(CalendarApp.Visibility.PRIVATE)(data[i][8]));
    
    cal.setVisibility(CalendarApp.Visibility.PRIVATE)(data[i][8]); // https://developers.google.com/apps-script/reference/calendar/calendar-event#setvisibilityvisibility https://stackoverflow.com/a/34909992/10789707

    cal.addPopupReminder(data[i][9]);

    rangeList.push(`R${i + 3}`); // not sure about that line (It seems to add to the empty list at i +3 https://spreadsheet.dev/array-method-push-in-apps-script
  }
  if (rangeList.length == 0) return;
  ss.getRangeList(rangeList).setValue("created");
}

遗留问题:

第一个问题:

  • 全天活动栏:*

x1c 0d1x的数据
正如你在上面的屏幕截图中看到的,我找到了isAllDayEvent()方法,但它不接受参数,因此我无法向它提供我在Google Sheet输入中准备的第6列中设置的硬编码布尔值的预制列表。您建议使用什么解决方法来允许列6输入设置AllDayEvent参数?我在文档中寻找了一个setAllDayEvent()方法,但是google calendar的人没有提供。
第二个问题:

  • Private / setVisibility()列:*
TypeError: cal.setVisibility is not a function



与前面相同的问题,但使用setVisibility()方法。我如何使用一个变通方法来提供它的预制列表的硬编码布尔值设置在第8列我准备在谷歌工作表输入。
第三个问题:

  • Private / addPopupReminder()列:*
TypeError: cal.addPopupReminder is not a function

与之前相同的问题,但使用addPopupReminder()方法。我如何使用一个变通方法来提供它的预制列表的硬编码整数值设置在第9列我准备在谷歌工作表输入。

doinxwow

doinxwow1#

替代建议

  • 注**:如果您认为您的问题被误解了,请再次澄清,并附上您的数据和预期结果的示例。

根据你的问题,我理解你正在做这个过程:

  • 根据工作表中的Created表头添加eventall-day event
  • 如果行具有空值,则将其作为事件添加。
  • 否则,不执行任何操作(表示该行已经创建)。
  • 创建事件时,将基于工作表中的全天事件表头。
  • 如果该行有true值,则将其添加为全天事件
  • 如果是false,则添加为事件
  • 添加eventall-day event后,将Created标题下的行值更新为“created”。

我已经重构了你的脚本,并将其拆分为可管理的部分。您可以查看下面的调整脚本。

  • 调整脚本[已更新]*
function addEvents() {
  var range = SpreadsheetApp.getActive().getActiveSheet().getDataRange();
  var rawData = range.getDisplayValues().filter(row => !row.join('').trim().length <= 0 ); //Filter 'rawData' & not include empty rows.

  //Add events based on the header named 'Created'. If a row has an empty value, it will call the function 'addCurrentEvent'; otherwise, it will be ignored.
  var result = rawData.map(column => {
    return !column[10].match(/created/i) ? column.map((cell, index) => index == 10 ? addCurrentEvent(column) : cell) : column
  });

  //Sets the sheet range (w/ actual rows that have data) with updated values.
  SpreadsheetApp.getActive().getActiveSheet().getRange(range.getA1Notation().replace(/(K)\d+$/, `$1${result.length}`)).setValues(result);
}

function addCurrentEvent(column) {
  var cal = CalendarApp.getCalendarById("••••••••••••••");
  var startDate = new Date(`${column[1]} ${column[2]}`);
  var endDate = new Date(`${column[3]} ${column[4]}`);
  var visibility = column[8].toLowerCase() == 'true' ? CalendarApp.Visibility.PRIVATE : CalendarApp.Visibility.PUBLIC;

  //'addEvent' will be called to run when creating an EVENT.
  const addEvent = (data) => {

    cal.createEvent(data[0], startDate, endDate, {
      location: data[7],
      description: data[6]
    }).setVisibility(visibility).addPopupReminder(parseFloat(data[9]));

    //Log for review
    console.log(`"${data[0]}" event has been added!\n\nDETAILS\n\nStart date: ${startDate}\nEnd date: ${endDate}\nLocation: ${data[7]}\nDescription: ${data[6]}\nPrivacy: ${visibility}`);

    return `created`; //returns a 'created' value once the sheet row has been added
  };

  //'addAllDayEvent' will be called to run when creating an ALL DAY EVENT.
  const addAllDayEvent = (data) => {

    cal.createAllDayEvent(data[0], startDate, {
      location: data[7],
      description: data[6]
    }).setVisibility(visibility).addPopupReminder(parseFloat(data[9]));

    //Log for review
    console.log(`"${data[0]}" all day event has been added!\n\nDETAILS\n\nStart date: ${startDate}\nEnd date: ${endDate}\nLocation: ${data[7]}\nDescription: ${data[6]}\nPrivacy: ${visibility}`);

    return `created`; //returns a 'created' value once the sheet row has been added
  };

  //Check and run the current data if it is an 'All Day Event' or an 'Event'
  return column[5].toLowerCase() == 'true' ? addAllDayEvent(column) : addEvent(column);
}

字符串

  • 演示 *
    • 假床单 *
  • 例如,MyEvent2将是一个全天活动,应该是私人的。*


的数据

    • 运行addEvents函数后:*


    • 事件已创建:*

    • 更新的虚拟表:*

    • MyEvent2是作为全天活动添加的,它是私人的。*

    • 其他事件 *

46scxncf

46scxncf2#

虽然,不幸的是,我不能理解but I would like to use the same format as the default Excel CSV file sample sightly augmented as with the 11 columns from the table below:.。如果你想使用已经导入的电子表格中的值,下面的答案如何?
因此,这个答案假设您的值已经导入到电子表格中,并且脚本直接从电子表格中检索值。请小心点。

修改要点:

  • 关于1st problem:2nd Problem:3rd Problem:isAllDayEventsetVisibilityaddPopupReminder的方法用于类CalendarEvent。但是,在您的脚本中,这些方法被用作ClassCalendar的方法。我想你现在的问题可能是因为这个。
  • isAllDayEvent()没有参数。
  • 从你的展示表中,我认为if (data[i][11] == "created") continue;可能是if (data[i][10] == "created") continue;
  • 根据if (data[i][10] == "created") continue;,我认为rangeList.push( R${i + 3} )可能是rangeList.push( K${i + 2} )

当这些点反映在你的脚本中时,下面的修改怎么样?

修改脚本:

function addEvents() {
  var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var lr = ss.getLastRow();
  var cal = CalendarApp.getCalendarById("YOURGOOGLECALENDARIDHERE");
  var data = ss.getRange("A2:K" + lr).getValues();
  var dateANDTimeArr = ss.getRange("A2:K" + lr).getDisplayValues();
  while (data[data.length - 1][0] == '') data.pop();
  var rangeList = [];
  for (var i = 0; i < data.length; i++) {

    if (data[i][10] == "created") continue; // Modified: This is column "K".

    var theEventStartDate = dateANDTimeArr[i][1];
    var startHour = dateANDTimeArr[i][2].substring(0, 2);
    var startMin = dateANDTimeArr[i][2].substring(3, 5);
    var theEventEndDate = dateANDTimeArr[i][3];
    var endHour = dateANDTimeArr[i][4].substring(0, 2);
    var endMin = dateANDTimeArr[i][4].substring(3, 5);
    Logger.log("theEventStartDate : " + theEventStartDate);
    Logger.log("startHour : " + startHour);
    Logger.log("startMin : " + startMin);
    Logger.log("theEventEndDate : " + theEventEndDate);
    Logger.log("endHour : " + endHour);
    Logger.log("endMin : " + endMin);
    var startDate = new Date(theEventStartDate + " " + startHour + ":" + startMin + ":00");
    var endDate = new Date(theEventEndDate + " " + endHour + ":" + endMin + ":00");

    // --- I modified the below script.
    var event = cal[data[i][5] ? "createAllDayEvent" : "createEvent"](data[i][0], startDate, endDate, { location: data[i][7], description: data[i][6] });
    event.setVisibility(CalendarApp.Visibility[data[i][8] ? "PRIVATE" : "DEFAULT"]); // "DEFAULT" might be "PUBLIC"?
    if (data[i][9].toString()) event.addPopupReminder(data[i][9]);
    rangeList.push(`K${i + 2}`);
    // ---

  }
  if (rangeList.length == 0) return;
  ss.getRangeList(rangeList).setValue("created");
}

字符串

  • 当我使用您的显示表测试这个修改后的脚本时(我假设每个日期值都用作日期对象),没有错误发生。并且,我确认可以创建3个事件。

注意:

  • 在您的显示表中,如果All Day EventTRUE,请更改End Date。因为出现了类似Exception: Event start date must be before the event end date.的错误。请小心点。

参考资料:

  • isAllDayEvent()
  • setVisibility(可见性)
  • addPopupReminder(minutesBefore)

相关问题