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.
  • 的示例脚本

参考文献: