我的客户有大约150个Google电子表格,每个电子表格都有一个用于“供应商” . 电子表格基于模板电子表格,其中我设置了自定义函数的触发器 . 但是,将模板复制并设置为新的供应商电子表格时,触发器将丢失 .
我已经编写了一个与电子表格共享的库来整合代码 . 我一直在尝试添加一种方法来安装电子表格中的触发器(使用库),一旦它们被打开以便在从模板复制时纠正它们的缺席,但是,我没有取得任何成功 . 我相信库可能无法为除了自身之外的任何东西创建可安装的触发器 .
使用引用为“SheetNames”的库,正确链接并正常运行,我在每个电子表格中都有:
function onOpen(){
SheetNames.manageTimers();
}
在库“SheetNames”中,我有这样的代码:
function deleteAllTriggers(workbook) {
// Loop over all triggers and delete them
var allTriggers = ScriptApp.getUserTriggers(workbook);
for (var i = 0; i < allTriggers.length; i++) {
ScriptApp.deleteTrigger(allTriggers[i]);
}
}
function manageTimers(){
// code to install timers if not present
// and remove them from terminated vendors' sheets named "Vendor 2xxx..."
var workbook = SpreadsheetApp.getActiveSpreadsheet();
var workbookName = workbook.getName();
//Assumes workbookName is formatted as "Vendor XXXX..."
var vendorNumber = ""+workbookName.substr(7, 256);
if ((vendorNumber.length >= 4) && (vendorNumber.substr(0,1) == "2")) {
//this is a 2xxx vendor and all timers need to be deleted
Logger.log("Deleted all timers for "+workbookName);
deleteAllTriggers(workbook);
return;
}
var allTriggers = ScriptApp.getUserTriggers(workbook);
for (var i = 0; i < allTriggers.length; i++) {
if (allTriggers[i].getHandlerFunction() == "maintenance") {
//delete old version of trigger if not timeBased
if (allTriggers[i].getEventType()=="CLOCK") {
var maintexists=1;
} else {
ScriptApp.deleteTrigger(allTriggers[i]);
}
}
if (allTriggers[i].getHandlerFunction() == "incrementDummyValueToForceUpdate") {
//delete old version of trigger if not timeBased
if (allTriggers[i].getEventType()=="CLOCK") {
var counterexists=1;
} else {
ScriptApp.deleteTrigger(allTriggers[i]);
}
}
}
//create triggers if they don't exist
if (!maintexists) {
ScriptApp.newTrigger('maintenance')
.forSpreadsheet(workbook)
.timeBased()
.onMonthDay(27)
.create();
}
if (!counterexists) {
ScriptApp.newTrigger('incrementDummyValueToForceUpdate')
.forSpreadsheet(workbook)
.timeBased()
.everyMinutes(5)
.create();
}
}
具体来说,代码在 .timeBased()
上扼流,错误为 TypeError: Cannot find function timeBased in object SpreadsheetTriggerBuilder. (line 104, file "Sheets", project
这似乎是合适的,因为 .forSpreadsheet()
参数似乎只适用于 onOpen
, onEdit
, onChange
等 .
如果我更改引用
var allTriggers = ScriptApp.getUserTriggers(workbook);
至
var allTriggers = ScriptApp.getProjectTriggers();
并改变这一点
ScriptApp.newTrigger('incrementDummyValueToForceUpdate')
.forSpreadsheet(workbook)
.timeBased()
.everyMinutes(5)
.create();
对此
ScriptApp.newTrigger('incrementDummyValueToForceUpdate')
.timeBased()
.everyMinutes(5)
.create();
然后手动将代码放入每个电子表格中,它工作正常,但这违背了库的目的 . 如果我将更改后的代码放入库中,它会在库本身中创建触发器,这不是我需要的 .
所以,基本上,我正在寻找一个如何使用库创建可安装触发器的解决方案,这样我就不必将所有这些代码复制到数百个电子表格中,也不必手动设置触发器 .
2 回答
您不能使用:
.forSpreadsheet(workbook)
来创建基于时间的触发器 .肯定是:
我不确定函数
incrementDummyValueToForceUpdate
是否可以访问活动的电子表格 . 在附加组件中它可以,但您没有使用附加组件 .您可以发布加载项,并让客户在每个电子表格中使用加载项 . 如果您不想这样做并且每个电子表格都有一个绑定项目,则可以通过编程方式更新绑定项目 .
就在昨天,宣布了新的Apps Script API . 您需要更新项目 . 请参阅“更新项目内容”
https://developers.google.com/apps-script/api/how-tos/manage-projects
事实证明该位不正确,并且通过库添加触发器会在工作表本身中创建触发器 . 示例代码: