查找和复制的慢速循环



我已经编写了一个创建报告的函数:

  1. 检测特定范围内是否有特定字母(函数要求用户输入字母和列)
  2. 如果有字母,则抓取整行
  3. 将其复制到另一张图纸

我的代码目前正在运行,但需要很长时间才能完成。此外,如果我有超过数百个结果,我会遇到超时问题。

你可以在这里复制这个问题:

https://docs.google.com/spreadsheets/d/1ggVvxquruYfckNWxhsV6-Od2J8QIkMOYpJps7qz9PkI/edit?usp=sharing

这是代码:

for(var i = 0; i<rapport.length-1; i++) {
if(colonneCode[i] == code.getResponseText()) {
ligneCode[v] = i;
v++;
}
}
for(var i = 0; i<ligneCode.length;i++) {

var codeLastRow = 12;
var copySource = sheet.getRange(ligneCode[i]+10, 1, 1, 16);
var copyTarget = feuille.getRange(feuille.getLastRow()+1,1,1,16);
copyTarget.setValues(copySource.getValues());
copySource.copyTo(copyTarget, {formatOnly:true});
}

点击个性化菜单(Éevaluations Philippe Caron)->个人分类->第一输入框";2〃->第二输入框";e"->第三个是您想要的新工作表的名称。

评测代码

我使用这些片段来检查您的代码的时间。

let start = new Date()
Logger.log("before first for loop")
Logger.log(new Date().getTime() - start.getTime())

正如您可能猜到的,对于您工作表上的e示例,直到第二个for循环之前的大部分代码都在大约1秒内运行。然而,第二次循环花了大约45秒。本部分:

for(var i = 0; i<ligneCode.length;i++) {

var codeLastRow = 12;
var copySource = sheet.getRange(ligneCode[i]+10, 1, 1, 16);
var copyTarget = feuille.getRange(feuille.getLastRow()+1,1,1,16);
copyTarget.setValues(copySource.getValues());
copySource.copyTo(copyTarget, {formatOnly:true});
}

为什么这个代码很慢

因为在每一次迭代中,它都在调用getRangegetValuessetValuescopyTo。所有这些命令都要求应用程序脚本执行从电子表格中读取和写入。这很慢。

倾倒整个范围

将整个范围收集在一个大的2D阵列和setValues中要快得多。这需要首先在应用程序脚本中构建范围。因此,不将行的索引号存储在ligneCode中,而是将整行存储在output中。

顺便说一句,您可以使用array.push(item)将项添加到数组的末尾。无需跟踪索引号。

所以不是这样:

var ligneCode = [];
for(var i = 0; i<rapport.length-1; i++) {
if(colonneCode[i] == code.getResponseText()) {
ligneCode[v] = i;
v++;
}
}

构建一个数组,表示要粘贴到新工作表中的内容。

var output = [];
for (var i = 0; i < rapport.length - 1; i++) {
if (colonneCode[i] == code.getResponseText()) {
output.push(rapport[i]);
}
}

一旦你有了新的工作表feuille,你所需要做的就是:

var target = feuille.getRange(
11, // first row
1, // first column
output.length, // the height of the output
output[0].length // the width of the output
);
target.setValues(output);

结果

现在,以e为例,整个脚本运行大约需要2秒。

参考

  • 应用程序脚本文档中的Range类
  • setValues详细信息

最新更新