You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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();
}
核心修改说明
  1. 精准删除触发器:不再批量删除所有项目触发器,而是通过getSourceId判断触发器绑定的工作簿ID,仅删除当前工作簿的关联触发器;时间触发器无绑定源,通过脚本属性存储的归属ID匹配删除。
  2. 时间触发器归属标记:创建时间触发器时,将其唯一ID与当前工作簿ID关联存入脚本属性,确保后续删除时能精准识别归属。
  3. 代码效率优化:提前获取activeSpreadsheet对象,避免重复调用SpreadsheetApp.getActive()。

内容的提问来源于stack exchange,提问作者Shilpa Chawla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 08:31:10