这与两天前提出的一个问题非常相似,该问题是关于将活动电子表格与日历同步。听起来您想将电子表格视为其发起的事件的主人,这将大大简化问题。 this answer 介绍了您需要做的基本操作。如果您只想修改现有代码,我在下面有一个实现。
我有来自this blog 的代码的修改版本,它将修改预先存在的日历条目以匹配电子表格中的信息。我对电子表格的排列方式有所不同,这反映在代码中。
日期 |标题 |开始时间 |结束时间 |位置 |说明 |
事件 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);
}
删除/重新创建
在此替代方案中,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;
注意事项
-
getEventSeriesById 的文档错误地指出,当找不到匹配的事件时,它会返回 null,而它会引发异常。 (讨厌!)所以我把它封闭在一个 try / catch 块中,只是为了继续游泳。
- 不幸的是,虽然
getEventSeriesById 用于检索事件,但它returns 是一个不支持setTime() 方法的EventSeries 对象。如果您不希望更改事件的时间,则可以。否则,您可以通过设置recurrence 规则和次数将Event 更改为EventSeries,或者删除旧事件并创建一个新事件,如删除/重新创建。 Issue 1154。
- 电子表格总是胜出。通过 Google 日历记录的任何事件更改(在相关字段中)都将被脚本覆盖。