工作表的 Google 脚本 - 超出最长执行时间

Google Script for a Sheet - Maximum Execution time Exceeded

本文关键字:执行时间 Google 脚本 工作      更新时间:2023-09-26

我正在编写一个脚本,该脚本将查看月度报告,并为我们工作的公司的每家商店创建工作表,并将每个商店的数据复制到新工作表中。目前我遇到的问题是我们有两天的数据,171 行需要我的脚本 369.261 秒才能运行,并且无法完成。

function menuItem1() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet1 = ss.getSheetByName("All Stores");
  var data = sheet1.getDataRange().getValues();
  var CurStore;
  var stores = [];
  var target_sheet;
  var last_row;
  var source_range
  var target_range;
  var first_row = sheet1.getRange("A" + 1 +":I" + 1);
  //assign first store number into initial index of array
  CurStore = data[1][6].toString();
  //add 0 to the string so that all store numbers are four digits.
  while (CurStore.length < 4) {CurStore = "0" + CurStore;}
  stores[0] = CurStore;
  // traverse through every row and add all unique store numbers to the array
  for (var row = 2; row <= data.length; row++) {
    CurStore = data[row-1][6].toString(); 
    while (CurStore.length < 4) {
      CurStore = "0" + CurStore;
    }
    if (stores.indexOf(CurStore) == -1) {
      stores.push(CurStore.toString());
    }
  }
  // sort the store numbers into numerical order
  stores.sort();
  // traverse through the stores array, creating a sheet for each store, set the master sheet as the active so we can copy values, insert first row (this is for column labels), traverse though every row and when the unique store is found, 
  // we take the whole row and paste it onto it's newly created sheet
  // at the end push a notification to the user letting them know the report is finished.
  for (var i = stores.length -1; i >= 0; i--) {
    ss.insertSheet(stores[i].toString());
    ss.setActiveSheet(sheet1);
    target_sheet = ss.getSheetByName(stores[i].toString());
    last_row = target_sheet.getLastRow();
    target_range = target_sheet.getRange("A"+(last_row+1)+":G"+(last_row+1));
    first_row.copyTo(target_range);
    for (var row = 2; row <= data.length; row++) { 
      CurStore = data[row-1][6].toString();
      while (CurStore.length < 4) {
        CurStore = "0" + CurStore;
      }
      if (stores[i] == CurStore) {
        source_range = sheet1.getRange("A" + row +":I" + row);
        last_row = target_sheet.getLastRow();
        target_range = target_sheet.getRange("A"+(last_row+1)+":G"+(last_row+1));
        source_range.copyTo(target_range);
      }
    }
    for (var j = 1; j <= 9; j++) {
       target_sheet.autoResizeColumn(j);
    }
  }
  Browser.msgBox("The report has been finished.");
}

任何帮助将不胜感激,因为我在使用它方面仍然相对较新,而且我相信有很多方法可以加快速度,如果没有,我最终会找到一种方法来分解函数以划分执行。如果需要,如果需要,我还可以提供一些示例数据。

提前谢谢。

问题是在

每次迭代中调用SpreadsheepApp lib 相关方法,例如 getRange()。如下所述:

在脚本中使用 JavaScript 操作要快得多 而不是调用其他服务。您可以在 Google 中完成的任何任务 应用程序脚本本身将比进行需要的调用快得多 从 Google 的服务器或外部服务器获取数据,例如 对电子表格、文档、网站、翻译、网址提取等的请求。 如果您能找到最小化 脚本对这些服务进行的调用。

我遇到了同样的情况,而不是做类似 for(i=0;i<data.length;i++) 的事情,我最终将data.length分为 3 个单独的函数,并在每次其中一个函数结束时手动运行它们。和你一样,我有一个复杂的报告要自动化,这是唯一的解决方案。