【问题标题】:How to fix "Service invoked too many times in a short time: exec qps."如何解决“在短时间内调用太多次服务:exec qps。”
【发布时间】:2019-09-06 13:52:49
【问题描述】:

我有一个相当大的学校设置来记录会议时间和链接到单独工作表的学生信息。

  • 10 校长用于输入信息的学校电子表格,包括指向每个学生个人日历的超链接,并查看从日历返回的出勤统计数据。
  • 43 个导师电子表格,可根据导师姓名从学校电子表格中提取学生数据。
  • ~109 个学生日历电子表格,包含 9 个标签,为期 9 个月。用于输入导师出勤信息。

使所有内容都链接的大部分内容是一个自定义函数,它从超链接函数中提取 URL。我找到了代码herehere。该函数在学校电子表格中用作每个学生的唯一标识符。

我曾尝试在 Utilities.sleep 中添加各种数量(包括 3000),但错误最终会返回(再次偶尔出现)。看来这可能是基于每日配额限制服务的问题,但我没有看到专门解决 exec qps。

/** 
 * Returns the URL of a hyperlinked cell, if it's entered with hyperlink command. 
 * Supports ranges
 * @param {A1}  reference Cell reference
 * @customfunction
 */
function linkURL(reference) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var formula = SpreadsheetApp.getActiveRange().getFormula();
  var args = formula.match(/=\w+\((.*)\)/i);
  try {
    var range = sheet.getRange(args[1]);
  }
  catch(e) {
    throw new Error(args[1] + ' is not a valid range');
  }
  var formulas = range.getFormulas();
  var output = [];
  for (var i = 0; i < formulas.length; i++) {
    var row = [];
    for (var j = 0; j < formulas[0].length; j++) {
      var url = formulas[i][j].match(/=hyperlink\("([^"]+)"/i);
      row.push(url ? url[1] : '');
    }
    output.push(row);
    Utilities.sleep(2000);
  }
  return output
}

我遇到的一个错误是“TypeError:无法从 null 读取属性“1”。 (第 16 行,文件“代码”)',这似乎不一定会影响函数执行。我很想知道为什么会发生这个错误。

但是,我确实通过不同的学校电子表格偶尔收到错误,上面写着“服务在短时间内调用了太多次:exec qps。在调用之间尝试 Utilities.sleep(1000)。(第 0 行)。”这会在整个电子表格中显示 #Error 并导致信息不显示。

这似乎是服务受到每日配额限制的问题,但我没有看到专门解决 exec qps。在这么大的项目中是否有解决此问题的方法?学校系统是否可以升级到可以使错误消失的东西?

【问题讨论】:

  • 在循环中我只看到 .match.push 被调用,这是正常的 javascript 函数,我不相信它们有速率限制。
  • 第 16 行是哪一行?
  • @barbsan 在上面的脚本中是throw new Error(args[1] + ' is not a valid range');
  • 移除Utilities.sleep并批量调用函数:=linkURL(A1:A10)

标签: javascript google-apps-script google-sheets custom-function


【解决方案1】:

for 循环中放置sleep 方法不会阻止配额错误,因为该循环没有使用任何服务。

服务是:

sheet = SpreadsheetApp.getActiveSheet();
formula = SpreadsheetApp.getActiveRange().getFormula();

服务应放入for 循环,如下所示:

/** 
 * Returns the URL of a hyperlinked cell, if it's entered with hyperlink command. 
 * Supports ranges
 * @param {A1}  reference Cell reference
 * @customfunction
 */
function linkURL(reference) {
  var formula,i,sheet;

  for (i=1;i<4;i++) {//Retry up to 3 times - must begin at 1 for sleep calculation
    try{
      sheet = SpreadsheetApp.getActiveSheet();
      formula = SpreadsheetApp.getActiveRange().getFormula();
      break;
    }catch(e){
      if (i!==3){Utilities.sleep(i*1500);}//Wait an increasingly longer time on each iteration
      if (i>=3) {
        errorHandling_(e);//Call central error handling
      }
    };

  }

  if (!sheet) {//If there is no sheet then there is no point in running more code
    //An error has already been handled above
    return;
  }

  var args = formula.match(/=\w+\((.*)\)/i);

  try {
    var range = sheet.getRange(args[1]);
  }catch(e) {
    errorHandling_(e);
  }

  if (!range) {//If there is no range then there is no point in running the code below -
    //An error message has already been handled above
    return;
  }

  var formulas = range.getFormulas();
  var output = [];

  for (var i = 0; i < formulas.length; i++) {
    var row = [];
    for (var j = 0; j < formulas[0].length; j++) {
      var url = formulas[i][j].match(/=hyperlink\("([^"]+)"/i);
      row.push(url ? url[1] : '');
    }
    output.push(row);

  }
  return output
}

function errorHandling_(e) {
  var errorMessage,stack;
  //Handle all errors in one central place

  errorMessage = e.message;
  stack = e.stack;

  //Email the user?


  //Email the developer?

}

【讨论】:

  • 这可能已经解决了问题。今天下午我会和一些工作人员一起做一些测试,如果我没有问题的话,把它标记为答案。谢谢!
  • 在有机会与工作人员进行测试之前,它又开始抛出错误。还有其他想法吗?
  • 再次查看可能的问题后,我注意到通过查看执行记录,我没有收到任何代码错误。我仍然收到#Error!在电子表格后的某些单元格中坐了一会儿。如果我再次进入并运行代码,它会重新加载链接 URL。有没有办法让它在一段时间后重新运行代码?我对此一无所知。
  • 执行脚本有助于确定代码是否失败,以及它在哪一行失败,但对于调试,最好在某处注销信息。并且您希望在出现问题时得到通知。执行记录不会通知您存在问题。您可以使用console.log('Error: ' + e + "stack: " + e.stack) 将错误和堆栈发送到堆栈驱动程序。然后从代码编辑器中,选择“查看”和“Stackdriver logging”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-22
  • 1970-01-01
相关资源
最近更新 更多