使用集合检查名称是否存在
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和你的有点相似。
我正在尝试创建一个子例程,该子例程将获取一堆字符串的集合,单步执行它,并检查是否存在以该字符串为名称的命名范围或公式。先尝试一个项目:
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和你的有点相似。