有没有办法使这个循环更有效?

时间:2019-02-05 04:51:46

标签: google-apps-script google-sheets

我有一个Google表格,我正在其中编制清单。我最近注意到了许多数学错误,因此我决定减少思维上的加法并建立一个Apps Script循环,该循环添加两个列并为我重置第一列。但是因为我基本上在每个循环中都使用getValue,所以这是一个非常耗时的过程。

我试图寻找写入数组等的方法,但这是我第一次涉足Google表格而不是Excel。

这是整个功能:

function Update() {

  var ss = SpreadsheetApp.getActive();

  var sheet = ss.getSheetByName('Name');


 for (var x = 2; x < 905; x++) {


  var range1 = sheet.getRange([x],7);

  var num1 = range1.getValue();

  var range2 = sheet.getRange([x],8)

  var num2 = range2.getValue();


  range2.setValue(num1 + num2)

  range1.setValue ('0')

  }
}

它可以正常工作,但是速度确实很慢,我希望您能获得一些使它更有效的提示。

2 个答案:

答案 0 :(得分:3)

尝试一下:

function Update() {
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getSheetByName('Name');
  var rg=sh.getRange(2,7,904,2);
  var vA=rg.getValues();
  for(var i=0;i<vA.length;i++){
    vA[i][1]=vA[i][0]+vA[i][1];
    vA[i][0]=0;
  }
  rg.setValues(vA);
}

答案 1 :(得分:2)

如Cooper的答案所示,您想使用"best practices"的批处理Range方法getValuessetValues来操纵JavaScript数组

一种改进是使用Array类方法来减少嵌套属性访问,例如map(基于源数组返回数组)或forEach(对每个源数组中的元素)。这些类方法为您的回调函数提供了当前元素,索引和源数组作为函数参数(如果需要)。

当您想要短路行为(一旦满足某些条件时停止处理)时,传统的基于索引的for循环仍然是最重要的。

function processArray() {
  const wb = SpreadsheetApp.getActive();
  const sheet = wb.getSheetByName('Name');

  const startRow = 2, endRow = 905;
  const startCol = 7, numCols = 2;
  const rg = sheet.getRange(startRow, startCol, endRow - startRow + 1, numCols);

  // Construct a new array based on the source array.
  const result = rg.getValues().map(function (row) {
    return [ 0, row[0] + row[1] ];
  });
  // (In this case we haven't changed the dimensions, so we could re-use `rg` .)
  if (result.length) {
    // sheet.getRange(someRow, someCol, result.length, result[0].length).setValues(result);
    rg.setValues(result);
  }
}

(请注意,当前Apps脚本不支持const的块范围使用,仅支持重新分配保护)