【问题标题】:Which function is a faster alternative to FOR? Google Apps Script - Google Sheets哪个函数比 FOR 更快? Google Apps 脚本 - Google 表格
【发布时间】:2021-06-19 11:53:59
【问题描述】:

我有一个代码:

function check(){
  var sh = SpreadsheetApp.getActive();
  var sheet = sh.getSheetByName("1")
  var getNames = sheet.getRange("A:A").getValues().filter(String).toString().split(",");
    for (var j = 0; j < getNames.length; j++) {
      var sheetnow = sh.getSheetByName(getNames[j]);
      var last = sh.getSheetByName(getNames[j]).getLastRow();
      for (var i = 1 ; i <= last ; i++ ) {
        var rangeactive = sheetnow.getRange(i ,7).getValue();
        var setval = sheetnow.getRange(i ,8);
          if (rangeactive == 1 && setval.getValue() == "") {
              setval.setValue("OK");
          }   
      }
    }
}

它仍然可以正常工作,但 For 会非常慢,因为所有工作表都有超过 200000 行并且运行时间超过 6 分钟。还有其他更有效的方法吗?谢谢

https://docs.google.com/spreadsheets/d/13p4xrIfACk_l_oRgBnDr8VaOtEL9o4SxeIql5eqryOc/edit#gid=1480346296

【问题讨论】:

  • 使用 getValues() 和 setValues() 比使用多个 getValue() 或 setValue() 调用更快。

标签: google-apps-script google-sheets


【解决方案1】:

试试这个:

function check(){
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName("1")
  const names = sh.getRange(1,1,sh.getLastRow()).getValues().flat();
  names.forEach(n => {
    let s = ss.getSheetByName(n);
    let vs = s.getRange(1,7,s.getLastRow(),2).getValues();
    let sv = s.getRange(1,8,sh.getlastRow()).getValues();
    vs.forEach((r,i) => {
      if(r[0] == 1 && r[1] == '') {
        sv[i][0] = "OK";
      }
    });
    s.getRange(1,8,sv.length,sv[0].length).setValues(sv);
  });  
}

【讨论】:

  • 感谢@Cooper,确实更快。但最后它给出了一个错误并且没有结束脚本,这是为什么呢? TypeError: Cannot read property 'getRange' of null 第 5,7 行
  • 我不知道我没有你的数据,所以我无法真正调试它。
  • 对不起,我不关注非现场资源的链接。如果它不在问题中,那么我不使用它。我能做的最好的就是给你一个更快的方法,让你调试它。
  • 对不起,我刚刚将它添加到问题部分。
  • 是的,但我仍然不关注非现场资源的链接..