在编辑您的帖子期间,根据 cmets 的一些拼写错误已经得到纠正。
在回答您的问题时,我想介绍相关方面。
虽然在集合中使用键主要有三个优点
- 如果订单更改,您的代码仍将访问正确的项目
- 您可以直接访问该项目而无需通读整个
收藏
- 它可以让你的代码更具可读性。
*但同时在使用keys中主要存在三个问题
合集
无法检查密钥是否存在
您无法更改密钥
您无法检索密钥
根据 Pearsons 的文章,集合的键是只写的 - 无法获取集合的现有键的列表。进一步阅读引用的段落:-
这里,Col 是一个 Collection 对象,我们将在其中存储多个
CFile 对象。 CollKeys Collection 用于存储密钥
存储在 Coll Collection 中的 CFile 对象。我们需要这一秒
集合,因为集合的键是只写的——有
无法获取现有集合键的列表。中的一个
CFiles 提供的增强功能是能够检索列表
集合的键。
Custom Collection Classes
一种方法是遍历集合的成员,看看是否有匹配您正在寻找的东西,另一种方法是捕获 Item not in collection 错误,然后设置一个标志来表示该项目不存在.对这些方法的看法不同,而有些人认为这不是捕获错误的好方法,而其他部分则认为对于任何中型到大型集合而言,这将比迭代快得多。
因此,如果我们采用一种方法来捕获错误,那么我们得到的错误编号取决于导致错误的确切原因。我们需要一个代码例程来检查错误。可以用最简单的方式。
'c1 is the collection
For i = 1 To c1.Count
Debug.Print Err.Number, Err.Description
If Err.Number <> 0 Then Err.Clear
Next i
各种专业人士提出的错误捕获例程在他们认为重要并包含在其例程中的错误编号上有所不同。与收集对象相关的各种常见错误编号是:-
-
Error 5无效的过程调用或参数。这个错误也可能发生
如果尝试调用在
当前平台。例如,某些程序可能仅适用于
Microsoft Windows 或 Macintosh 等。
-
error 438"对象不支持这个属性或方法一个对象
是一个类实例。类实例支持一些属性
在该类类型定义中定义,不支持这个。
-
Error 457 此键已与此元素关联
集合。您为集合成员指定了一个键
标识集合的另一个成员。选择不同的键
为该会员。
-
Error 91 对象变量或未设置块变量。有两个
创建对象变量的步骤。首先你必须声明
对象变量。然后您必须为该对象分配一个有效的引用
变量使用 Set 语句。你试图使用一个对象
尚未引用有效对象的变量。
-
Error 450 参数数量错误或属性无效
分配。过程调用中的参数数量
与预期的所需参数的数量不同
过程。如果您尝试为只读属性赋值,
在上述错误中,错误编号 438 被认为是重要的,另一个是 5。我在我的示例测试程序中加入了一个函数例程,该例程由 Mark Nold 在 7 年前于 2008 年发布,参见 SO 问题 Determining whether an object is a member of a collection in VBA应归功于他。
在程序测试运行时不允许出现错误 457 等错误。我试图填充重复的键数据,它在程序测试时给出了错误,如快照所示。
删除后显示正确的输出,如快照所示。
如果不将键值存储在独立数组中,可能无法使用普通集合获取集合的键列表。最简单的替代方法是添加对 Microsoft 脚本运行时的引用并改用功能更强大的字典。
我已经包含了这种方法来获取我的程序中的键列表。
在填充 Collection 时,要确保 key 是第二个参数,并且必须是唯一的字符串。
我的程序的完整代码是。
Sub Generic_key_check()
Dim arr As Variant
Dim c1 As New Collection
Dim dic As Object
With Application
.ScreenUpdating = False
End With
Set dic = CreateObject("Scripting.Dictionary")
dic.CompareMode = vbTextCompare
'Populate the collection
c1.Add "sheet1", "sheet1"
c1.Add "sheet2", "sheet2"
c1.Add "sheet3", "sheet3"
c1.Add "sheet4", "sheet4"
c1.Add "sheet5", "sheet5"
c1.Add 2014001, "Long1"
c1.Add 2015001, "Long2"
c1.Add 2016001, "Long3"
c1.Add 2015002, "Long4"
c1.Add 2016002, "Long5"
'Populate the dictionary
dic.Add "sheet1", "sheet1"
dic.Add "sheet2", "sheet2"
dic.Add "sheet3", "sheet3"
dic.Add "sheet4", "sheet4"
dic.Add "sheet5", "sheet5"
dic.Add "Long1", 2014001
dic.Add "Long2", 2015001
dic.Add "Long3", 2016001
dic.Add "Long4", 2015002
dic.Add "Long5", 2016002
' Get a list of key items by Dictionary Method
Dim N As Variant
For Each N In dic.Keys
Debug.Print "Key: " & N, "Value: " & dic.item(N)
Next
'Test for two types of data whether key exists or not.
If InCollection(c1, "Long1") Then
'If Exists("Long1", c1) Then
Debug.Print "Good"
Else
' If there is error then print out the error number and its description.
Debug.Print Err.Number, Err.Description
Debug.Print "Not Good"
End If
If InCollection(c1, "sheet2") Then
Debug.Print "Good"
Else
Debug.Print Err.Number, Err.Description
Debug.Print "Not Good"
End If
'Checking whether desired key has populated correctly
Debug.Print c1("Sheet1")
Debug.Print c1("Long3")
'Listing out collection items to check theyexist in the collection.
For i = 1 To c1.Count
Debug.Print c1.item(i)
Next i
With Application
.ScreenUpdating = True
End With
Set c1 = Nothing
End Sub
Public Function InCollection(col As Collection, key As String) As Boolean
Dim var As Variant
Dim errNumber As Long
InCollection = False
Set var = Nothing
Err.Clear
On Error Resume Next
var = col.item(key)
errNumber = CLng(Err.Number)
On Error GoTo 0
'5 is not in, 0 and 438 represent incollection
If errNumber = 5 Then ' it is 5 if not in collection
InCollection = False
Else
InCollection = True
End If
End Function
快照中显示了即时窗口中显示的每个程序的最终输出。