有没有一种方法可以加快Google Script中的for循环?

时间:2020-04-02 14:03:33

标签: for-loop google-apps-script google-sheets

我有一个for循环正在使用我的Google表格,但是大约需要5分钟来过滤2100行数据。我已经读过关于使用过滤器以及一起摆脱for循环的知识,但是我对使用Google Script编码非常陌生,还无法完全理解语法。任何建议,不胜感激。

下面的代码:

function Inspect() {a

   var sSheet = SpreadsheetApp.getActiveSpreadsheet();
   var srcSheet = sSheet.getSheetByName("Inventory");
   var tarSheet = sSheet.getSheetByName("Inspections");
   var lastRow = srcSheet.getLastRow();

   for (var i = 2; i <= lastRow; i++) {
var cell = srcSheet.getRange("A" + i);
var val = cell.getValue();
if (val == true) {

  var srcRange = srcSheet.getRange("B" + i + ":I" + i);
  var clrRange = srcSheet.getRange("A" + i);

  var tarRow = tarSheet.getLastRow();
  tarSheet.insertRowAfter(tarRow);
  var tarRange = tarSheet.getRange("A" + (tarRow+1) + ":H" + (tarRow+1));
  var now = new Date();
  var timeRange = tarSheet.getRange("I"+(tarRow+1));
  timeRange.setValue(now);

  srcRange.copyTo(tarRange);
  clrRange.clear();
  //tarRange.activate();
  timeRange.offset(0, 1).activate();
}

}

};  

2 个答案:

答案 0 :(得分:1)

是的,要加快速度,您需要首先获取所有值,并将逻辑应用于获取的2D数组而不是单元格,最后,将使用setValues来更新工作表。我会选择这样的东西:

function Inspect() {

  var sSheet = SpreadsheetApp.getActiveSpreadsheet();
  var srcSheet = sSheet.getSheetByName("Inventory");
  var tarSheet = sSheet.getSheetByName("Inspections");
  var srcLastRow = srcSheet.getLastRow();
  var tarLastRow = tarSheet.getLastRow();

  var srcArray = srcSheet.getRange(1,1,srcLastRow,9).getValues();//(A1:I(lastrow))
  var tarArray = tarSheet.getRange(1,1,tarLastRow,9).getValues();//(A1:I(lastrow))

  for (var i = 1; i < srcArray.length; i++) {
    var val = srcArray[i][0];
    if (val == true) {
      var copyValues = srcArray[i].slice(1);//Get all elements from the row excluding first column (srcSheet.getRange("B" + i + ":I" + i);)
      var now = new Date();
      copyValues[8]=now;//set the time on column 9 (array starts at position 0!)

      var tarNewLine = copyValues;
      tarArray.push(tarNewLine);
      //clear values on source (except column A):
      for(var j=1;j<srcArray[i].length;j++){
        srcArray[i][j]="";    
      }
    }    
  } 
  tarSheet.clear();
  tarSheet.getRange(1, 1,tarArray.length,tarArray[0].length).setValues(tarArray);
  srcSheet.clear();
  srcSheet.getRange(1, 1,srcArray.length,srcArray[0].length).setValues(srcArray);
}; 

答案 1 :(得分:0)

您无法绕开循环,但应将对SpreadsheetApp的调用次数减至最少,请参阅Apps Script Best Practices

不是for循环,而是那些使您的代码变慢的调用。取而代之的是,尽可能多地使用数组。如果循环是嵌套的,则成为一个问题-这也是您应避免的事情。

示例如何在循环外执行对SpreadsheetApp的大多数调用并使用数组:

function Inspect() {  
  var sSheet = SpreadsheetApp.getActiveSpreadsheet();
  var srcSheet = sSheet.getSheetByName("Inventory");
  var tarSheet = sSheet.getSheetByName("Inspections");
  var lastRow = srcSheet.getLastRow();  
  var Acolumn =  srcSheet.getRange("A2:A" + lastRow);
  var Avalues = Acolumn.getValues();
  var srcRange = srcSheet.getRange("B2:I" + lastRow);
  var srcValues = srcRange.getValues();
  var array = [];
  var now = new Date();
  for (var i = 0; i < lastRow-1; i++) {  
    var val = Avalues[i][0];
    if (val == true) {
      srcValues[i].push(now);
      array.push(srcValues[i]);
      var clrRange = Acolumn.getCell(i+1, 1);
      clrRange.clear();
    }
  }
  var tarRow = tarSheet.getLastRow();
  tarSheet.insertRowAfter(tarRow);
  if(array.length!=0){
    var tarRange = tarSheet.getRange("A" + (tarRow+1) + ":I" + (tarRow  + array.length));
    tarRange.setValues(array);

  }
};