You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

protection.removeEditors执行报错:Spreadsheets服务超时问题求助

问题描述

我编写的lockrow定时函数(每小时执行一次)在首次循环输出Logger.log(3)后立即失败,报错信息为:Exception: Service Spreadsheets timed out while accessing document with id .....。该问题3年前已在Google IssueTracker(编号148894990)上报并标记为已修复,但目前仍存在,函数每日因该错误失败25次。

原代码

function lockrow(){ 
  // timer to run every hour
  var ss = SpreadsheetApp.getActiveSpreadsheet();  
  var gpsht = ss.getSheetByName("GatePass");  
  var gplr=gpsht.getLastRow();
  var locks = gpsht.getRange("W:X").getValues();
  for (i=gplr-1 ; i > 1 ; i--){//
    if (locks[i][1]==1) { //printed
      if (locks[i][0]=="") { //not locked
        Logger.log("Locking row - " + (i+1));
        var range = gpsht.getRange('A'+(i+1)+':Q'+(i+1)).activate();
        Logger.log(2)
        var protection = range.protect().setDescription('Locked');
        Logger.log(3)
        protection.removeEditors(protection.getEditors());
        Logger.log(4)
        Logger.log("Success")
        gpsht.getRange("W"+(i+1)).setValue(1);
        Logger.log(5)
        SpreadsheetApp.flush();
        Utilities.sleep(3000) ;
      }
     }//if
  }//for
}//function

修复方案

针对这个超时问题,可通过优化代码减少Spreadsheet服务的调用频次和负载,同时添加容错机制:

  • 移除无意义的UI操作:删掉range.activate(),该操作仅用于界面选中,对脚本逻辑无作用,反而增加服务交互开销。
  • 批量收集待处理行:先遍历所有行,把需要锁定的行号和要更新的值一次性收集,避免循环内频繁触发服务调用。
  • 添加重试机制:对容易超时的保护操作增加重试逻辑,遇到超时错误时等待后重试1-2次,避免直接终止函数。
  • 批量更新单元格:把W列的更新操作合并为一次setValues()调用,减少API请求次数。

优化后的示例代码:

function lockrow() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var gpsht = ss.getSheetByName("GatePass");
  var gplr = gpsht.getLastRow();
  // 仅读取有数据的范围,避免处理大量空行
  var locks = gpsht.getRange("W2:X" + gplr).getValues();
  var rowsToLock = [];
  var wColumnUpdates = [];

  // 第一步:批量收集需要处理的行和更新值
  for (var i = 0; i < locks.length; i++) {
    var rowNum = i + 2; // 对应工作表的实际行号
    if (locks[i][1] === 1 && locks[i][0] === "") {
      rowsToLock.push(rowNum);
      wColumnUpdates.push([1]); // 标记为已锁定
    } else {
      wColumnUpdates.push([locks[i][0]]); // 保持原有值
    }
  }

  // 第二步:批量处理行保护,带重试机制
  rowsToLock.forEach(function(row) {
    var range = gpsht.getRange('A' + row + ':Q' + row);
    var success = false;
    // 最多重试2次
    for (var retry = 0; retry < 2; retry++) {
      try {
        var protection = range.protect().setDescription('Locked');
        protection.removeEditors(protection.getEditors());
        Logger.log("成功锁定行 - " + row);
        success = true;
        break;
      } catch (e) {
        if (retry === 1) {
          Logger.log("锁定行" + row + "失败:" + e.toString());
        }
        Utilities.sleep(1000); // 重试前等待1秒
      }
    }
  });

  // 第三步:批量更新W列数据
  gpsht.getRange("W2:W" + gplr).setValues(wColumnUpdates);
  SpreadsheetApp.flush();
}

内容的提问来源于stack exchange,提问作者arul selvan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:25:21