从电子表格创建Google日历事件,但可以防止重复

use*_*577 26 google-calendar-api google-sheets google-apps-script

我正在尝试编写一个脚本,该脚本将从Google电子表格中获取数据,并在我的Google日历中创建活动.

我管理得很好,但每次运行它都会产生重复.所以现在我试图通过在电子表格中创建一个列17来防止这种情况,每列自动生成唯一的事件ID,然后每次运行脚本时,它将查看每行的事件ID并删除相应的事件如果我已经更改了行,则在使用原始数据或更新的数据重新创建它之前在日历中.

我是新手编写的任何类型的脚本并拼凑在一起,但现在正在撞墙.任何人都可以解决这个问题吗?

function CalInsert() {
    var cal = CalendarApp.getDefaultCalendar();
    var id = SpreadsheetApp.getActiveSheet().getRange(2,17).getValue();

    if (id != 0) {
        var event = cal.getEventSeriesById(id);
        event.deleteEventSeries();
    }

    var sheet = SpreadsheetApp.getActiveSheet();
    var startRow = 2; // First row of data to process
    var numRows = sheet.getLastRow(); // Number of rows to process
    var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn());
    var data = dataRange.getValues();

    for (i in data) {
        var row = data[i];
        var title = row[0]; // First column
        var desc = row[13]; // Second column
        var tstart = row[14];
        var tstop = row[15];

        var event = cal.createEvent(title, tstart, tstop, {description:desc});
        var eventid = event.getId();
        SpreadsheetApp.getActiveSheet().getRange(2,17).setValue(eventid);
    }
}
Run Code Online (Sandbox Code Playgroud)

Mog*_*dad 39

这与两天前提出的问题非常相似,该问题涉及将事件电子表格与日历同步.听起来你想要将电子表格视为它所发生的事件的主人,这将大大简化问题.本答案涵盖了您需要做的基础知识.如果您只是修改现有代码,我在下面有一个实现.

我有一个来自此博客的代码的修改版本,它将修改预先存在的日历条目以匹配电子表格中的信息.我的电子表格安排不同,这反映在代码中.

日期| 标题| 开始时间| 结束时间| 位置| 说明| 事件ID

创建新事件时,脚本会填充事件ID列,然后在以后的调用中使用该列从日历中检索事件,从而避免重复.

脚本

/**
 * 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=0; i<data.length; i++) {
    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);
}
Run Code Online (Sandbox Code Playgroud)

删除/重新创建

在此替代方案中,eventID用于查找和删除以前存在的事件.之后,将使用电子表格中的数据创建新事件.这样做的好处是可以更新事件的所有值,包括开始和停止时间(请参阅下面的注释).另一方面,对原始事件所做的任何更改都将丢失 - 例如,如果其他人被邀请参加活动,或者添加了自定义提醒.

要使用此替代方法,只需将匹配的代码替换为:

// Check if event already exists, delete it if it does
try {
  var event = cal.getEventSeriesById(id);
  event.deleteEventSeries();
  row[6] = '';  // Remove event ID    
}
catch (e) {
  // do nothing - we just want to avoid the exception when event doesn't exist
}
//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
debugger;
Run Code Online (Sandbox Code Playgroud)

笔记

  • 文档getEventSeriesById错误地指出它null在没有找到匹配事件时返回,而是抛出异常.(讨厌!)所以我把它放在一个try/catch块中,只是为了继续游泳.
  • 不幸的是,在getEventSeriesById检索事件时,它returns是一个EventSeries不支持该setTime()方法的对象.如果您不希望更改事件的时间,那就OK.否则,您可以通过设置重复规则和时间来更改Event为a ,或删除旧事件并创建新事件,如删除/重新创建中所示.问题1154.EventSeries
  • 电子表格总是胜利.通过Google日历记录的任何事件更改(在相关字段中)都将被脚本覆盖.

  • 这似乎是你真正喜欢的主题:-) +1用于详尽无遗. (6认同)