2D阵列问题 - Google Apps脚本

时间:2018-06-04 19:08:34

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

我正在尝试循环测试A列中的值的大范围单元格,如果返回true,那么我想将相邻的3个单元格(BD列)存储在数组中并最终将数组粘贴到单独的工作表上。当前代码查找所有正确的值,但它将它们全部写入一行而不是像原始数据源中那样将多行和3列写入。

var dataset = [],
    month,
    i,
    j,
    x = 0,
    targetmonth = ss.getSheetByName("BOH").getRange("B2").getValue(),
    location = ss.getSheetByName(output).getRange("D3").getValue();

for ( i = 7; i < 3000; i++){
  month = ss.getSheetByName(location).getRange(i,1).getValue();
  if (month == targetmonth){
    for (j = 2; j<5; j++){
      dataset [x] = [ss.getSheetByName(location).getRange(i,j).getValues()];
      x = x + 1;
    } 
  }
}

//I've changed the range size in line below to 360x3 which is what it should be 
//but this line currently only runs when set to 1x360

ss.getSheetByName(output).getRange(8,3,360,3).setValues([dataset]);

1 个答案:

答案 0 :(得分:0)

遵循最佳做法,您应该通过使用getValues()最大限度地减少对电子表格服务的重复调用。您当前的脚本循环将逐个访问A7:A2999的值,当它可以在一次读取中执行时:

// const x -> no reassignment / redeclaring x allowed. (You can still manipulate the object).
const startRow = 7, endRow = 2999,
    numRows = endRow - startRow + 1;
const months = ss.getSheetByName(location)
  .getRange(startRow, 1, numRows, 1).getValues();

然后您有条件地访问相同范围的列B:D。您会发现,在开始时将其全部读入内存仍然更快,并且只访问您想要的行和需要时列:

const startCol = 2, endCol = 4,
    numCols = endCol - startCol + 1;
const targetValues = ss.getSheetByName(location)
  .getRange(startRow, startCol, numRows, numCols).getValues();

您还应该使用比ij更有意义的迭代索引名称,并且您不必在函数的开头声明所有内容(请参阅JavaScript和&#39;当使用点更有意义时,吊装&#39;)。

你的其余功能看起来像这样:

const output = [],
    targetMonth = /** set this */,
    destinationName = /** set this */;
for (var monthIndex = 0; monthIndex < months.length; ++monthIndex) {
  // Add the array of target column values to the output (by reference)
  if (months[monthIndex][0] === targetMonth) {
    output.push(targetValues[monthIndex]);
  }
}
// Write the output array.
ss.getSheetByName(destinationName).getRange(8, 3, output.length, output[0].length).setValues(output);

我们刚从~numRows x numColumns Spreadsheet访问到~4!鉴于单个小区访问呼叫大约需要0.1秒,这将是boatloads faster。是的,如果你读了很多细胞,它可能需要一段时间(从400k细胞获得/设定值约为30秒),但只要1对1的访问就不会有任何接近。

参考文献:

PS:如果在序列化数据之前更改targetValues中的值,那么output中引用的值也会更新,因为它们是同一个对象。 (阅读&#34;按值&#34; /深拷贝和&#34;通过引用&#34; /浅拷贝来理解原因。对于这个编写的脚本,区别无关紧要,因为它们没有被修改。)