Google 张脚本超过最大执行时间
Google sheets script Exceeded maximum execution time
我编写了一个脚本,将股票数据从存储在 Google 驱动器中的 csv 文件导入到现有的 google sheet.
在一个函数中,我对多个 csv 文件执行此操作。不幸的是,我有时会收到“超出最大执行时间”,但并非总是如此。
你知道我可以如何提高性能吗:
//++++++++++++++ SPY +++++++++++++++++++
var file = DriveApp.getFilesByName("SPY.csv").next();
var csvData = Utilities.parseCsv(file.getBlob().getDataAsString());
//Create new temporary sheet
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var yourNewSheet = activeSpreadsheet.getSheetByName("SPY-Import");
if (yourNewSheet != null) {
activeSpreadsheet.deleteSheet(yourNewSheet);
}
yourNewSheet = activeSpreadsheet.insertSheet();
yourNewSheet.setName("SPY-Import");
//Import
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
//Copy from temporary sheet to destination
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A:B').activate();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('SPY'), true);
spreadsheet.getRange('A2').activate();
spreadsheet.getRange('\'SPY-Import\'!A:B').copyTo(spreadsheet.getActiveRange(),
SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
//Delete temporary sheet
// Get Spreadsheet Object
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// Get target sheet object
var sheet = spreadsheet.getSheetByName("SPY-Import");
// Delete
spreadsheet.deleteSheet(sheet);
提前致谢!
我相信你的情况和目标如下。
- 您有多个 CSV 文件,例如
SPY.csv
。
- 您的 Spreadsheet 有几个 sheet 对应于每个 CSV 文件,例如
SPY
.
- 您想将 CSV 数据中的值放入 Spreadsheet。
- 您想输入 CSV 数据的“A”列和“B”列的值。
- 在您目前的情况下,您多次复制问题中的脚本,并通过更改 csv 文件名和 sheet 名称 运行 它们。
- 您想减少脚本的处理成本。我是这样理解你的目标的。
修改点:
SpreadsheetApp.getActiveSpreadsheet()
被多次使用。并且,activate()
被多次使用。
- 我觉得你的情况,
SpreadsheetApp.getActiveSpreadsheet()
可以声明一次,activate()
不需要使用
- 为了将 CSV 数据复制到 Spreadsheet,CSV 数据被放入临时 sheet,所需的值被复制到目标 sheet。
- 在这种情况下,我认为CSV数据是通过数组处理直接放到目的地sheet。
我认为以上几点可以降低工艺成本。当以上几点反映到你的脚本中,就变成了下面这样。
修改后的脚本:
请复制粘贴以下脚本,准备obj
的变量。当您 运行 脚本时,将检索和处理 CSV 数据,然后将值放入 Spreadsheet.
function myFunction() {
var obj = [
{filename: "SPY.csv", sheetname: "SPY"},
{filename: "###.csv", sheetname: "###"},
,
,
,
];
var ss = SpreadsheetApp.getActiveSpreadsheet();
obj.forEach(({filename, sheetname}) => {
var file = DriveApp.getFilesByName(filename);
if (file.hasNext()) {
var sheet = ss.getSheetByName(sheetname);
if (sheet) {
// sheet.clearContents(); // Is this requierd in your situation?
var csv = DriveApp.getFileById(file.next().getId()).getBlob().getDataAsString();
var values = Utilities.parseCsv(csv).map(([a, b]) => [a, b]);
sheet.getRange(2, 1, values.length, 2).setValues(values);
}
}
});
}
注:
- 请在启用 V8 的情况下使用此脚本
- 我不确定你的 CSV 数据。所以当不能使用
Utilities.parseCsv(csv)
时,请使用分隔符
- 本次修改使用了Spreadsheet服务。如果上面修改后的脚本出现
Exceeded maximum execution time
同样的错误,请告诉我。那时,我想建议使用 Sheets API. 的示例脚本
参考文献:
我编写了一个脚本,将股票数据从存储在 Google 驱动器中的 csv 文件导入到现有的 google sheet.
在一个函数中,我对多个 csv 文件执行此操作。不幸的是,我有时会收到“超出最大执行时间”,但并非总是如此。
你知道我可以如何提高性能吗:
//++++++++++++++ SPY +++++++++++++++++++
var file = DriveApp.getFilesByName("SPY.csv").next();
var csvData = Utilities.parseCsv(file.getBlob().getDataAsString());
//Create new temporary sheet
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var yourNewSheet = activeSpreadsheet.getSheetByName("SPY-Import");
if (yourNewSheet != null) {
activeSpreadsheet.deleteSheet(yourNewSheet);
}
yourNewSheet = activeSpreadsheet.insertSheet();
yourNewSheet.setName("SPY-Import");
//Import
var sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
//Copy from temporary sheet to destination
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A:B').activate();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('SPY'), true);
spreadsheet.getRange('A2').activate();
spreadsheet.getRange('\'SPY-Import\'!A:B').copyTo(spreadsheet.getActiveRange(),
SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
//Delete temporary sheet
// Get Spreadsheet Object
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// Get target sheet object
var sheet = spreadsheet.getSheetByName("SPY-Import");
// Delete
spreadsheet.deleteSheet(sheet);
提前致谢!
我相信你的情况和目标如下。
- 您有多个 CSV 文件,例如
SPY.csv
。 - 您的 Spreadsheet 有几个 sheet 对应于每个 CSV 文件,例如
SPY
. - 您想将 CSV 数据中的值放入 Spreadsheet。
- 您想输入 CSV 数据的“A”列和“B”列的值。
- 在您目前的情况下,您多次复制问题中的脚本,并通过更改 csv 文件名和 sheet 名称 运行 它们。
- 您想减少脚本的处理成本。我是这样理解你的目标的。
修改点:
SpreadsheetApp.getActiveSpreadsheet()
被多次使用。并且,activate()
被多次使用。- 我觉得你的情况,
SpreadsheetApp.getActiveSpreadsheet()
可以声明一次,activate()
不需要使用
- 我觉得你的情况,
- 为了将 CSV 数据复制到 Spreadsheet,CSV 数据被放入临时 sheet,所需的值被复制到目标 sheet。
- 在这种情况下,我认为CSV数据是通过数组处理直接放到目的地sheet。
我认为以上几点可以降低工艺成本。当以上几点反映到你的脚本中,就变成了下面这样。
修改后的脚本:
请复制粘贴以下脚本,准备obj
的变量。当您 运行 脚本时,将检索和处理 CSV 数据,然后将值放入 Spreadsheet.
function myFunction() {
var obj = [
{filename: "SPY.csv", sheetname: "SPY"},
{filename: "###.csv", sheetname: "###"},
,
,
,
];
var ss = SpreadsheetApp.getActiveSpreadsheet();
obj.forEach(({filename, sheetname}) => {
var file = DriveApp.getFilesByName(filename);
if (file.hasNext()) {
var sheet = ss.getSheetByName(sheetname);
if (sheet) {
// sheet.clearContents(); // Is this requierd in your situation?
var csv = DriveApp.getFileById(file.next().getId()).getBlob().getDataAsString();
var values = Utilities.parseCsv(csv).map(([a, b]) => [a, b]);
sheet.getRange(2, 1, values.length, 2).setValues(values);
}
}
});
}
注:
- 请在启用 V8 的情况下使用此脚本
- 我不确定你的 CSV 数据。所以当不能使用
Utilities.parseCsv(csv)
时,请使用分隔符 - 本次修改使用了Spreadsheet服务。如果上面修改后的脚本出现
Exceeded maximum execution time
同样的错误,请告诉我。那时,我想建议使用 Sheets API. 的示例脚本