Google 应用程序脚本超出了最大执行限制
Google App Script Exceeded Maximum Execution Limit
我一直在尝试导出 spreadsheet 的全部内容。该代码工作正常,但它显示一条错误消息,指出 超出最大执行限制 。根据我的研究,最长执行时间只有 6 分钟。我对此很陌生,但仍在努力弄清楚。你能帮我确定一个可能的解决方案吗?
这是我目前正在使用的 ...
function PrintMultiple() {
const srcSs = SpreadsheetApp.getActiveSpreadsheet();
const sheet = srcSs.getSheetByName("TEMPLATE");
const values = sheet.getRange("C2").getDataValidation().getCriteriaValues()[0].getValues().flat().filter(String);
const dstSs = SpreadsheetApp.create("tempSpreadsheet");
SpreadsheetApp.getActive().toast("About to take some action... Please wait...");
values.forEach(v => {
sheet.getRange("C2").setValue(v);
SpreadsheetApp.flush();
const tempSheet = sheet.copyTo(srcSs);
const range = tempSheet.getDataRange();
range.copyTo(range, {contentsOnly: true});
tempSheet.getRange("B2:2").clear().clearDataValidations();
tempSheet.getDrawings().forEach(e => e.remove());
tempSheet.deleteColumn(1);
tempSheet.deleteRow(1);
tempSheet.deleteRow(2);
tempSheet.deleteRow(3);
tempSheet.copyTo(dstSs);
srcSs.deleteSheet(tempSheet);
});
dstSs.deleteSheet(dstSs.getSheets()[0]);
}
我相信你的目标如下。
- 您想减少脚本的处理成本。
从你的脚本来看,当values
的长度很大时,我认为复制的过程可能是成本高的。那么,在这种情况下,使用 Sheets API 怎么样?我认为当使用 Sheets API 时,您的脚本的处理成本可能会降低。当 Sheets API 用于您的脚本时,它变成如下。
修改后的脚本:
在您使用此脚本之前,please enable Sheets API at Advanced Google services。
function PrintMultiple() {
const ss = SpreadsheetApp.getActiveSpreadsheet().copy("tempSpreadsheet");
const sheet = ss.getSheetByName("TEMPLATE");
const sourceSheetId = sheet.getSheetId();
sheet.getDrawings().forEach(e => e.remove());
const values = sheet.getRange("C2").getDataValidation().getCriteriaValues()[0].getValues().flat().filter(String);
const requests1 = values.flatMap((v, i) => {
const sheetId = 123456 + i;
return [
{ duplicateSheet: { newSheetName: `page${i + 1}`, sourceSheetId, newSheetId: sheetId, insertSheetIndex: i + 2 } },
{ updateCells: { range: { sheetId: sheetId, startRowIndex: 1, endRowIndex: 2, startColumnIndex: 2, endColumnIndex: 3 }, rows: [{ values: [{ userEnteredValue: { numberValue: v } }] }], fields: "userEnteredValue.numberValue" } },
];
});
Sheets.Spreadsheets.batchUpdate({ requests: requests1 }, ss.getId());
const requests2 = values.flatMap((_, i) => {
const sheetId = 123456 + i;
return [
{ copyPaste: { source: { sheetId }, destination: { sheetId }, pasteType: "PASTE_VALUES" } },
{ deleteDimension: { range: { sheetId, startIndex: 0, endIndex: 3, dimension: "ROWS" } } },
{ deleteDimension: { range: { sheetId, startIndex: 0, endIndex: 1, dimension: "COLUMNS" } } },
];
});
Sheets.Spreadsheets.batchUpdate({ requests: requests2 }, ss.getId());
ss.deleteSheet(sheet);
ss.deleteSheet(ss.getSheets()[0]);
}
- 本次修改使用Sheets的batchUpdate方法API进行值的复制和行列的删除
- 当此脚本为 运行 时,将在根文件夹中创建“tempSpreadsheet”电子表格。
参考:
我一直在尝试导出 spreadsheet 的全部内容。该代码工作正常,但它显示一条错误消息,指出 超出最大执行限制 。根据我的研究,最长执行时间只有 6 分钟。我对此很陌生,但仍在努力弄清楚。你能帮我确定一个可能的解决方案吗?
这是我目前正在使用的
function PrintMultiple() {
const srcSs = SpreadsheetApp.getActiveSpreadsheet();
const sheet = srcSs.getSheetByName("TEMPLATE");
const values = sheet.getRange("C2").getDataValidation().getCriteriaValues()[0].getValues().flat().filter(String);
const dstSs = SpreadsheetApp.create("tempSpreadsheet");
SpreadsheetApp.getActive().toast("About to take some action... Please wait...");
values.forEach(v => {
sheet.getRange("C2").setValue(v);
SpreadsheetApp.flush();
const tempSheet = sheet.copyTo(srcSs);
const range = tempSheet.getDataRange();
range.copyTo(range, {contentsOnly: true});
tempSheet.getRange("B2:2").clear().clearDataValidations();
tempSheet.getDrawings().forEach(e => e.remove());
tempSheet.deleteColumn(1);
tempSheet.deleteRow(1);
tempSheet.deleteRow(2);
tempSheet.deleteRow(3);
tempSheet.copyTo(dstSs);
srcSs.deleteSheet(tempSheet);
});
dstSs.deleteSheet(dstSs.getSheets()[0]);
}
我相信你的目标如下。
- 您想减少脚本的处理成本。
从你的脚本来看,当values
的长度很大时,我认为复制的过程可能是成本高的。那么,在这种情况下,使用 Sheets API 怎么样?我认为当使用 Sheets API 时,您的脚本的处理成本可能会降低。当 Sheets API 用于您的脚本时,它变成如下。
修改后的脚本:
在您使用此脚本之前,please enable Sheets API at Advanced Google services。
function PrintMultiple() {
const ss = SpreadsheetApp.getActiveSpreadsheet().copy("tempSpreadsheet");
const sheet = ss.getSheetByName("TEMPLATE");
const sourceSheetId = sheet.getSheetId();
sheet.getDrawings().forEach(e => e.remove());
const values = sheet.getRange("C2").getDataValidation().getCriteriaValues()[0].getValues().flat().filter(String);
const requests1 = values.flatMap((v, i) => {
const sheetId = 123456 + i;
return [
{ duplicateSheet: { newSheetName: `page${i + 1}`, sourceSheetId, newSheetId: sheetId, insertSheetIndex: i + 2 } },
{ updateCells: { range: { sheetId: sheetId, startRowIndex: 1, endRowIndex: 2, startColumnIndex: 2, endColumnIndex: 3 }, rows: [{ values: [{ userEnteredValue: { numberValue: v } }] }], fields: "userEnteredValue.numberValue" } },
];
});
Sheets.Spreadsheets.batchUpdate({ requests: requests1 }, ss.getId());
const requests2 = values.flatMap((_, i) => {
const sheetId = 123456 + i;
return [
{ copyPaste: { source: { sheetId }, destination: { sheetId }, pasteType: "PASTE_VALUES" } },
{ deleteDimension: { range: { sheetId, startIndex: 0, endIndex: 3, dimension: "ROWS" } } },
{ deleteDimension: { range: { sheetId, startIndex: 0, endIndex: 1, dimension: "COLUMNS" } } },
];
});
Sheets.Spreadsheets.batchUpdate({ requests: requests2 }, ss.getId());
ss.deleteSheet(sheet);
ss.deleteSheet(ss.getSheets()[0]);
}
- 本次修改使用Sheets的batchUpdate方法API进行值的复制和行列的删除
- 当此脚本为 运行 时,将在根文件夹中创建“tempSpreadsheet”电子表格。