简体   繁体   English

工作表的Google脚本-超过了最大执行时间

[英]Google Script for a Sheet - Maximum Execution time Exceeded

I'm writing a script that's going to look through a monthly report and create sheets for each store for a company we do work for and copy data for each to the new sheets. 我正在编写一个脚本,该脚本将浏览一份月度报告,并为我们工作的公司的每个商店创建工作表,并将每个工作表的数据复制到新工作表中。 Currently the issue I'm running into is that we have two days of data and 171 lines is taking my script 369.261 seconds to run and it is failing to finish. 目前,我遇到的问题是,我们有两天的数据,并且有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.");
}

Any help would be greatly appreciated as I'm still relatively new at using this, and I'm sure there are plenty of ways to speed this up, if not, I'll end up finding a way to break down the function to divide up the execution. 由于我在使用此功能时还比较陌生,因此将不胜感激,并且我确信有很多方法可以加快此速度,否则,我将最终找到一种方法来分解除以执行。 If need be, I can also provide some sample data if need be. 如果需要,我还可以提供一些示例数据。

Thanks in advance. 提前致谢。

The problem is calling SpreadsheepApp lib related methods like getRange() in each iteration. 问题是在每次迭代中都调用SpreadsheepApp lib相关的方法,例如getRange() As stated here: 如此处所述:

Using JavaScript operations within your script is considerably faster than calling other services. 在脚本中使用JavaScript操作比调用其他服务要快得多。 Anything you can accomplish within Google Apps Script itself will be much faster than making calls that need to fetch data from Google's servers or an external server, such as requests to Spreadsheets, Docs, Sites, Translate, UrlFetch, and so on. 在Google Apps脚本本身中可以完成的任何事情,比进行需要从Google服务器或外部服务器获取数据的调用要快得多,例如对电子表格,文档,站点,翻译,UrlFetch等的请求。 Your scripts will run faster if you can find ways to minimize the calls the scripts make to those services. 如果您找到最小化脚本对这些服务的调用的方法,则脚本将运行得更快。

I ran into the same situation and, instead of doing something like for(i=0;i<data.length;i++) , I ended up dividing the data.length into 3 separate functions and ran them manually each time one of them ended. 我遇到了同样的情况,而不是像for(i=0;i<data.length;i++) ,我最终将data.length分为3个独立的函数,并在其中每个函数结束时手动运行了它们。 Same as you, I had a complex report to automate and this was the only solution. 和您一样,我有一个复杂的报表要自动化,这是唯一的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM