我在一个工作簿中有一个包含594个命名区域的列表,该工作簿有近20个工作表,每个工作表有大约200列数据。我需要找出命名区域的使用位置,以便删除不相关的区域。我将命名区域列表粘贴到工作表上,然后尝试通过记录它们来查找它们是否在公式中使用。然后在所有工作表和列中使用find方法。问题是,尽管使用了lookin xlformulations,它还是会检索命名的范围,即使它只是一个文本。
以下是我的(更新)尝试(如果还不明显,我是一个业余爱好者):
Application.ScreenUpdating = False
Count = ActiveWorkbook.Sheets.Count
Sheets(Count).Activate
Dim locr(1 To 595)
Dim locc(1 To 595)
Dim locn(1 To 595)
Dim nam(1 To 595)
Dim rng As Range
Range("a1").Select
For X = 1 To 595 'populate array with named ranges
ActiveCell.Offset(1, 0).Select
nam(X) = ActiveCell.Value
Next X
For i = 1 To 595 'name loop
For j = 1 To (Count - 1) 'sheet loop
Sheets(j).Activate
On Error Resume Next
Set orange = Sheets(j).Cells.SpecialCells(xlCellTypeFormulas) 'limit range to cells that only contain formulas
On Error GoTo 20 'if no formulas in sheet, go to next sheet
If Not orange Is Nothing Then
Set rng = orange.Find(What:=nam(i), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False) 'find named range
If Not rng Is Nothing Then 'if named range found
Application.Goto rng, True 'go to cell where name range found and record address
locr(i) = ActiveCell.Row
locc(i) = ActiveCell.Column
locn(i) = ActiveSheet.Name
GoTo 10 'value found, go to next sheet
Else
End If
Else
End If
20 Next j
locr(i) = "" 'record empty since "rng" is empty
locr(i) = ""
locr(i) = ""
10 Next i
Sheets(Count).Activate
Range("c1").Select
b = 1
For a = 1 To 595 'populate addresses of named ranges
ActiveCell.Offset(b, 2).Value = locr(a)
ActiveCell.Offset(b, 1).Value = locc(a)
ActiveCell.Offset(b, 0).Value = locn(a)
b = b + 1
Next a
4条答案
按热度按时间5uzkadbs1#
这是我能想到的一种方法,我将分两部分来解释。
第一部分
假设我们有一个命名范围
Sid
。这个单词
Sid
可以以任何一种形式出现,如下图所示。为什么它以=
开头?这在下面的Part2
中已经解释过了。任何其他的场景,我猜都是上述场景的子集,在我们的例子中,唯一有效的查找是第一个和最后一个,因为我们正在查找命名的范围。
所以这里有一个快速的函数来检查单元格公式是否有一个命名的范围。我相信它可以变得更有效
在第一种和最后一种情况下,
Debug.Print isNamedRangePresent(Range("D2"), "Sid")
会给予True
,请看这个第二部分
现在来看看
.Find
。我发现你在工作表中只搜索了一次。因为你可以有很多Sid
的场景,所以你不能只有一个.Find
。你必须使用.FindNext
。关于如何使用它,请参见THIS链接。我已经在那里解释过了,所以我不会在这里解释。**我们可以通过只搜索那些包含公式的单元格来提高
.Find
的效率。**为此,我们必须使用.SpecialCells(xlCellTypeFormulas)
。这解释了为什么我们在PART1
的示例中使用“=”。:)下面是一个示例(底部添加了PART1代码)
产出
呸!
xlpyo6sf2#
此代码使用这些名称创建工作簿的副本。然后,它将遍历并删除复制的工作簿中的名称列表中的每个名称。它将计算前后工作簿中的公式错误数。如果错误数相同,则不使用该名称。如果错误数不同,则使用该名称。
我喜欢在这种非常复杂的情况下做这种测试。这意味着你不必担心测试的复杂规则。你可以根据结果来回答问题。
由于测试都是在副本上完成的,所以应该是安全的。不过一定要在之前保存所有的工作!
要使用,请将您的名称列表放入工作簿中,并将该列表的范围命名为“NamesToTest”:
然后将以下代码放入同一工作簿中并运行:
结果将显示在调试窗口中:
这段代码很有希望是非常容易理解的。SpecialCells是值得了解的,所以如果有必要的话,请仔细阅读它。在本例中,它标识了有错误的单元格--这就是16参数。
请注意,这只检查工作簿级别的名称。如有必要,您可以添加工作表级别的检查。
3duebb1j3#
下面的代码对我来说是有效的。
1)可以使用
range.ShowDependents
方法绘制指向从属于该区域的单元格的箭头。完成后,使用range.ShowDependents True
删除箭头。2)一旦箭头被画出来,
range.NavigateArrow
就可以跟随这些箭头,并返回结果范围。我找不到任何文档说明如果没有依赖范围会发生什么。通过实验,我能够确定,如果没有依赖范围,它将返回原始范围。0tdrvxhp4#
下面的NamesInCells宏报告引用活动工作簿中每个已定义名称(命名区域)的公式单元格数。结果位于工作簿的NamesInCells工作表中从第1行开始的A:D列(Scope、Name、RefersTo、Cells)中。如果该工作表不存在,则将其添加到最后一张工作表之后。
对于每个可见的名称(未隐藏),宏将使用私有函数Formula_Errors来确定在名称的RefersTo属性无效之前和之后有多少公式单元格出错。前后的差值是公式中引用该名称的单元格数。但是,如果在之前生成错误的单元格公式中使用了名称,该单元格的after结果将相同。此问题由私有函数Prior_Errors解决,该函数确定在Name无效之前Name是否出现在错误单元格的公式中。Prior_Errors使用的InStr方法不完美,但仅适用于在启动宏之前有错误的公式(希望很少)。此外,如果在具有初始错误的单独公式中,则具有工作簿范围的名称和具有工作表范围的重复名称可能会被额外计数。
这个宏的灵感来自Doug Glancy上面的回答:https://stackoverflow.com/a/26691025/10172433