Google Workspace Editor插件:工作簿间触发器冲突问题求助(附代码)
问题根源
你的代码里有个致命问题:
const triggers = ScriptApp.getProjectTriggers(); triggers.forEach(trigger => ScriptApp.deleteTrigger(trigger));
ScriptApp.getProjectTriggers()获取的是整个插件项目下的所有触发器,不是当前打开工作簿专属的触发器。当你在A工作簿执行这段代码时,会把同插件项目下B工作簿的触发器也一并删除,直接导致B的触发器失效。
解决方案
修改删除触发器的逻辑,只清理当前工作簿关联的触发器,保留其他工作簿的。具体代码调整如下:
function createTimeTrigger(triggerTime) { const documentProperties = PropertiesService.getDocumentProperties(); const selectedTriggerTime = documentProperties.getProperty("triggerTime"); const activeSpreadsheet = SpreadsheetApp.getActive(); const activeSpreadsheetId = activeSpreadsheet.getId(); // 仅删除当前工作簿关联的触发器 const triggers = ScriptApp.getProjectTriggers(); triggers.forEach(trigger => { const triggerSourceId = trigger.getSourceId(); // 针对绑定工作簿的触发器(onChange/onFormSubmit),直接匹配ID if (triggerSourceId === activeSpreadsheetId) { ScriptApp.deleteTrigger(trigger); } // 针对无绑定源的时间触发器,通过脚本属性标记的归属ID判断 else if (!triggerSourceId) { const triggerBindId = PropertiesService.getScriptProperties().getProperty(`trigger_${trigger.getUniqueId()}`); if (triggerBindId === activeSpreadsheetId) { ScriptApp.deleteTrigger(trigger); PropertiesService.getScriptProperties().deleteProperty(`trigger_${trigger.getUniqueId()}`); } } }); let triggerStatus = ""; if (documentProperties.getProperty("onChangeTrigger") === "true") { ScriptApp.newTrigger("testTrigger").forSpreadsheet(activeSpreadsheet).onChange().create(); triggerStatus += " 已配置:变更时触发"; } else if (documentProperties.getProperty("onFormSubmitTrigger") === "true" && activeSpreadsheet.getFormUrl() !== null) { ScriptApp.newTrigger("testTrigger").forSpreadsheet(activeSpreadsheet).onFormSubmit().create(); triggerStatus += " 已配置:表单提交时触发"; } else if (documentProperties.getProperty("onFormSubmitTrigger") === "true") { showAlert_("错误", "触发器配置无效:未关联表单"); return; } else if (selectedTriggerTime !== "Select" && selectedTriggerTime !== null) { const timeTrigger = ScriptApp.newTrigger("testTrigger").timeBased().everyHours(triggerTime).create(); // 给时间触发器标记所属工作簿ID,存入脚本属性 PropertiesService.getScriptProperties().setProperty(`trigger_${timeTrigger.getUniqueId()}`, activeSpreadsheetId); triggerStatus += ` 已配置:每${triggerTime}小时触发一次`; } else if (documentProperties.getProperty("onChangeTrigger") === "true" && selectedTriggerTime !== "Select" && selectedTriggerTime !== null) { ScriptApp.newTrigger("testTrigger").forSpreadsheet(activeSpreadsheet).onChange().create(); const timeTrigger = ScriptApp.newTrigger("testTrigger").timeBased().everyHours(triggerTime).create(); PropertiesService.getScriptProperties().setProperty(`trigger_${timeTrigger.getUniqueId()}`, activeSpreadsheetId); triggerStatus += ` 已配置:变更时触发 + 每${triggerTime}小时触发一次`; } triggerStatus = triggerStatus || "- 无激活触发器"; documentProperties.setProperty("triggerStatus", `更新者:${Session.getEffectiveUser().getEmail()},时间:${new Date().toLocaleString()}${triggerStatus}`); showToast_("触发器配置成功", ""); getLastRunStatus(); getTriggerStatus(); launchApp(); }
核心修改说明
- 精准删除触发器:不再批量删除所有项目触发器,而是通过
getSourceId判断触发器绑定的工作簿ID,仅删除当前工作簿的关联触发器;时间触发器无绑定源,通过脚本属性存储的归属ID匹配删除。 - 时间触发器归属标记:创建时间触发器时,将其唯一ID与当前工作簿ID关联存入脚本属性,确保后续删除时能精准识别归属。
- 代码效率优化:提前获取
activeSpreadsheet对象,避免重复调用SpreadsheetApp.getActive()。
内容的提问来源于stack exchange,提问作者Shilpa Chawla
相关产品推荐
相关产品推荐

