将Google Apps Script的OnOpen触发器改为基于时间的触发器
将Google Apps Script的OnOpen触发器改为基于时间的触发器
没问题,我来帮你调整脚本并设置定时触发器。首先要注意的是,你原来的函数依赖于onOpen事件的参数e,而时间驱动触发器不会传递这个参数,所以第一步得先修改脚本,去掉对e的依赖,然后再设置定时触发。
第一步:修改原有脚本
把原来的installedOnOpen函数改成不需要事件参数的版本,替换掉e.source为直接获取当前活动表格。修改后的完整代码如下:
function protectSheetRanges() { const editors = ["abc@abc.com", "xyz@xyz.com"]; const sheetNames = ["Sheet1"]; const ss = SpreadsheetApp.getActiveSpreadsheet(); // 替换原来的e.source const sheets = ss.getSheets().filter(s => sheetNames.includes(s.getSheetName())); if (sheets.length == 0) return; sheets.forEach(s => { const p = s.getProtections(SpreadsheetApp.ProtectionType.RANGE); if (p.length > 0) { p.forEach(pp => pp.remove()); } // Gets all the values from col1 to col16 up to the last row var range = s.getRange(1, 1, s.getLastRow(), 16).getValues(); var lastRow = range.length - 1; /* the for loop below checks the rows from the bottom up and will stop once it encounters a non-empty row. This mimics the behavior of the getLastRow() method but restricts it to columns 1 - 16 */ for (lastRow; lastRow > 0; lastRow--) { if (range[lastRow].join('').length > 0) break; } if (lastRow != 0) { const startRow = 6; const numRows = lastRow - 4; const newProtect = s.getRange(startRow, 1, numRows, 16).protect(); newProtect.removeEditors(newProtect.getEditors()); newProtect.addEditors(editors); // Added if (newProtect.canDomainEdit()) newProtect.setDomainEdit(false); } }); }
主要修改点:
- 函数名改为
protectSheetRanges(更贴合功能,也避免和内置的onOpen冲突) - 用
SpreadsheetApp.getActiveSpreadsheet()替代了原来的e.source,直接获取当前表格
第二步:设置每48小时凌晨1点的定时触发器
有两种方式可以创建这个触发器,选你方便的就行:
方式一:手动在脚本编辑器创建
- 打开你的Google表格,点击顶部菜单的「工具」→「脚本编辑器」
- 在脚本编辑器左侧边栏,点击闹钟形状的「触发器」图标
- 点击页面右下角的「添加触发器」按钮
- 在弹出的设置窗口里填写以下内容:
- 选择要运行的函数:
protectSheetRanges - 选择部署类型:选择「Head deployments」(如果是新脚本,直接选这个就行)
- 选择事件源:「时间驱动」
- 选择时间类型:「基于定时器」
- 选择时间间隔:「每48小时」
- 选择具体时间:「凌晨1:00到2:00」(这样脚本会在凌晨1点左右自动运行)
- 选择要运行的函数:
- 点击「保存」,然后按照提示完成权限授权即可。
方式二:用代码自动创建触发器
如果你想通过代码快速创建,可以添加下面的辅助函数,运行一次即可自动生成触发器(还会自动删除同名旧触发器,避免重复):
function create48HourTrigger() { // 先清除已有的同名触发器 const existingTriggers = ScriptApp.getProjectTriggers(); existingTriggers.forEach(trigger => { if (trigger.getHandlerFunction() === "protectSheetRanges") { ScriptApp.deleteTrigger(trigger); } }); // 创建每48小时凌晨1点的触发器 ScriptApp.newTrigger("protectSheetRanges") .timeBased() .everyHours(48) .atHour(1) .create(); }
添加完这个函数后,点击脚本编辑器的运行按钮(▶️),运行create48HourTrigger,按提示授权权限,之后触发器就自动创建好了。
注意事项
- 第一次运行脚本或创建触发器时,Google会要求你授权脚本访问你的电子表格,按照提示操作即可,需要选择「高级」→「前往xxx脚本(不安全)」(这是自定义脚本的常规权限提示,放心授权即可)
- 定时触发器的运行时间可能会有几分钟的误差,这是Google服务器的正常情况,不影响功能。
备注:内容来源于stack exchange,提问作者Essem
相关产品推荐
相关产品推荐

