如何在Google Sheets撤销操作时绕过Google Apps Script的onEdit触发?
解决onEdit触发器在撤销时重复触发的问题
方法1:用PropertiesService记录操作状态,过滤撤销操作
通过存储上次编辑的单元格位置和值,当触发onEdit时,对比当前操作是否是撤销回到之前的状态,若是则跳过执行。
修改后的脚本示例:
function onEdit(e) { const prop = PropertiesService.getScriptProperties(); const lastEditKey = 'last_edit'; // 获取当前编辑的信息 const currentRange = e.range.getA1Notation(); const currentValue = e.value; // 读取上次记录的编辑信息 const lastEdit = JSON.parse(prop.getProperty(lastEditKey) || '{}'); // 判断是否是撤销操作:同一单元格,且值回到上次编辑前的旧值 if (currentRange === lastEdit.range && currentValue === lastEdit.oldValue) { // 是撤销操作,清除记录并返回,不执行更新 prop.deleteProperty(lastEditKey); return; } // 记录本次编辑的信息:单元格位置、编辑前的旧值 const editInfo = { range: currentRange, oldValue: e.oldValue }; prop.setProperty(lastEditKey, JSON.stringify(editInfo)); // 执行正常的状态更新逻辑 functionToUpdateStatus(currentValue); } // 你的状态更新函数 function functionToUpdateStatus(value) { // ... 原有的更新逻辑 }
方法2:用LockService防止重复执行
如果撤销触发的onEdit会导致重复执行更新函数,可以用锁服务确保同一时间只有一个脚本实例运行,避免重复操作。
示例:
function onEdit(e) { const lock = LockService.getScriptLock(); // 尝试获取锁,超时时间设为1秒,避免阻塞 if (!lock.tryLock(1000)) { // 无法获取锁,说明已有脚本在执行(可能是撤销触发的重复调用),直接返回 return; } try { const value = e.value; functionToUpdateStatus(value); } finally { // 释放锁 lock.releaseLock(); } } function functionToUpdateStatus(value) { // ... 原有的更新逻辑 }
注意事项
- 方法1需要确保只有单个用户操作表格,多用户场景下可能需要调整存储键(比如结合用户邮箱)。
- 方法2适用于更新函数执行较快的场景,超时时间可根据实际逻辑调整。
内容的提问来源于stack exchange,提问作者sunmoonlake
相关产品推荐
相关产品推荐

