如何解决“服务在短时间内被调用太多次:exec qps。”

时间:2019-09-06 13:52:49

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

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

  • 校长用来输入信息的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的问题。在如此大的项目中,是否有解决方案?学校系统可以升级到某些东西,以使错误消失吗?

1 个答案:

答案 0 :(得分:1)

在您的sleep循环中放置一个for方法不会停止配额错误,因为该循环未使用任何服务。

服务是:

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?

}