使用集合检查名称是否存在

Using a collection to check if Names exist

我正在尝试创建一个子例程,该子例程将获取一堆字符串的集合,单步执行它,并检查是否存在以该字符串为名称的命名范围或公式。先尝试一个项目:

Dim colCritNames As New Collection
colCritNames.Add "Version" 'the name of a named formula

For i = 1 To colCritNames.Count
    nm = CStr(colCritNames(i).Name)
    nmchk = Check_UW_For_Name(nm)
    If Not nmchk Then Call Fail("Critical Name")  'prints a msgbox with the error type so I know what happened
Next i
'...code for if all the names are there...

Function Check_UW_For_Name(find_name As String) As Boolean
Dim wb As Workbook
Set wb = UserFileBook  'global ref to the workbook to check

On Error Goto Fail
Check_UW_For_Name = CBool(Len(wb.Names(find_name).Name) <> 0)
On Error GoTo 0
End Function

这是根据完整内容编辑的。 Check_UW_For_Name 当我用“Version”作为参数调用它时工作正常 Check_UW_For_Name("Version");它在 USerFIleBook 中找到它,当我用“Nope”调用它时,因为没有 Nope 名称,它转到了我的错误处理程序。但是当我尝试使用集合来存储我想要查找的名称时,我不断得到 'ByRef argument mismatch'。我只尝试了 nm = colCritNames(i)nm=colCritNames(i).Name,我尝试让 find_name 成为 Variant 并添加一个 ByVal,我最初尝试让 nm 成为一个名字,让 Check_UW_For_Name(find_name 作为名称)并为每个使用一个(对于 colCritNames 中的每个 nm...)并且它的 none 有效。

我如何设置一个名称集合并逐步查看它以查看相关工作簿中是否存在匹配的命名 range/formula?或者有更好的方法吗? (我也需要其他地方的合集)

我不太明白您对集合的计划是什么,但这将添加具有指定字符串的任何单元格以及任何范围。一旦它们被识别(添加到集合中),我不清楚你在做什么,但希望这是有道理的并让你继续。

Sub RunForEachString()
   Const yourStrings = "foo,bar,hope,this,works"
   Dim stringsAsArray() As String
   stringsAsArray = Split(yourStrings, ",")
   
   Dim i As Long
   
   For i = LBound(stringsAsArray) To UBound(stringsAsArray)
     Call findAllNamesFormulas(stringsAsArray(i), ThisWorkbook)
   Next i
   
End Sub


Private Sub findAllNamesFormulas(theText As String, theWorkbook As Workbook)
   Dim ws As Worksheet, n As Name, aCell As Range
   Dim aCollection As New Collection
   
   For Each ws In ThisWorkbook.Worksheets
      For Each aCell In ws.UsedRange.Cells
         If InStr(1, aCell.Formula, theText, vbTextCompare) > 0 Then
            aCollection.Add (aCell)
         End If
         
      Next aCell
   Next ws

   For Each n In ThisWorkbook.Names
      If InStr(1, n.Name, theText, vbTextCompare) > 0 Then
         aCollection.Add (n)
      End If
   Next n
   
   'not sure what you plan to do after collection?
   Debug.Print aCollection.Count
End Sub

这对我有用:

Sub Tester()
    Dim colCritNames As New Collection, nm, wb As Workbook, msg As String
    
    colCritNames.Add "Version"
    colCritNames.Add "NotThere"
    colCritNames.Add "AlsoNotThere"
    
    Set wb = ThisWorkbook 'for example
    For Each nm In colCritNames
        If Not Check_UW_For_Name(wb, CStr(nm)) Then
            msg = msg & vbLf & " - " & nm
        End If
    Next nm
    
    If Len(msg) > 0 Then
        MsgBox "One or more required names are missing:" & msg, _
                vbExclamation, "Oops"
        Exit Sub
    End If
    
    'proceed if OK...
    
End Sub

'check for a defined Name `find_name` in workbook `wb`
' prefer wb as parameter over using a Global....
Function Check_UW_For_Name(wb As Workbook, find_name As String) As Boolean
    On Error Resume Next
    Check_UW_For_Name = (wb.Names(find_name).Name = find_name)
End Function

您可以像这样创建工作簿中所有命名范围的集合:

Private Sub NamedRangesDemo()

    Dim NamedRanges As New Collection, NamedRange As Variant
    
    For Each NamedRange In ThisWorkbook.Names
    
        NamedRanges.Add NamedRange.Name
        
    Next NamedRange

End Sub

然后将您想要的任何字符串与 NamedRanges 集合进行比较。

顺便说一句,this question和你的有点相似。