【问题标题】:exceeded maximum execution time in google-apps-script超过了 google-apps-script 中的最大执行时间
【发布时间】:2013-06-21 06:23:20
【问题描述】:

我有两个电子表格。我想将spreadsheet1 的C 列与spreadsheet2 的A 列相匹配。这两个电子表格都有超过 8000 条记录。由于记录数量巨大,我的脚本不断给出exceeded maximum execution time 错误。这是脚本

function compare() {

var ss=SpreadsheetApp.getActiveSpreadsheet();
  var sheetList1=ss.getSheetByName("spreadsheet1");
  var sheetList2=ss.getSheetByName("spreadsheet2");

   var sheet1Data=sheetList1.getRange(2,3,sheetList1.getLastRow(),1).getValues();

   var sheet2Data=sheetList2.getRange(1,1,sheetList2.getLastRow(),1).getValues();

   for (i in sheet2Data){
    var row = 2;
      for (j in sheet1Data){
        if (sheet1Data[j][0]==sheet2Data[i][0]){
           sheetList1.getRange("A"+row).setValue('Inactive');           
        }
        row++;
      }


   }

}

关于优化此脚本的任何建议。或者如何处理这个错误? 在此先感谢:)

编辑

感谢您的精彩回复。有一个问题。如果我在if 语句之前将数据推送到newSheet1Data 数组中,那么它会写入Inactive 两次。即如果有两行,它将inactive 写入四行。喜欢

newSheet1Data.push(sheet1Data[j]); 
        if (sheet1Data[j][2]==sheet2Data[i][0]){
          newSheet1Data[j][0]='Inactive';
        }

如果我在if 语句中推送数据并且没有发生匹配,则它找不到行并给出此错误TypeError: Cannot set property "0.0" of undefined to "Inactive"。喜欢

if (sheet1Data[j][0]==sheet2Data[i][0]){
           newSheet1Data.push(sheet1Data[j]);
           newSheet1Data[j][0]='Inactive';           
        }

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:

    您应该避免在循环中对电子表格 API 进行任何调用,尤其是当其中包含大量数据时。

    我们的想法是只使用数组并在完成后将结果写回。 下面的代码执行此操作(基于您的代码,如果 col C sheet1 中的数据与 sheet2 col A 中的数据相同,则在 sheet1 col A 中写入一个字符串)。 我希望我没有犯错,但我没有机会测试我的代码......它可能需要一些调试;-)

    function compare() {
      var ss=SpreadsheetApp.getActiveSpreadsheet();
      var sheetList1=ss.getSheetByName("Sheet1");
      var sheetList2=ss.getSheetByName("Sheet2");
      var sheet1Data=sheetList1.getDataRange().getValues();// get the whole sheet in an array
      var sheet2Data=sheetList2.getRange(1,1,sheetList2.getLastRow(),1).getValues();
      var newSheet1Data = [] ; // create a new array to collect data
       for (i=0;i<sheet1Data.length;++i){
          for (j=0;j<sheet2Data.length;++j){
          if(i!=j){continue};
            newSheet1Data.push(sheet1Data[i]); // add the full row to target array
            if (sheet1Data[i][2]==sheet2Data[j][0]){
              newSheet1Data[i][0]='Inactive';//if condition is true change column A
              break
            }
          }
       }
      newSheet1Data.shift();// remove first row (probably headers ?)
      sheetList1.getRange(2,1,newSheet1Data.length,newSheet1Data[0].length).setValues(newSheet1Data);  // write back to sheet1 in one batch
    } 
    

    编辑:看到你的文档后,我更准确地理解了你想要什么...... 这是新代码(在您的 SS 上测试)

    function compare() {
      var ss=SpreadsheetApp.getActiveSpreadsheet();
      var sheetList1=ss.getSheetByName("Sheet1");
      var sheetList2=ss.getSheetByName("Sheet2");
      var sheet1Data=sheetList1.getDataRange().getValues();// get the whole sheet in an array
      var sheet2Data=sheetList2.getRange(1,1,sheetList2.getLastRow(),1).getValues();
      var newSheet1Data = [] ; // create a new array to collect data
      for (i=0;i<sheet1Data.length;++i){
        newSheet1Data.push(sheet1Data[i]); // add the full row to target array
           for (j=0;j<sheet2Data.length;++j){
             if (sheet1Data[i][2]==sheet2Data[j][0]){
              newSheet1Data[i][0]='Inactive';//if condition is true change column A
              break;// don't continue after condition was true, this will speed up the process
            }
          }
       }
      newSheet1Data.shift();// remove first row (probably headers ?)
      sheetList1.getRange(2,1,newSheet1Data.length,newSheet1Data[0].length).setValues(newSheet1Data);  // write back to sheet1 in one batch
    } 
    

    【讨论】:

    • 对不起,我在代码中打错了,最后一行 od 代码:当然必须使用 sheetName 才能使用 .getRange(),我更新了答案。
    • 我终于测试了,这个版本按预期工作,循环不适合这个逻辑。
    • 你确定吗?数据只推送一次......如果你得到 2 行的副本,我真的不知道为什么。你能分享一份你的电子表格的副本,看看会发生什么,或者至少有一个数据样本可以评估吗?我的测试运行良好。顺便说一句,更改推送位置后出现的错误是正常的,此时您尝试写入的行不存在。它必须是第一位的。
    • 另外:我在代码中添加了一行来加快速度(更多一点!)看休息; + 评论
    • 它仍然需要 5 分钟的时间。如果数据变得更少,我猜脚本将再次停止工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    相关资源
    最近更新 更多