Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google apps script 删除GAS中无效的命名范围_Google Apps Script_Google Sheets - Fatal编程技术网

Google apps script 删除GAS中无效的命名范围

Google apps script 删除GAS中无效的命名范围,google-apps-script,google-sheets,Google Apps Script,Google Sheets,我在一张工作表中定义了一些命名范围,稍后将其删除。之后,范围保留在侧栏“数据->命名范围…”中,范围为“#REF”。我想删除它们,因为我不希望它们累积 它们未列在SpreadsheetApp.GetActiveSpreadsheet.getNamedRanges()中 如何以编程方式删除它们 另一种解决方案是如何定义在删除图纸时删除的命名范围。如果在重复的工作表中有一个命名范围,则会发生这种情况-命名范围的名称类似于“'Sheet1Copy'!RangeName”,但无法定义这样的名称。使用re

我在一张工作表中定义了一些命名范围,稍后将其删除。之后,范围保留在侧栏“数据->命名范围…”中,范围为“#REF”。我想删除它们,因为我不希望它们累积

它们未列在
SpreadsheetApp.GetActiveSpreadsheet.getNamedRanges()

如何以编程方式删除它们

另一种解决方案是如何定义在删除图纸时删除的命名范围。如果在重复的工作表中有一个命名范围,则会发生这种情况-命名范围的名称类似于“'Sheet1Copy'!RangeName”,但无法定义这样的名称。

使用
removeNamedRange(name)
删除命名范围。它甚至可以与具有#REF!
SpreadsheetApp.getActiveSpreadsheet().getNamedRanges()未返回范围和

为了更方便地维护电子表格,请使用#REF!作为范围,保留命名范围的列表。您可以使用辅助电子表格进行此操作。

更新如下 如果要删除唯一的命名范围,则接受的答案可以正常工作,但如果有多个范围共享相同的名称(即,工作表范围的命名范围与电子表格范围的命名范围),则接受的答案无效

命名范围的第一个实例的范围可能是整个电子表格,而工作表的任何副本(包含原始命名范围)将具有范围为复制工作表的命名范围(例如
'SheetCopy'!NamedRange
而不是
NamedRange

如果要删除引用不再有效的工作表范围命名范围,请尝试从脚本编辑器中运行以下脚本:

function removeDeadReferences()
{
  var activeSS = SpreadsheetApp.getActiveSpreadsheet();
  
  var sheets = activeSS.getSheets();
  
  var sheetNamedRanges, loopRangeA1Notation;
  
  var x, i;
  // minimum sheet count is 1, no need to check for empty array, but why not
  if (sheets.length)
  {
    for (x in sheets)
    {
      sheetNamedRanges = sheets[x].getNamedRanges();
      // check for empty array
      if (sheetNamedRanges.length)
      {
        for (i = 0; i < sheetNamedRanges.length; i++)
        { // get A1 notation of referenced cells for testing purposes
          loopRangeA1Notation = sheetNamedRanges[i].getRange().getA1Notation();
          // check for length to prevent throwing errors during tests
          if (loopRangeA1Notation.length)
          { // check for bad reference
            // note: not sure why the trailing "!" mark is currently omitted
            // ....: so there are added tests to ensure future compatibility
            if (
              loopRangeA1Notation.slice(0,1) === "#"
              || loopRangeA1Notation.slice(-1) === "!"
            || loopRangeA1Notation.indexOf("REF") > -1
            )
            {
              sheetNamedRanges[i].remove();
            }
          }
        }
      }
    }
  }
}

命令拼写错误。正确的拼写是:
SpreadsheetApp.getActiveSpreadsheet().getNamedRanges()
谢谢。我认为,这不是
getNamedRanges()函数的正常行为。它不会显示带有“#REF”的范围,但它们会出现在命名范围列表中,这非常烦人。是否存在解决此问题的未决问题?@MaxMakhrov:我还没有找到有关此问题的具体问题。是否可以使其适用于范围为工作表而不是电子表格的命名范围?@Todd您是否已经尝试过使用工作表范围的命名范围?只要我调用
.getNamedRanges()
最近,在包含错误引用的工作表或电子表格上,它会抛出错误。就在几周前,我能够调用该函数,循环并测试特定名称,并通过
.setRange()
函数重置范围。今天试过同样的剧本,不行。谷歌似乎不喜欢命名范围。这看起来更像是一个问题而不是答案。不管怎么说,你已经看过script.google.com上的失败报告了吗?我在这里读的比我的贡献还多,所以如果我没有正确回答,我很抱歉。OP提到了“范围”,并询问如何以编程方式删除“范围”,我觉得可以提供更多内容来实现既定目标。(…)没有Stackdriver日志,编辑器中给出的错误是非常无用的,“很抱歉,发生了服务器错误。请稍等,然后重试。(第90行,文件“维护”)”。我可能遗漏了什么,但这对我来说好像没有答案。我认为你的帖子应该被拆分。请在此保留您对替代方法的贡献,如果您愿意,请发布一个关于您的问题的新问题,因为它似乎不会发生在OP上。@Rubén,我已更新了答案以提供更多上下文。机管局并没有真正解决OP问题的后半部分,这似乎要求更像“维护程序”的东西。OP听起来好像要删除任何无效引用,不一定是运行时已知的引用。@Todd,这正是我要找的脚本!但是,我得到的
TypeError:sheet.getName不是removeDeadReferences(removeDeadReferences:18:23)中的函数
function removeDeadReferences()
{
  var activeSS = SpreadsheetApp.getActiveSpreadsheet();
  
  var sheets = activeSS.getSheets();
  var sheet;
  var sheetName;
  
  var sheetNamedRanges, sheetNamedRange, sheetNamedRangeName;
  var loopRange, loopRangeA1Notation;
  
  var x, i;
  // minimum sheet count is 1, no need to check for empty array
  for (x in sheets)
  {
    sheet = sheets[x];
    // for logging
    sheetName = sheet.getName();

    sheetNamedRanges = sheet.getNamedRanges();
    // check for empty array
    if (sheetNamedRanges.length)
    {
      for (i = 0; i < sheetNamedRanges.length; i++)
      {
        sheetNamedRange = sheetNamedRanges[i];
        // for logging
        sheetNamedRangeName = sheetNamedRange.getName();

        // v8 engine won't allow you to get range if it is invalid
        try {
          loopRange = sheetNamedRange.getRange();
        }
        catch (error)
        {
          Logger.log(error);

          loopRange = null;
        }
        // get A1 notation of referenced cells for testing purposes
        loopRangeA1Notation = (
          loopRange != null
          ? loopRange.getA1Notation()
          : false
        );
        // check for bad reference
        // added tests to ensure future compatibility
        // but any of these should suffice
        // comment out ones you don't want to test for
        if (
          loopRangeA1Notation == false
          || loopRangeA1Notation.slice(0,1) === "#"
          || loopRangeA1Notation.slice(-1) === "!"
          || loopRangeA1Notation.indexOf("REF") > -1
          )
        {
          Logger.log("The named range, '" + sheetNamedRangeName + "', within the Sheet named, '" + sheetName + "', was removed.");
          sheetNamedRange.remove();
        }
      }
    }
  }
}