从电子表格创建Google日历重复事件

时间:2014-08-26 21:52:10

标签: google-apps-script google-sheets google-calendar-api

底部是以前博客的代码,效果很好! 此代码使用以下Google表格标题进行设置:

Date | Title | Start Time | End Time | Location | Description | EventID

但是,我需要能够创建重复发生的事件。 新的Google表格标题如下:

Date | Title | Start Time | End Time | Location | Description | Type | Recurring | EventID

如果Type =“PM”(新列),我需要每月为“重复”(也是新列)数月创建定期事件。 如果每次运行脚本时仍然没有重复项,这怎么可能?

/**
 * Adds a custom menu to the active spreadsheet, containing a single menu item
 * for invoking the exportEvents() function.
 * The onOpen() function, when defined, is automatically invoked whenever the
 * spreadsheet is opened.
 * For more information on using the Spreadsheet API, see
 * https://developers.google.com/apps-script/service_spreadsheet
 */
function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Export Events",
    functionName : "exportEvents"
  }];
  sheet.addMenu("Calendar Actions", entries);
};

/**
 * Export events from spreadsheet to calendar
 */
function exportEvents() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var headerRows = 1;  // Number of rows of header info (to skip)
  var range = sheet.getDataRange();
  var data = range.getValues();
  var calId = "YOUR_CALENDAR_ID";
  var cal = CalendarApp.getCalendarById(calId);
  for (i in data) {
    if (i < headerRows) continue; // Skip header row(s)
    var row = data[i];
    var date = new Date(row[0]);  // First column
    var title = row[1];           // Second column
    var tstart = new Date(row[2]);
    tstart.setDate(date.getDate());
    tstart.setMonth(date.getMonth());
    tstart.setYear(date.getYear());
    var tstop = new Date(row[3]);
    tstop.setDate(date.getDate());
    tstop.setMonth(date.getMonth());
    tstop.setYear(date.getYear());
    var loc = row[4];
    var desc = row[5];
    var id = row[6];              // Sixth column == eventId
    // Check if event already exists, update it if it does
    try {
      var event = cal.getEventSeriesById(id);
    }
    catch (e) {
      // do nothing - we just want to avoid the exception when event doesn't exist
    }
    if (!event) {
      //cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
      var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc}).getId();
      row[6] = newEvent;  // Update the data array with event ID
    }
    else {
      event.setTitle(title);
      event.setDescription(desc);
      event.setLocation(loc);
      // event.setTime(tstart, tstop); // cannot setTime on eventSeries.
      // ... but we CAN set recurrence!
      var recurrence = CalendarApp.newRecurrence().addDailyRule().times(1);
      event.setRecurrence(recurrence, tstart, tstop);
    }
    debugger;
  }
  // Record all event IDs to spreadsheet
  range.setValues(data);

2 个答案:

答案 0 :(得分:0)

好的,这又是一件有趣的事情...... 上面的代码需要做一些修改才能做你想做的事情:

由于新创建的事件不是系列(或者它们必须创建为eventSeries,但这会使条件更复杂......)当我们创建一个新事件时,我们不使用该对象但使用{{1}获取它它隐含地改变了它的本质,而不需要定义重复。

这个技巧很好用,使代码更简单。

另一个问题是关于设置时间和日期:您的代码从没有年份的日期对象获取小时/分钟值(这在读取SS时是正常的)但这意味着Javascript日期在1月(月份)中具有日期值0)和1月是冬天(因为你知道XD)因此我们遇到了夏令时问题,所有时间值都是1小时后因为设置月份和日期之后没有改变小时值(这不清楚我'我害怕......但你现在可以用你的代码检查它了吗?

我必须反转过程并将时间值设置为日期对象,这样才能得到正确的结果。

由于要编写更多代码,我创建了一个小函数来完成工作:它有助于保持主代码“更清晰”。

在它下面是完整的代码,我还添加了一个“PER WEEK”重现来测试这个想法......保留它或者如果你不需要它就离开它。

getEventSeriesById()

enter image description here

test sheet here in view only

答案 1 :(得分:0)

如果要在特定时间间隔上显示重复事件,.interval函数允许您在重复方法下执行此操作。 在上面的示例中,将适当的代码更改为

var recurrence = CalendarApp.newRecurrence().addMonthlyRule().interval(times)

那样做。 这意味着如果对于一个事件,次数= 3,此事件将每3个月出现在您的日历上。