问题描述
我一直在尝试寻找一种方法,以特定顺序在多个工作表中运行脚本。每个工作表都有自己的脚本数量,当我使用它们时运行得很好(通过创建附加到按钮和/或菜单的“组合”脚本)。
有很多脚本,手动逐个运行脚本效率不高。
我一直在尝试利用库,但没有找到使其正常工作的方法。
我见过 Google Apps Script section on libraries 和 relevant stackoverflow threads like this one,但一直无法弄清楚。
这是我最后一次尝试(在尝试了许多不同的方法之后......)
function mastercombine() {
const west = SpreadsheetApp.openByUrl(`https://docs.google.com/spreadsheets/d/1NmN7h2wEGFlY1FatjEpJ9MRpZ_I_MtlyoApGG4F6rcw/edit#gid=589651642`);
west.West.combine();
freezeValues1();
}
我想我可能不完全理解如何调用库中的每个项目以在其各自的工作表上运行该函数。我试过用几种不同的方式调用它,但我很难过,因为它们都给出了空错误。
我收到的文本错误:
TypeError: 无法读取未定义的属性“masterSheetInfo” mastercombine@Combined Reset.gs:5 的副本
以west.West 开头的部分试图调用库工作表/函数。 “west”是常量,“West”是库 ID,“combine”是 West 中的函数(它在自己的工作表中正确运行)。
结束部分 (freezeValues1) 是一个应该在当前工作表上运行的函数(它可以在没有库部分的情况下独立工作)。
我最接近让事情按特定顺序运行的方法是将可安装的触发器附加到每个工作表,但我无法获得似乎随附的“将在一个小时内的某个时间运行”位。我希望通过一个触发器来调用它们。
从库中调用的脚本:
function combine() {
sortSheets();
SpreadsheetApp.flush();
Utilities.sleep(500);
sheetNames();
}
function sheetNames() {
var ss,list,tar;
ss = SpreadsheetApp.getActive()
list = ss.getSheets().slice(4).map(function (s,ind) {
return ['=HYPERLINK("https://docs.google.com/spreadsheets/d/1tfi_L668w7hpDqeGl84TEfVIm4zKMkyuwrKsG-uKx9A/edit#gid=' + s.getSheetId() + '","' + s.getName() + '")'];
})
tar = ss.getSheets()[0]; //List will be written to FirsT sheet in the workbook.
tar.getRange(2,1,tar.getLastRow(),1).clearContent();
tar.getRange(2,list.length,1).setValues(list)
}
解决方法
来自问题
以 west.West 开头的部分正在尝试调用库工作表/函数。 “west”是常量,“West”是库 ID,“combine”是 West 中的函数(它在自己的工作表中正确运行)。
- Google Apps 脚本库没有工作表。
-
west.West
不工作,因为west
已分配类电子表格对象,而此类没有West
属性/方法。因此,west.West
返回undefined
。
一种选择是将 West.masterSheetInfo()
转换为参数化函数,即 West.masterSheetInfo(west)
注意:如果参数化函数,有一行像
const west = SpreadsheetApp.getActiveSpreadsheet();
可能会被替换成类似
var west = west || SpreadsheetApp.getActiveSpreadsheet();
关于执行顺序,在 Google Apps Scripts 中,函数语句按照它们的编写顺序执行。
资源
相关
- Order of execution of functions in functional programming
- Google script - call library function with .getActiveSpreadsheet()
恐怕这是不可能的
无论如何都不是通过 Apps 脚本本身。您可以远程运行函数,但只能通过 Apps Script API。
https://developers.google.com/apps-script/api/how-tos/execute
尽管这有其自身的复杂性和局限性。
即使是触发器也不会因其他脚本对工作表所做的更改而触发。因此,您不能拥有一个实用程序表,您的外部脚本可以在其中更改某些内容并在表上具有 onChange
触发器。
来自:
https://developers.google.com/apps-script/guides/triggers/installable#restrictions
脚本执行和 API 请求不会导致触发器运行。
解决方法
为什么脚本必须存在于目标电子表格中?难道你不能只拥有一个包含所有代码的主脚本,然后对所有电子表格进行操作吗?
例如:
function main() {
let ssIds = [
"1b2RdsafasdfasdfE4GZy5y5465y54y54sMw","1b2R40ierqwerqwerf9Mvkm6I-TqE4GZsyMw","1b2R40iHFqqwerewqrwerkm6I-TqE4GZysMw","1b2R40iHFqOV7-ytqwertywerkm6I-TqGZsMw","1b2R40iHFqOVtryertyerf9Mvkm6I-T4GZsMw"
];
ssIds.forEach(id => {
let ss = SpreadsheetApp.openById(id);
// Do stuff here.
//...
//...
})
}