循环通过两个单元格来查找匹配,然后在匹配时复制范围

时间:2014-08-30 15:02:15

标签: google-apps-script google-sheets

我试图编写一个谷歌应用程序sctipt,循环到日期范围以查找匹配项,并且对于它找到的每个匹配项,它都会复制指定范围的"费用"进入指定范围。当我运行脚本时,它会执行,但没有任何反应。它超过了执行时间限制,所以我认为它会陷入循环中。

更新:如果有人想查看所涉及数据的示例,我已经创建了测试工作表:https://docs.google.com/spreadsheets/d/1J9L5b3UMCJGZV8QiUu9RyVrmaDVaK7FroLN8aDLYwxs/edit?usp=sharing

这是我的代码:

function menuItem1() {
 var sheet = SpreadsheetApp.getActiveSheet();

  //Updating Expenses 2
  for(row = 10; row <= 61; row++){
    var date1 = sheet.getRange(row, 3, 1);
    var date1value = date1.getValue();

    for(row2 = 22; row2 < 59; row++){
      var date2 = sheet.getRange(row2, 18, 1);
      var date2value = date2.getValue();


      if(date1value == date2value){
        sheet.getRange(row2, 19, 2, 8).copyTo(sheet.getRange(row1, 5, 8), {contentsOnly:true});
      }
    }

如果有人可以帮助解决问题是什么,我们将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:1)

您应该阅读有关best practice in spreadsheets的文档,以尝试加快您的代码。

下面是对代码的严格翻译,这些代码将在不到一秒的时间内执行,同时执行完全相同的操作。一旦你摆脱了超时问题,我希望你能够做到你想要的。

当然,我没有测试您脚本的最终目标,因为我对您的数据一无所知。

一些变量是日期,在这种情况下,您应该特别注意它,看看日期是否最终具有您在工作表中看不到的相关时间值,并处理它。

代码:

function menuItem1() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var data = sheet.getDataRange().getValues();// get all values in your sheet up to the last row and last column (where data exist)
  // define limits in array (values = row values-1)
  var r1start = 9;
  var r1max = 60;
  var r2start = 21;
  var r2max = 58;
  // choose columns
  var col1 = 2; 
  var col2 = 17;
  for(var r1=r1start ;  r1<r1max ; r1++){
    for(var r2=r2start ;  r2<r2max ; r2++){
      if(data[r1][col1] == data[r2][col2]){
        sheet.getRange(r2+1, 19, 2, 8).copyTo(sheet.getRange(r1+1, 5, 8), {contentsOnly:true});
        Logger.log('match found');
      }
    }
  }
}

编辑:

上面的代码正在运行,但它没有考虑所有空单元格,因此它在空单元格上找到了大量匹配。日期对象的比较不正常,这就是为什么我切换到原生日期值(毫秒)... 由于它仅复制值,我们没有看到数据更改,因此它在整个目标范围内写入空值!

现在使用示例表更容易实现: - ),下面的新工作代码。

function menuItem1() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var data = sheet.getDataRange().getValues();// get all values in your sheet up to the last row and last column (where data exist)

  // define limits in array (values = row values-1)
  var r1start = 9;
  var r1max = 60;
  var r2start = 21;
  var r2max = 58;

  // choose columns
  var col1 = 2; 
  var col2 = 17;

  for(var r1=r1start ;  r1<r1max ; r1++){
    for(var r2=r2start ;  r2<r2max ; r2++){
      if(data[r1][col1]=='' || data[r2][col2]==''){continue}; // skip all empty rows to avoid false equalities in empty cells and speed up the process
      Logger.log(data[r1][col1]+'  = ?  '+data[r2][col2]);// this is only to view data in the logger
      if(data[r1][col1].getTime() == data[r2][col2].getTime() ){ // compare on date native values
        sheet.getRange(r2+1, 19, 2, 8).copyTo(sheet.getRange(r1+1, 5, 8), {contentsOnly:true});
        Logger.log('match found'); 
      }
    }
  }
}