我试图循环通过一个大范围的单元格测试A列中的值,如果返回true,那么我想将相邻的3个单元格(B-D列)存储在一个数组中,并最终将该数组粘贴到一个单独的工作表上。当前代码找到所有正确的值,但它将它们全部写入一行,而不是像原始数据源中那样的多行和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]);
发布于 2018-06-05 06:16:13
遵循最佳实践,您应该通过使用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();
您还应该使用比i
和j
更有意义的迭代索引名称,并且不必在函数开始时声明所有内容(请阅读有关JavaScript和“提升”的内容),此时使用点更有意义。
然后,函数的其余部分如下所示:
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);
我们刚刚从~numRow x numColumns电子表格访问次数减少到~4次!考虑到单个手机接入呼叫大约需要0.1秒,这将是boatloads faster。是的,如果你读取大量的单元格,这可能需要一段时间(从400k单元格获取/设置值大约需要30秒),但这远远比不上1x1的访问。
参考文献:
Range#getValues()
Sheet#getRange(r, c, nR, nC)
Array#push
PS:如果在序列化数据之前更改targetValues
中的值,那么output
中引用的值也会更新,因为它们是同一个对象。(请阅读“按值”/“深层复制”和“按引用”/浅层复制以了解原因。对于编写的这个脚本,区别并不重要,因为它们没有被修改。)
https://stackoverflow.com/questions/50687249
复制相似问题