我正在尝试编写一个脚本,该脚本将从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);
}
}
答案 0 :(得分:38)
这与两天前提出的问题非常相似,该问题涉及将事件电子表格与日历同步。听起来你想要将电子表格视为它所发生的事件的主人,这将大大简化问题。 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
是一个EventSeries
对象,它不支持setTime()
方法。如果您不希望更改事件的时间,那就OK。否则,您可以通过设置重复规则&amp ;,将Event
更改为EventSeries
。时间,或删除旧事件并创建一个新事件,如删除/重新创建中所示。 Issue 1154。 答案 1 :(得分:4)
我想发布此帖给任何想要使用它的人,我已经修改了脚本以便在我已经使用的工作表中工作。日期格式和事件重复是一些需要修复的问题,但经过一些测试后,我对这是如何工作非常满意。我用它来预订工作并与我的移动员工分享,并在整个市。 下一步是将日历事件拉到电子表格,这样它可以双向工作,我可以使用手机上的日历应用程序即时预订工作,所以如果有人有任何建议,我还需要插入一个脚本将响应数据形成到同一工作表中,并添加完整的行,其中作业编号匹配,保持现有数据不变。
`function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Export Events",
functionName : "exportEvents"
}]; sheet.addMenu("Calendar Actions", entries);
};
function parseDate(s) {
var months = {jan:0,feb:1,mar:2,apr:3,may:4,jun:5,
jul:6,aug:7,sep:8,oct:9,nov:10,dec:11};
var p = s.replace(".", "").split('-');
return new Date(p[2], months[p[1].toLowerCase()], p[0]);
}
/**
* Export events from spreadsheet to calendar
*/
function exportEvents() {
var sheet = SpreadsheetApp.getActiveSheet();
var headerRows = 6; // Number of rows of header info (to skip)
var range = sheet.getDataRange();
var data = range.getDisplayValues();
//var calId = "Your calendar Id"; // PRODUCTION
var calId = "Your_calendar Id to test"; // TEST
var cal = CalendarApp.getCalendarById(calId);
//Logger.log(cal);
//Logger.log(data.length);
for (i=0; i<data.length; i++) {
if (i < headerRows) continue; // Skip header row(s)
if (data[i][0].length < 1) continue; // Skip if no content.
var row = data[i];
Logger.log(row);
var date = parseDate(row[0]); // First column
//Logger.log(date);
var title = row[1]; // Second column
var tstart = new Date();
var s = row[2].split(":");
tstart.setHours(s[0]);
tstart.setMinutes(s[1]);
tstart.setSeconds(s[2]);
tstart.setDate(date.getDate());
tstart.setMonth(date.getMonth());
tstart.setYear(date.getYear());
var tstop = new Date();
var e = row[3].split(":");
tstop.setHours(e[0]);
tstop.setMinutes(e[1]);
tstop.setSeconds(e[2]);
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
var event = null;
if (id.length > 0) {
try {
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();
var r = i + 1;
var cell = sheet.getRange("G" + r);
cell.setValue(newEvent);
}
else {
Logger.log(event);
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;
}
}
`