如何在Google Sheet单元格更新时自动更新或删除关联Google Calendar事件
问题修复方案
报错原因
你遇到的ReferenceError: e is not defined错误是因为onEdit触发器触发时传入的编辑事件对象没有被函数接收,当前函数没有声明e参数,导致调用var {range} = e时找不到对应变量。
核心修改点
- 给函数添加事件对象参数:把函数定义改为
function simpleSheetsToCalendar(e) - 禁止手动直接运行该函数,只有编辑工作表触发onEdit触发器时,系统会自动传入
e参数,手动运行因缺少事件对象仍会报错
优化后完整代码
// 新增参数e接收编辑事件对象 function simpleSheetsToCalendar(e) { var sheetNames = ["Oct-08-2021 | Plan", "Oct-15-2021 | Plan"]; // 请替换为你需要使用的工作表名称 var calendarId = "myCalendar"; // 请替换为你的日历ID var {range} = e; var sheet = range.getSheet(); if (!(sheetNames.includes(sheet.getSheetName()) && range.rowStart >= 4 && range.rowEnd <= 24 && range.columnStart >= 3 && range.columnStart <= 6)) return; // 1. 读取日历所有事件,创建标题映射对象用于去重校验 var events = []; var pageToken = ""; do { var res = Calendar.Events.list(calendarId, {maxResults: 2500, fields: "nextPageToken,items(id,summary,start(dateTime),end(dateTime))", pageToken}); events = events.concat(res.items); pageToken = res.nextPageToken; } while(pageToken); var obj = events.reduce((o, e) => Object.assign(o, {[e.summary]: e}), {}); // 2. 读取工作表C4:F24范围数据,生成新增、修改、删除事件的操作队列 var values = sheet.getRange("C4:F24").getValues().reduce((o, [title,,startTime,endTime]) => { if (!obj[title] && title && startTime && endTime && !o[title]) { o.add[title] = {startTime, endTime}; } else if (obj[title] && title && startTime && endTime) { if (new Date(obj[title].start.dateTime).getTime() != startTime.getTime() || new Date(obj[title].end.dateTime).getTime() != endTime.getTime()) { obj[title].start.dateTime = startTime; obj[title].end.dateTime = endTime; o.modify.push(obj[title]); } } else if (obj[title] && title && !startTime && !endTime) { o.remove.push(obj[title].id); } return o; }, {add: {}, remove: [], modify: []}); // 3. 执行新增事件操作 var eventCal = CalendarApp.getCalendarById(calendarId); var ar = Object.entries(values.add); if (ar.length > 0) { ar.forEach(([title, {startTime, endTime}]) => eventCal.createEvent(title, startTime, endTime)); } // 4. 执行修改事件操作 if (values.modify.length > 0) { values.modify.forEach(({id, start, end}) => eventCal.getEventById(id).setTime(start.dateTime, end.dateTime)); } // 5. 执行删除事件操作 if (values.remove.length > 0) { values.remove.forEach(id => eventCal.getEventById(id).deleteEvent()); } }
后续配置步骤
- 先删除原有绑定的onEdit触发器,避免重复触发
- 新建可安装onEdit触发器:选择触发函数为
simpleSheetsToCalendar,事件源为电子表格,事件类型为「修改时」 - 首次触发授权时,按照提示授予脚本访问日历和工作表的权限
- 需确保工作表和目标日历的时区设置一致,避免事件时间偏移
功能说明
优化后的脚本已经覆盖你提出的两个需求:
- C4:F24范围内数据修改时,会自动比对日历现有事件的时间,不一致则自动更新,不会重复创建
- E4:F24的时间内容删除后,会自动匹配对应标题的日历事件进行删除
注意:该逻辑默认事件标题唯一,若存在重名事件可能会出现匹配错误
内容的提问来源于stack exchange,提问作者athombomb
相关产品推荐
相关产品推荐

