Google Sheet Script在工作表中循环并添加新行和文本

时间:2016-07-27 21:53:03

标签: google-apps-script google-sheets

我在google工作表中创建了我的第一个函数。基本上我按照我想要的方式工作但它达到了最大执行时间限制。我发布了下面的代码,我确信有一些方法可以优化它,以便它可以更快地运行。

代码基本上循环遍历工作表中的记录以添加图像文件名。每个产品有六个图像文件名,有时我需要添加新行来列出所有文件名,如下面的屏幕截图所示:

file structure

function myFunction() {

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var range = sheet.getDataRange();
  var values = range.getValues();

  var c = 1;

  for (var i=1; i<values.length; i++) {

    c = 1;

    do {
    c = c + 1;
    i = i + 1;
    } while (values[i+1][13] == values[i][13]);

    while (c < 6) {
    sheet.insertRowsAfter(i+1,1);
    c = c + 1;
    i = i + 1;
    sheet.getRange(i+1,1).setValue(values[i-1][0]);
    }

    range = sheet.getDataRange();
    values = range.getValues();


    if(c <= 6) {
      sheet.getRange(i-4,25).setValue(values[i-5][13] + "_main.jpg");
      sheet.getRange(i-3,25).setValue(values[i-5][13] + "_detail.jpg");
      sheet.getRange(i-2,25).setValue(values[i-5][13] + "_detail1.jpg");
      sheet.getRange(i-1,25).setValue(values[i-5][13] + "_detail2.jpg");
      sheet.getRange(i,25).setValue(values[i-5][13] + "_side.jpg");
      sheet.getRange(i+1,25).setValue(values[i-5][13] + "_back.jpg");
    }

    if(c > 6) {
      sheet.getRange(i-c+2,25).setValue(values[i-c+2][13] + "_main.jpg");
      sheet.getRange(i-c+3,25).setValue(values[i-c+2][13] + "_detail.jpg");
      sheet.getRange(i-c+4,25).setValue(values[i-c+2][13] + "_detail1.jpg");
      sheet.getRange(i-c+5,25).setValue(values[i-c+2][13] + "_detail2.jpg");
      sheet.getRange(i-c+6,25).setValue(values[i-c+2][13] + "_side.jpg");
      sheet.getRange(i-c+7,25).setValue(values[i-c+2][13] + "_back.jpg");
    }

}

1 个答案:

答案 0 :(得分:1)

一次大批量更新,而不是一堆小批量更新

你的问题是每次调用sheet.getRange相对于平均运行代码需要相当多的时间(~100 ms)。如果你在循环运行100次的情况下每循环执行10次,那么只需几秒钟,你的代码就会运行几分钟。

加快速度的方法是将所有这些小更新(每次sheet.getRange调用)并将其合并为一个大批量更新,按照此article by google about best practices with google scripts的建议。

例如,而不是这样做:

sheet.getRange(1, 1).setValue(1);
sheet.getRange(2, 1).setValue(2);
sheet.getRange(1, 2).setValue(3);
sheet.getRange(2, 2).setValue(4);

这样做:

sheet.getRange(1, 1, 2, 2).setValue([[1, 2], [3, 4]]);

如何使用您的代码

首先使用sheet.getDataRange().getValues()为尽可能少的I / O调用加载所需的所有数据。

接下来进行所有必要的计算而不读取和写入电子表格。如果需要,可以使用二维数组代替电子表格:

data = [["A", "tire.jpg"], ["B", "fire.jpg"]];
data[i+2][c-1] = values[3][8] + "_main.jpg";

完成后,您可以一次性将data写入电子表格:

sheet.getRange(1, 1, data.length, data[0].length).setValues(data);