Google Apps 脚本 setValues() 问题:间歇性超时

Google Apps script setValues() issue: timing out intermittently

我有一个 Google Apps 脚本 运行4 年来一直没有问题。但是,自 3 周以来我遇到了这个问题:脚本 运行ning 很长一段时间并且失败了。每 10 运行 秒中每 3 次就会发生这种情况。错误信息是“Service Spreadsheets timed out while accessing spreadsheet with id [spreadsheet id here]”.

实际的脚本,它是精心制作的(数千行)并且 运行s 在数百个 spreadsheets 上使用 fetchUrl() 获取数据并填充 sheet 与 setValues()。在过去的 4 年里,这个实际的脚本过去在 spreadsheets 和 10 sheets 上运行良好,并且可以更新每个 sheet 中的 180k 个单元而没有问题。现在,我连一个都更新不了 sheet.

下面的脚本重现了这个问题:它使用 .getValues().setValues() 将 1300 行 x 140 列从 Sheet1 复制到 Sheet2。当行数增加到 800 以上时,脚本开始失败. 当它 运行 没问题时,执行日志显示它需要 8 秒。当它失败时,日志显示 运行 次,最多 900 秒。在此期间,您有超过 10 分钟无法访问传播sheet,如果您尝试在不同的选项卡中加载传播sheet,它根本不会加载。

我已经打开了 Google 支持的问题,我没有时间表,但对于给您带来的不便深表歉意。这发生在我尝试过脚本的所有域上,而不仅仅是我的域。您需要尝试 运行 脚本 10 次才能看到失败。

如果有人可以提出解决方法或提供有关此问题的一些见解,我将不胜感激。

这是复制问题的 link 传播 sheet:https://docs.google.com/spreadsheets/d/1jea15rtjv85YIZumABMfFKESb2_QmX0-7zC-KchWeDc/edit?usp=sharing

function myFunction() {
  var row1 = 1;
  var col1 = 1;
  var row2 = 1300;
  var col2 = 140;
  console.log({numrows:row2, numcols:col2} );
  var rng = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange(row1,col1,row2,col2);
  var values_to_set = rng.getValues();
  var rng2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getRange(row1,col1,row2,col2);
  rng2.setValues(values_to_set);
  console.log('done');
  
}

这个问题是already reported to Google in Issuetracker。为问题添加一个星标(在左上角)以请求 Google 开发人员优先处理该问题并修复它。


与此同时,考虑使用 的高级 Google 服务对电子表格进行大量操作。


问题似乎源于 set* 方法。在您的具体情况下,另一种选择是使用 range.copyTo(而不是 getValues()setValues()),它可以正常工作(最多测试 15 次)

/**@OnlyCurrentDoc*/
function myFunction() {
  var row1 = 1;
  var col1 = 1;
  var row2 = 1300;
  var col2 = 140;
  console.log({numrows:row2, numcols:col2} );
  var rng = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange(row1,col1,row2,col2);
  /*var values_to_set = rng.getValues();*/
  var rng2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getRange(row1,col1,row2,col2);
  /*rng2.setValues(values_to_set);*/
  /*Added*/rng.copyTo(rng2, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false)
  console.log('done');
}


function test_myFunction(i=15){
  while(i--){
    myFunction();
  }
}

据此comparison of read/write methods, using advanced services写比setValues()快。

使用原始代码段的以下修改版本适用于您的示例电子表格:

function myFunction() {
  var row1 = 1;
  var col1 = 1;
  var row2 = 1300;
  var col2 = 140;
  Logger.log({numrows:row2, numcols:col2} );
  var rng = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange(row1,col1,row2,col2);
  var values_to_set = rng.getValues();
  var rng2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2").getRange(row1,col1,row2,col2);
  //rng2.setValues(values_to_set);
  // Based on https://developers.google.com/apps-script/advanced/sheets
  var request = {
    'valueInputOption': 'USER_ENTERED',
    'data': [
      {
        'range': 'Sheet2!' + rng2.getA1Notation(),
        'majorDimension': 'ROWS',
        'values': values_to_set
      }
    ]
  };
  Sheets.Spreadsheets.Values.batchUpdate(request, SpreadsheetApp.getActiveSpreadsheet().getId());
  Logger.log('done');
}

google v8 引擎似乎有问题。我最近遇到了同样的问题。禁用 v8 引擎后,它现在工作正常。

转到工具->脚本编辑器。 在脚本编辑器 window 中,单击 运行 然后禁用 v8 引擎。见附件。

我在将十几条记录插入到具有 15 万行的 sheet 中时遇到了同样的问题。它会读取第一个文件,插入,然后在第二个或第三个文件上失败。我在这个 sheet 中有几个选项卡做一些非常复杂的嵌套查询和 arrayformula vlookups 并设置了 sheet 设置以每分钟和更改时更新。
我解决问题的解决方案是用复杂查询复制我的原始 sheet,并用 importRange 替换源数据选项卡(从原始数据 sheet 中提取数据)。然后,我从原始数据 sheet 中删除了所有其他选项卡。将原始数据 sheet 与动态计算隔离开来。 简短回答:删除包含复杂查询、数组公式和 vlookup 的选项卡 sheet.

问题不是代码本身,而是 运行 的帐户类型。

我有两个价差sheets,属于我的个人账户 p................@gmail.com。 为这 2 sheets 编写的交互脚本非常简单,包括从 sheet 1(大约 150000 个单元格)获取范围和值并在 sheet 2 上设置值. 现在,如果我尝试使用我的个人帐户 运行 脚本,我会收到“服务传播 sheet 在访问具有 id ... 的文档时超时”错误。错误显示在大约 140 秒时。

在工作中,我获得了一个公司付费帐户,使用我的工作电子邮件,p.....@c..mi.com。我与此帐户共享 sheets 1 和 2,并具有编辑权限。 当我 运行 这个相同的脚本,使用这个工作付费帐户时,错误永远不会出现,并且脚本在大约 50 秒后成功完成。