Google apps script getNamedRanges()上的Google工作表脚本服务器错误

Google apps script getNamedRanges()上的Google工作表脚本服务器错误,google-apps-script,google-sheets,server-error,Google Apps Script,Google Sheets,Server Error,在为Google Sheets编写Google Apps脚本以删除通过删除引用的目标而孤立的命名范围时,发生了意外的“服务器错误”。有人能告诉我怎么避免吗 编辑:请注意,除了解决所附的演示脚本外,每次调用例程SpreadsheetApp.getNamedRanges()时,我都会寻找一个通用的解决方案。我将部署一个命令,从任何Google电子表格中删除孤立的范围名称。它将是dlbTools中NamedRanges例程的一部分,dlbTools已经在Google插件商店中提供 我写了一个谷歌电子表

在为Google Sheets编写Google Apps脚本以删除通过删除引用的目标而孤立的命名范围时,发生了意外的“服务器错误”。有人能告诉我怎么避免吗

编辑:请注意,除了解决所附的演示脚本外,每次调用例程SpreadsheetApp.getNamedRanges()时,我都会寻找一个通用的解决方案。我将部署一个命令,从任何Google电子表格中删除孤立的范围名称。它将是dlbTools中NamedRanges例程的一部分,dlbTools已经在Google插件商店中提供

我写了一个谷歌电子表格来演示它,产生了这样一个信息: -“很抱歉,发生服务器错误。请稍等,然后重试。(第8行,文件“代码”)。”。 此电子表格可在以下网站公开获取:

出现以下错误:

  • 调用方法SpreadsheetApp.getNamedRanges()时
  • 仅在删除已使用完整行样式引用在命名范围中引用的行之后
  • 仅当命名范围引用类似于“1:1”而不是“A1:B1”时
  • 仅在被引用行被删除后,导致命名范围引用“#REF!”
使用Google电子表格演示此意外服务器错误的步骤包括:

  • 选择菜单项“工具>脚本编辑器…”
  • 切换到“查找孤立脚本”选项卡
  • 选择菜单项Run>findOrphans
  • 观察红色条上的内容:“很抱歉,发生了服务器错误。请稍等,然后重试。(第8行,文件“代码”)”
  • 选择菜单项“查看>日志”
  • 选择菜单项“查看>执行记录”
以下是演示服务器错误的测试脚本: 函数findOrphans(){

//Helper函数记录命名的范围名称和引用。
var logNamedRanges=函数(场景){
Logger.log('记录场景的命名范围:'+场景);
log('在调用getNamedRanges()之前的logNamedRanges()中');
var namedRanges=ss.getNamedRanges();
Logger.log('在调用getNamedRanges()之后的logNamedRanges()中');
var names=namedRanges.map(函数(nr){return nr.getName()+'-->'+nr.getRange().getA1Notation();});
Logger.log('\n'+names.join('\n'));
} 
//Helper函数将命名范围更改为整行引用。
//也就是说,“A1:B1”变为“1:1”。
var changeRangeReferencesToFullRow=函数(){
Logger.log('在调用getNamedRanges()之前的changeRangeReferencesToFullRow()中');
var namedRanges=shtTest.getNamedRanges();
Logger.log('在调用getNamedRanges()之后的changeRangeReferencesToFullRow()中');
对于(变量i=0;i
使用API进行测试 @Tanaike关于使用Sheets API的建议很有帮助,因为它成功地检索了电子表格应用程序调用失败的命名范围列表。不幸的是,它不包括那些最感兴趣的孤儿


演示电子表格现在包括一个名为
trySheetsAPI.gs
的附加脚本文件。顶部的注释告诉我们如何识别测试Sheets API的附加代码。虽然我很感激这个有用且有趣的建议,但它仍然不允许我编写一个通用的孤立删除例程。

这个考虑如何?我不知道这是不是最好的。对不起

修改点: 发现更新namedrange时会发生错误。脚本的流程如下所示

row1Name #REF
row2Name 'Copy of Static'!A2:Z2
row1Name 'Copy of Static'!1:1
row2Name 'Copy of Static'!2:2
row1Name #REF
row2Name 'Copy of Static'!2:2
运行
setupTestSheet()
时,NamedRange由
ss.setNamedRange('row1Name',shtTest.getRange('1:1'))
ss.setNamedRange('row2Name',shtTest.getRange('2:2'))定义,如下所示。使用工作表API检索以下值

{
  "namedRanges": [
    {
      "namedRangeId": "#####",
      "name": "row1Name",
      "range": {
        "endColumnIndex": 26,
        "startRowIndex": 0,
        "endRowIndex": 1,
        "sheetId": #####,
        "startColumnIndex": 0
      }
    },
    {
      "namedRangeId": "#####",
      "name": "row2Name",
      "range": {
        "endColumnIndex": 26,
        "startRowIndex": 1,
        "endRowIndex": 2,
        "sheetId": #####,
        "startColumnIndex": 0
      }
    }
  ]
}
在这个时候
{
  "namedRanges": [
    {
      "namedRangeId": "#####",
      "name": "row1Name",
      "range": {
        "startRowIndex": 0,
        "endRowIndex": 1,
        "sheetId": #####
      }
    },
    {
      "namedRangeId": "#####",
      "name": "row2Name",
      "range": {
        "startRowIndex": 1,
        "endRowIndex": 2,
        "sheetId": #####
      }
    }
  ]
}
row1Name 'Copy of Static'!1:1
row2Name 'Copy of Static'!2:2
row1Name #REF
row2Name 'Copy of Static'!2:2
function doTest (whichPass) {
  Logger.log('\n\nStarting test using ' + whichPass + '\n\n');
  setupTestSheet();

  var r = shtTest.getNamedRanges(); // <--- Added

  if (whichPass.slice(0,3) == '1:1') {
  // next line is only difference between the passes
    changeRangeReferencesToFullRow();
  }
  logNamedRanges('Before row delete')

  var dummy = [i.remove() for each (i in r) if (i.getName() == "row1Name")]; // <--- Added

  shtTest.deleteRow(1);
  if (whichPass.slice(-5) == 'error') {
  // next line stops test before error occurs
    Logger.log('Halted test to avoid error');
    return;
  }
  logNamedRanges('After row delete')
  Logger.log('Finished test using ' + whichPass );
}
var ss = SpreadsheetApp.getActiveSpreadsheet();
var r = Sheets.Spreadsheets.get(ss.getId(), {fields: "namedRanges(name,namedRangeId)"});
Sheets.Spreadsheets.batchUpdate(
  {"requests": [{
      "deleteNamedRange": {
        "namedRangeId": [i.namedRangeId for each (i in r.namedRanges) if (i.name == "### name ###")][0]
  }}]},
  ss.getId()
);