[英]Google app script exceeded execution time limit
我有一个包含近 160 个子工作表的 Google 工作表。 所有问题都在“全部”表中,B 列是它们应该在的实际电子表格名称。 以下代码正在从“所有”电子表格中读取数据,并将它们完美地发送到所需电子表格的最后一行,但这需要很长时间。 可能是因为它有很多子表并且一次又一次地使用 getSheetByName。 现在我已经将所有子工作表的名称和 ID 一次存储在“工作表”和“工作表 ID”arrays 中。 我正在考虑比较rangeValues[j][1]
和sheetNames[k][0]
。 以下是电子表格的代码和屏幕截图。
这是合适的方式吗? 请帮助我更快地运行脚本!
var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName("All"); var rangeData = sheet.getDataRange(); var lastRow = rangeData.getLastRow(); var searchRange = sheet.getRange(1,1, lastRow, 8); var curr_sheet; function send() { var rangeValues = searchRange.getValues(); var sheetNames = new Array(); var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets(); for (var i=0; i<sheets.length; i++) sheetNames.push( [ sheets[i].getName() ] ); //Logger.log (sheetNames.length); var sheetID = new Array(); var sheetIDs = SpreadsheetApp.getActiveSpreadsheet().getSheets(); for (var i=0; i<sheetIDs.length; i++) sheetID.push( [ sheetIDs[i].getSheetId() ] ); //Logger.log (sheetID.length); for ( j = 0; j < lastRow; j++) { for ( k = 0; k < sheetNames.length; k++) // { if (rangeValues[j][1] === sheetNames[k][0]) { var targetSheet = ss.getSheetByName(sheetNames[k][0]); // This line is working but taking very long to complete var targetSheet = ss.getSheetByID(sheetIDs[k][0]); // This line is not code just to show what I'm thinking to do. targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, 8).setValues([rangeValues[j]]); } } } }
我相信你的目标如下。
Class 电子表格中没有getSheetByID
的方法。 这样,我认为在您的情况下,可以删除以下脚本。
var sheetID = new Array(); var sheetIDs = SpreadsheetApp.getActiveSpreadsheet().getSheets(); for (var i=0; i<sheetIDs.length; i++) sheetID.push( [ sheetIDs[i].getSheetId() ] );
在您的脚本中,循环中使用了getSheetByName
和getRange(###).setValues(###)
。 而且,即使工作表是同一张工作表,每一行都会在每一行的循环中使用setValues
放置。 在这种情况下,处理成本会很高。 我认为这些情况可能是您的问题的原因。
幸运的是,在您的情况下,所有工作表都在同一个电子表格中。 因此,为了降低脚本的处理成本,在这里,我想建议使用 Sheets API 将值放入每个工作表。 修改脚本的流程如下。
当以上几点反映到您的脚本时,它变成如下。
请复制并粘贴以下脚本。 并且, 请在高级 Google 服务中启用表格 API 。 然后,请运行脚本。
function send() {
// 1. Retrieve Spreadsheet and values. This script is from your script.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("All");
var rangeData = sheet.getDataRange();
var lastRow = rangeData.getLastRow();
var searchRange = sheet.getRange(1,1, lastRow, 8);
var curr_sheet;
var rangeValues = searchRange.getValues();
// 2. Retrieve all sheets in the Spreadsheet.
var sheets = ss.getSheets().reduce((o, e) => Object.assign(o, {[e.getSheetName()]: e}), {});
// 3. Check whether the sheet names from the column "B" are existing.
// 4. Create the object for putting to each sheet using Sheets API.
var data = rangeValues.reduce((o, e) => {
if (sheets[e[1]]) {
if (o[e[1]]) {
o[e[1]].values.push(e);
} else {
o[e[1]] = {range: `'${e[1]}'!A${sheets[e[1]].getLastRow() + 1}`, values: [e]};
}
}
return o;
}, {});
// 5. Request the method of spreadsheets.values.batchUpdate of Sheets API using the created object.
Sheets.Spreadsheets.Values.batchUpdate({data: Object.values(data), valueInputOption: "USER_ENTERED"}, ss.getId());
}
尝试这个:
应该快很多
function send() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName("All");
var rg=sh.getRange(1,1,sh.getLastRow(),8);
var v=rg.getValues();
var names=[];
var sheets=ss.getSheets();
sheets.forEach(function(sh,i){names.push(sh.getName());});
v.forEach(function(r){
let idx=names.indexOf(r[1]);//column2
if(idx!=-1) {
sheets[idx].getRange(sheets[idx].getLastRow()+1,1,1,8).setValues([r]);
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.