我是 JS 和编程新手。 我正在运行一个包含大量工作表的项目电子表格,并尝试在一张主表中收集信息。 问题是,循环遍历 100 张表并获取值会使函数太慢,需要大约 40 秒的运行时间。
我查看了日志,发现 .getValue 的要求非常高,每次迭代都需要 0.2 秒。 我已经阅读过有关批处理函数的内容,但知道如何做到这一点...
function onEdit(e) {
//declaring variables
var sheetnames = new Array();
var budgetSums = new Array();
var projectState = new Array();
var workingHours = new Array();
var projectLink = new Array();
var sheetLink = new Array();
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var masterSheet =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Mastersheet");
//get information and cell values from diffentent sheets
for (var i=0 ; i<sheets.length ; i++) {
sheetnames.push( [ sheets[i].getName() ] );
budgetSums.push( [ sheets[i].getRange('F1').getValue() ] );
projectState.push( [ sheets[i].getRange('K1').getValue() ] );
workingHours.push( [ sheets[i].getRange('K2').getValue() ] );
sheetLink.push( [ sheets[i].getSheetId() ] )
}
//set cell values in the master sheet
for (var i=0; i<sheetnames.length; i++){
masterSheet.getRange(i +1, 1).setValue(sheetnames[i]);
masterSheet.getRange(i +1, 2).setValue(budgetSums[i]);
masterSheet.getRange(i +1, 3).setValue(projectState[i]);
masterSheet.getRange(i +1, 4).setValue(workingHours[i]);
}
for (var i=0; i<sheetnames.length; i++){
masterSheet.getRange(i +1, 5).setValue('=HYPERLINK("#gid=' + sheetLink[i]
+ '";"' + sheetnames[i] + '")' );
}
}
代码可以工作,但我不知道如何优化它。也许我需要采取不同的方法?
最佳答案
我相信您可以学习这两部分:
for (var i=0 ; i<sheets.length ; i++) {
sheetnames.push( [ sheets[i].getName() ] );
budgetSums.push( [ sheets[i].getRange('F1').getValue() ] );
projectState.push( [ sheets[i].getRange('K1').getValue() ] );
workingHours.push( [ sheets[i].getRange('K2').getValue() ] );
sheetLink.push( [ sheets[i].getSheetId() ] )
}
//set cell values in the master sheet
for (var i=0; i<sheetnames.length; i++){
masterSheet.getRange(i +1, 1).setValue(sheetnames[i]);
masterSheet.getRange(i +1, 2).setValue(budgetSums[i]);
masterSheet.getRange(i +1, 3).setValue(projectState[i]);
masterSheet.getRange(i +1, 4).setValue(workingHours[i]);
}
并像这样重写它们:
for (var i=0 ; i<sheets.length ; i++) {
masterSheet.getRange(i+1,1,1,4).setValues([[sheets[i].getName(),sheets[i].getRange('F1').getValue(),sheets[i].getRange('K1').getValue(),getRange('K2').getValue()]]);
sheetLink.push( [sheets[i].getSheetId()])
}
我尚未测试此代码,因此可能需要进行一些调整才能使其正常工作。
如果您可以重构用户界面,以便可以将它们全部放在一个 getValues() 中,那就太好了,但您必须考虑这可能会如何影响您的用户。当然,一种可能性是使用对话框进行数据输入,然后如何存储数据并不重要。但使用电子表格进行数据输入比为所有数据输入构建自定义对话框要简单得多。
仔细查看后,我认为您可能会一直这样做:
for (var i=0 ; i<sheets.length ; i++) {
masterSheet.getRange(i+1,1,1,5).setValues([[sheets[i].getName(),sheets[i].getRange('F1').getValue(),sheets[i].getRange('K1').getValue(),getRange('K2').getValue(), '=HYPERLINK("#gid=' + sheets[i].getSheetId() + '";"' + sheetnames[i] + '")']]);
}
如果您能为我们提供一个示例电子表格,我很乐意尝试使其正常工作。不要让我们与包含私有(private)信息的东西 Hook ,否则您将无法承受损失。
我认为我不想在 onEdit(e) 触发器中运行它。请记住,简单的触发器需要在 30 秒内完成。
关于arrays - Apps 脚本从不同工作表获取数据的功能很慢,我该如何优化它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57234821/