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