确定对象是否是VBA中的集合的成员

如何确定对象是否是VBA中的集合的成员? 具体来说,我需要找出一个表定义是否是TableDefs集合的成员。

你最好的select是遍历集合的成员,看看是否有任何匹配你正在寻找。 相信我,我必须做很多次。

第二个解决scheme(更糟糕的是)要捕获“物品不在收集中”错误,然后设置一个标志来表示物品不存在。

这不够好吗?

Public Function Contains(col As Collection, key As Variant) As Boolean Dim obj As Variant On Error GoTo err Contains = True obj = col(key) Exit Function err: Contains = False End Function 

不完全优雅,但我可以find最好(最快)的解决scheme是使用OnError。 这将比任何大中型集合的迭代快得多。

 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 

我从上面的build议中创build了这个解决scheme,并通过一个集合来迭代微型解决scheme。

 Public Function InCollection(col As Collection, Optional vItem, Optional vKey) As Boolean On Error Resume Next Dim vColItem As Variant InCollection = False If Not IsMissing(vKey) Then col.item vKey '5 if not in collection, it is 91 if no collection exists If Err.Number <> 5 And Err.Number <> 91 Then InCollection = True End If ElseIf Not IsMissing(vItem) Then For Each vColItem In col If vColItem = vItem Then InCollection = True GoTo Exit_Proc End If Next vColItem End If Exit_Proc: Exit Function Err_Handle: Resume Exit_Proc End Function 

您可以缩短build议的代码,以及推广意外的错误。 干得好:

 Public Function InCollection(col As Collection, key As String) As Boolean On Error GoTo incol col.Item key incol: InCollection = (Err.Number = 0) End Function 

对于密钥未用于收集的情况:

 Public Function Contains(col As Collection, thisItem As Variant) As Boolean Dim item As Variant Contains = False For Each item In col If item = thisItem Then Contains = True Exit Function End If Next End Function 

在您的具体情况(TableDefs)迭代收集和检查名称是一个好方法。 这是可以的,因为集合的关键字(Name)是集合中类的一个属性。

但是在VBA集合的一般情况下,关键字不一定是集合中对象的一部分(例如,您可以使用集合作为字典,而关键字与集合中的对象无关)。 在这种情况下,您别无select,只能尝试访问该项目并捕获错误。

我有一些编辑,最好的collections工作:

 Public Function Contains(col As collection, key As Variant) As Boolean Dim obj As Object On Error GoTo err Contains = True Set obj = col.Item(key) Exit Function err: Contains = False End Function 

在这种情况下,您可以考虑使用字典而不是集合。

我这样做,Vadims代码的一个变种,但对我来说更可读:

 ' Returns TRUE if item is already contained in collection, otherwise FALSE Public Function Contains(col As Collection, item As String) As Boolean Dim i As Integer For i = 1 To col.Count If col.item(i) = item Then Contains = True Exit Function End If Next i Contains = False End Function 

解决这个问题:如果对象是TableDeftypes,那么它应该定义在TableDefs集合中,否? 你想testing你的TableDefParent是否与给定的TableDefs集合的Parent

请参阅http://coderstalk.blogspot.com/2007/09/visual-basic-programming-how-to-check.html

如果集合中的项目不是“对象”,而是“数组”,则需要进行一些额外的调整。 除此之外,它为我工作得很好。

我是一个VBA新手,但你可以使用Excel匹配function。 假设你想知道A是否出现在一个范围内。 如果isna(match(a,range,0))是假的,那么A是该集合的成员。

这个版本适用于原始types和类(包括简短的testing方法)

 ' TODO: change this to the name of your module Private Const sMODULE As String = "MVbaUtils" Public Function ExistsInCollection(oCollection As Collection, sKey As String) As Boolean Const scSOURCE As String = "ExistsInCollection" Dim lErrNumber As Long Dim sErrDescription As String lErrNumber = 0 sErrDescription = "unknown error occurred" Err.Clear On Error Resume Next ' note: just access the item - no need to assign it to a dummy value ' and this would not be so easy, because we would need different ' code depending on the type of object ' eg ' Dim vItem as Variant ' If VarType(oCollection.Item(sKey)) = vbObject Then ' Set vItem = oCollection.Item(sKey) ' Else ' vItem = oCollection.Item(sKey) ' End If oCollection.Item sKey lErrNumber = CLng(Err.Number) sErrDescription = Err.Description On Error GoTo 0 If lErrNumber = 5 Then ' 5 = not in collection ExistsInCollection = False ElseIf (lErrNumber = 0) Then ExistsInCollection = True Else ' Re-raise error Err.Raise lErrNumber, mscMODULE & ":" & scSOURCE, sErrDescription End If End Function Private Sub Test_ExistsInCollection() Dim asTest As New Collection Debug.Assert Not ExistsInCollection(asTest, "") Debug.Assert Not ExistsInCollection(asTest, "xx") asTest.Add "item1", "key1" asTest.Add "item2", "key2" asTest.Add New Collection, "key3" asTest.Add Nothing, "key4" Debug.Assert ExistsInCollection(asTest, "key1") Debug.Assert ExistsInCollection(asTest, "key2") Debug.Assert ExistsInCollection(asTest, "key3") Debug.Assert ExistsInCollection(asTest, "key4") Debug.Assert Not ExistsInCollection(asTest, "abcx") Debug.Print "ExistsInCollection is okay" End Sub 

我写了这个代码。 我想它可以帮助别人…

 Public Function VerifyCollection() For i = 1 To 10 Step 1 MyKey = "A" On Error GoTo KillError: Dispersao.Add 1, MyKey GoTo KeepInForLoop KillError: 'If My collection already has the key A Then... count = Dispersao(MyKey) Dispersao.Remove (MyKey) Dispersao.Add count + 1, MyKey 'Increase the amount in relationship with my Key count = Dispersao(MyKey) 'count = new amount On Error GoTo -1 KeepInForLoop: Next End Function