我目前正在使用应用程序脚本来同步我的谷歌表到谷歌日历。这个过程是相当简单的,我的脚本只需要一个日期和标题从电子表格,并创建一个整天的事件在该日期与标题。
我面临的问题是,如果我不小心键入了错误的日期,或者我必须更新电子表格中的一个日期,在运行scheduleShifts函数时,所有的事件都会被再次创建,这导致了许多重复的事件,而我并不打算在那里。我试图找到一个解决方案,帮助更新事件的标题或删除事件,并在电子表格中的日期是错误的情况下创建一个新的事件。
更新电子表格中的数据然后更新日历也不是很有效,因为如果有很多日期或标题需要更改,那么在日历中更改所有的日期或标题会花费很多时间。此外,删除当前的日历,创建一个新的日历,将该id复制到电子表格中,然后再更新所有的东西,也会非常麻烦。
这就是我目前的代码样子。
function scheduleShifts()
{
/*Identify calendar*/
var spreadsheet = SpreadsheetApp.getActiveSheet();
var calendarId = spreadsheet.getRange("C1").getValue();
var eventCal = CalendarApp.getCalendarById(calendarId);
/*Import data from the spreadsheet*/
var signups = spreadsheet.getRange("C4:F73").getValues();
/*Create events*/
for (x=0; x<signups.length; x++)
{
var shift = signups[x];
var title = shift[0];
var date = shift[3];
eventCal.createAllDayEvent(title, date);
}
}
/*Make the script shareable for others to use*/
function onOpen()
{
var ui = SpreadsheetApp.getUi();
ui.createMenu('Sync to Calendar')
.addItem('Schedule shifts', 'scheduleShifts')
.addToUi();
}
我试着用高级日历服务检索所有的事件,把它们的标题推到一个数组中,然后用IndexOf验证,以避免重复事件。然而,我不确定如果事件的日期有更新时标题保持不变,这种方法是否有效。
我所引用的代码就是这样做的。
var existingEvents=Calendar.Events.list(calendarId);
var eventArray=[];
existingEvents.items.forEach(function(e){eventArray.push(e.summary)});
for (x=0; x<signups.length; x++) {
var shift = signups [x];
var startTime = shift[0];
var endTime = shift[1];
var inspector = shift[2];
if(eventArray.indexOf(inspector)==-1){
eventCal.createEvent(inspector, startTime, endTime);
}else{
Logger.log('event exists already');
}
}
如果有人需要更多的信息,请在评论中提问,我们将非常感谢您的帮助。
为了避免创建重复的事件,你可以让脚本写出相应的内容。eventId
当每一个事件被创建后,它就会出现。这样,下一次脚本运行时,就可以检查是否有 eventId
被填充(在这种情况下,事件已经存在),只有在事件不存在时才创建事件。它可以是这样的(在这个示例中,这个 eventIds
被写入G列)。)
function scheduleShifts() {
const spreadsheet = SpreadsheetApp.getActiveSheet();
const calendarId = spreadsheet.getRange("C1").getValue();
const eventCal = CalendarApp.getCalendarById(calendarId);
const signups = spreadsheet.getRange("C4:G7").getValues();
for (let x = 0; x < signups.length; x++) {
const shift = signups[x];
const title = shift[0];
const date = shift[3];
const eventId = shift[4];
if (eventId == "") { // Check the event doesn't exist
const newEvent = eventCal.createAllDayEvent(title, date);
const newEventId = newEvent.getId();
spreadsheet.getRange(4 + x, 7).setValue(newEventId); // Write new eventId to col G
}
}
}
关于更新过程,我建议你: -- 安装一个onEdit触发器,要么 手动 或 程序上. 这个动作需要授权,一个简单的 onEdit
触发器在这里不能工作(见 限制条件).
这样,你就可以使用 事件对象 只更新与被编辑的行相对应的事件,这样就避免了每次都要更新所有的事件,这将使这个过程的效率非常低。更新过程本身包括调用 setTitle 和 setAllDayDate.
该功能由 onEdit
触发器可以是这样的。
function updateEvent(e) {
var editedRow = e.range.getRow();
var editedData = e.source.getActiveSheet().getRange(editedRow, 3, 1, 5).getValues()[0];
var eventId = editedData[4];
try {
var event = CalendarApp.getEventById(eventId);
event.setTitle(editedData[0]);
event.setAllDayDate(editedData[3]);
} catch(err) {
console.log("There was a problem updating the event. This event might not exist yet.");
}
}
C4:G73
),如果事件的数量可能有所不同。你可以使用像 getLastRow() 根据电子表格的内容,不使这个范围成为动态的。eventId
这里使用的,对应于 类 CalendarEvent,与API不完全相同 活动资源. 在您使用 高级服务.