如何创建可多表格运行的Standalone脚本及表格ID数组
问题描述
我是脚本编写新手,已经掌握基础脚本编写能力,但发现有人因为我的脚本功能实用而试图复制成果。我知道可以创建Standalone(独立)脚本来关联多个运行相同脚本的表格,但担心在完成配置前脚本就被复制(当前处于活动期间无法移除访问权限)。恳请指导如何基于以下代码创建独立脚本,以及如何创建供脚本运行的表格ID数组:
function onEdit(e) { UpdateLog(e); FurtherUpdateLog(e); VehicleLog(e); Dropdown(e); } function UpdateLog(e) { const sh = e.range.getSheet(); const shts = ['CV Event Control Log']; const idx = shts.indexOf(sh.getName()); if(~idx ) { if(e.range.columnStart !== 3) return; var o = e.range.offset(0, -1) if(!o.getValue()) o.setValue(Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yy HH:mm:ss"))}; }; function FurtherUpdateLog(e) { const sh = e.range.getSheet(); const shts = ['CV Event Control Log']; const idx = shts.indexOf(sh.getName()); if(~idx ) { if(e.range.columnStart !== 6) return; var o = e.range.offset(0, -1) if(!o.getValue()) o.setValue(Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yy HH:mm:ss"))}; }; function VehicleLog(e) { const sh = e.range.getSheet(); const shts = ['Vehicle Tow Log']; const idx = shts.indexOf(sh.getName()); if(~idx ) { if(e.range.columnStart !== 3) return; var o = e.range.offset(0, -1) if(!o.getValue()) o.setValue(Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yy HH:mm:ss"))}; }; function Dropdown(e) { var oldValue; var newValue; var ss=SpreadsheetApp.getActiveSpreadsheet(); var activeCell = ss.getActiveCell(); if(activeCell.getColumn() == 9 && activeCell.getLastRow && ss.getActiveSheet().getName()=="CV Event Control Log") { newValue=e.value; oldValue=e.oldValue; if(!e.value) { activeCell.setValue(""); } else { if (!e.oldValue) { activeCell.setValue(newValue); } else { activeCell.setValue(oldValue+', '+newValue); } } } }
解决方案
一、创建独立脚本步骤
- 打开Google云端硬盘,点击「新建」→「更多」→「Google Apps Script」,创建空白脚本项目
- 删除默认的
myFunction()代码,把你提供的所有代码粘贴进去 - 点击顶部「保存」,给脚本起个清晰的名字(比如「通用日志管理脚本」)
二、添加表格ID白名单数组并修改代码
独立脚本需要验证触发来源的表格是否在授权列表里,避免被复制后滥用。具体修改如下:
1. 定义白名单数组
在代码最顶部添加一行,把你要授权的表格ID填进去(表格ID是表格URL中d/和/edit之间的字符串):
// 替换成你的目标表格ID,多个ID用逗号分隔 const ALLOWED_SPREADSHEET_IDS = ["表格ID1", "表格ID2"];
2. 修改完整代码(优化后版本)
// 允许运行脚本的表格ID白名单 const ALLOWED_SPREADSHEET_IDS = ["你的表格ID1", "你的表格ID2"]; function onEdit(e) { // 先验证表格是否在白名单,不在直接终止 const sheetId = e.source.getId(); if (!ALLOWED_SPREADSHEET_IDS.includes(sheetId)) return; UpdateLog(e); FurtherUpdateLog(e); VehicleLog(e); Dropdown(e); } function UpdateLog(e) { const sh = e.range.getSheet(); if (sh.getName() !== 'CV Event Control Log') return; if (e.range.columnStart !== 3) return; const timestampCell = e.range.offset(0, -1); if (!timestampCell.getValue()) { timestampCell.setValue(Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yy HH:mm:ss")); } }; function FurtherUpdateLog(e) { const sh = e.range.getSheet(); if (sh.getName() !== 'CV Event Control Log') return; if (e.range.columnStart !== 6) return; const timestampCell = e.range.offset(0, -1); if (!timestampCell.getValue()) { timestampCell.setValue(Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yy HH:mm:ss")); } }; function VehicleLog(e) { const sh = e.range.getSheet(); if (sh.getName() !== 'Vehicle Tow Log') return; if (e.range.columnStart !== 3) return; const timestampCell = e.range.offset(0, -1); if (!timestampCell.getValue()) { timestampCell.setValue(Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yy HH:mm:ss")); } }; function Dropdown(e) { const activeCell = e.range; const sh = activeCell.getSheet(); if (activeCell.getColumn() === 9 && sh.getName() === "CV Event Control Log") { const newValue = e.value; const oldValue = e.oldValue; if (!newValue) { activeCell.setValue(""); } else if (!oldValue) { activeCell.setValue(newValue); } else { activeCell.setValue(`${oldValue}, ${newValue}`); } } }
修改说明
- 新增白名单验证:在
onEdit开头先检查表格ID,不在列表里直接停止执行,复制脚本的人没有授权ID就无法使用 - 简化判断逻辑:把原代码里的
indexOf+~idx改成更直观的全等判断,可读性更强 - 优化
Dropdown函数:用事件对象e.range替代getActiveSpreadsheet(),避免独立脚本的上下文问题 - 变量命名更清晰:比如把
o改成timestampCell,便于后期维护
三、给目标表格绑定触发器
独立脚本不能用原生简单触发,需要手动创建可安装触发器:
- 打开你的独立脚本项目,点击左侧的闹钟图标(「触发器」)
- 点击「添加触发器」,按以下配置:
- 选择函数:
onEdit - 部署类型:选择「Head deployments」(首次配置需要先部署版本,按提示操作即可)
- 事件源:「从电子表格」
- 事件类型:「编辑时」
- 选择函数:
- 点击「保存」,按提示完成授权(需要允许脚本访问你的表格)
注意:只要表格ID在白名单里,触发器会自动响应这些表格的编辑事件,无需逐个表格重复配置
四、临时防复制措施(当前无法移除权限时)
在你完成独立脚本配置前,可以给原表格里的脚本加临时验证,阻止复制者使用:
在原脚本的onEdit函数最开头添加:
if (e.source.getId() !== "你的原表格ID") return;
这样只有你的原表格能触发脚本,其他人复制后无法运行,等独立脚本配置完成后,直接删除原表格里的脚本即可
内容的提问来源于stack exchange,提问作者Jon Harris
相关产品推荐
相关产品推荐

