You are on page 1of 10

10/8/2020 Determining whether an object is a member of a collection in VBA - Stack Overflow

Determining whether an object is a member of a collection in VBA


Asked 12 years ago Active 3 months ago Viewed 126k times

How do I determine whether an object is a member of a collection in VBA?

63 Specifically, I need to find out whether a table definition is a member of the TableDefs
collection.

vba object ms-access collections


9

edited Jul 1 at 7:23 asked Sep 26 '08 at 4:57


Martijn Pieters ♦ inglesp
841k 214 3229 3,161 9 28 30
2815

15 Answers Active Oldest Votes

Your best bet is to iterate over the members of the collection and see if any match what you
are looking for. Trust me I have had to do this many times.
25
The second solution (which is much worse) is to catch the "Item not in collection" error and
then set a flag to say the item does not exist.

answered Sep 26 '08 at 5:00


Gilligan
1,467 1 15 16

12 is this really the only way to do it? – inglesp Sep 26 '08 at 5:03

6 "correct" perhaps, but still very unsatisfactory. Thanks both. – inglesp Sep 26 '08 at 5:20

11 To be honest, I find Access in itself to be unsatisfactory as a programming platform in general. But we


must play with the cards we are dealt. :-) – Gilligan Sep 26 '08 at 11:50

3 A VB6/VBA collection is not just something you can iterate over. It also provides optional key access. –
Joe Sep 26 '08 at 18:27

4 Solution provided by Mark Nold below is far superior – Mr1159pm Feb 3 '13 at 6:19

Isn't it good enough?

74 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:

https://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba 1/10
10/8/2020 Determining whether an object is a member of a collection in VBA - Stack Overflow
Contains = False
End Function

edited Nov 9 '11 at 16:36 answered Jun 14 '09 at 1:10


Jason Plank Vadim
2,292 4 28 39 1,216 2 10 10

1 This seems like the simplest of all solutions presented here. I've used this and it works perfectly. I did
however have to change the col argument to be of type Variant. – A. Murray Dec 9 '12 at 21:55

1 Nearly 6 years later, it is still a perfectly viable solution. I'm using it as is with no issues. – FreeMan Apr
7 '15 at 15:01

3 It is a great solution, it is just a bit silly that thousands of people have to reimplement it. VB/VBA are
supposed to be higher level than that. – Leo May 4 '15 at 0:34

Worked very well for me. – LAL Sep 21 '15 at 21:32

23 This doesn't work if the value for a key is an object not a primitive - if the value is an object you'll get an
assignment error (object references need to be assigned with "Set"), thus returning "False" even if the
key exists. Replace the line obj = col(key) with IsObject(col(key)) to handle both object and primitive
values. – Richard H May 17 '16 at 8:34

Not exactly elegant, but the best (and quickest) solution i could find was using OnError. This
will be significantly faster than iteration for any medium to large collection.
39
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

answered Oct 20 '08 at 14:56


Mark Nold
5,342 6 27 33

9 I don't perceive this as non elegant... it's a try-catch approach, something very normal in C++ and java,
e.g. I'd bet it's much more fast that iterating the whole collection, because VB calculated the hash for
the provided key, and searched it on the hash table, not in the item's collection. – jpinto3912 Nov 12 '08
at 19:17

3 this implementation is not okay: i.e. it will return True if any other error than #5 occurs – TmTron Apr 22

https://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba 2/10
10/8/2020 Determining whether an object is a member of a collection in VBA - Stack Overflow

'13 at 15:55

3 errNumber is not 5 here, it's 3265 instead :( ... It's not elegant from this aspect - of relying on hard-
coded error codes – Amir Gonnen May 26 '14 at 7:20

This is an old question. I have carefully reviewed all the answers and comments, tested the
solutions for performance.
12
I came up with the fastest option for my environment which does not fail when a collection has
objects as well as primitives.

Public Function ExistsInCollection(col As Collection, key As Variant) As Boolean


On Error GoTo err
ExistsInCollection = True
IsObject(col.item(key))
Exit Function
err:
ExistsInCollection = False
End Function

In addition, this solution does not depend on hard-coded error values. So the parameter col
As Collection can be substituted by some other collection type variable, and the function must
still work. E.g., on my current project, I will have it as col As ListColumns .

edited Sep 30 '18 at 8:44 answered Jan 22 '18 at 5:41


ZygD
5,695 11 44 60

1 Excellent solution, and concise. Thank you! – Andre Feb 9 '18 at 10:54

Slight improvement is to exclude the f variable, i.e. simply call IsObject(col.item(key)) –


user2426679 Sep 29 '18 at 22:48

@user2426679 Thank you! I love slight improvements which reduce the amount of code :) – ZygD Sep
30 '18 at 8:45

I created this solution from the above suggestions mixed with microsofts solution of for
iterating through a collection.
3
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

https://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba 3/10
10/8/2020 Determining whether an object is a member of a collection in VBA - Stack Overflow
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

answered Nov 23 '12 at 16:36


Gov_Programmer
39 2

You can shorten the suggested code for this as well as generalize for unexpected errors. Here
you go:
3
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

edited Jun 5 '14 at 15:56 answered Jun 4 '14 at 15:46


KthProg
1,660 1 17 29

In your specific case (TableDefs) iterating over the collection and checking the Name is a
good approach. This is OK because the key for the collection (Name) is a property of the
2 class in the collection.

But in the general case of VBA collections, the key will not necessarily be part of the object in
the collection (e.g. you could be using a Collection as a dictionary, with a key that has nothing
to do with the object in the collection). In this case, you have no choice but to try accessing
the item and catching the error.

edited Sep 29 '08 at 21:17 answered Sep 26 '08 at 17:50


Joe
112k 27 175 309

I have some edit, best working for collections:

2
https://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba 4/10
10/8/2020 Determining whether an object is a member of a collection in VBA - Stack Overflow

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

Run code snippet Copy snippet to answer Expand snippet

answered Jan 3 '15 at 20:55


Levent
21 1

this version works for primitive types and for classes (short test-method included)

1 ' 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
' e.g.
' 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()

https://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba 5/10
10/8/2020 Determining whether an object is a member of a collection in VBA - Stack Overflow
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

answered Feb 6 '14 at 10:03


TmTron
8,472 2 42 81

For the case when key is unused for collection:

1 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

edited Sep 13 '16 at 16:34 answered Sep 13 '16 at 7:51


Sharunas Bielskis
801 1 14 17

Please edit with more information. Code-only and "try this" answers are discouraged, because they
contain no searchable content, and don't explain why someone should "try this". – abarisone Sep 13
'16 at 9:47

1 This is a disastrous solution in terms of speed, the ON ERROR solution is much better: see low-
bandwidth.blogspot.com.au/2013/12/… – Ben McIntyre Feb 16 '18 at 7:36

1 The solution is the best, when the collection contains no keys only items, since the ON ERROR
solution will not work in this case. What explanation is needed for this simple solution? A loop over the
members of the collection and check for equality. – Dietrich Baumgarten Feb 10 at 14:00

It requires some additional adjustments in case the items in the collection are not Objects, but
Arrays. Other than that it worked fine for me.
1

https://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba 6/10
10/8/2020 Determining whether an object is a member of a collection in VBA - Stack Overflow

Public Function CheckExists(vntIndexKey As Variant) As Boolean


On Error Resume Next
Dim cObj As Object

' just get the object


Set cObj = mCol(vntIndexKey)

' here's the key! Trap the Error Code


' when the error code is 5 then the Object is Not Exists
CheckExists = (Err <> 5)

' just to clear the error


If Err <> 0 Then Call Err.Clear
Set cObj = Nothing
End Function

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

edited Jan 21 '18 at 22:25 answered Feb 29 '12 at 10:34


ZygD muscailie
5,695 11 44 60 49 2

i used this code to convert array to collection and back to array to remove duplicates,
assembled from various posts here (sorry for not giving properly credit).
0
Function ArrayRemoveDups(MyArray As Variant) As Variant
Dim nFirst As Long, nLast As Long, i As Long
Dim item As Variant, outputArray() As Variant
Dim Coll As New Collection

'Get First and Last Array Positions


nFirst = LBound(MyArray)
nLast = UBound(MyArray)
ReDim arrTemp(nFirst To nLast)
i = nFirst
'convert to collection
For Each item In MyArray
skipitem = False
For Each key In Coll
If key = item Then skipitem = True
Next
If skipitem = False Then Coll.Add (item)
Next item
'convert back to array
ReDim outputArray(0 To Coll.Count - 1)
For i = 1 To Coll.Count
outputArray(i - 1) = Coll.item(i)
Next
ArrayRemoveDups = outputArray
End Function

answered Jun 9 at 11:09


nir
79 1 2

Not my code, but I think it's pretty nicely written. It allows to check by the key as well as by the
Object element itself and handles both the On Error method and iterating through all
https://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba 7/10
10/8/2020 Determining whether an object is a member of a collection in VBA - Stack Overflow

0 Collection elements.

https://danwagner.co/how-to-check-if-a-collection-contains-an-object/

I'll not copy the full explanation since it is available on the linked page. Solution itself copied in
case the page eventually becomes unavailable in the future.

The doubt I have about the code is the overusage of GoTo in the first If block but that's easy to
fix for anyone so I'm leaving the original code as it is.

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'INPUT : Kollection, the collection we would like to examine
' : (Optional) Key, the Key we want to find in the collection
' : (Optional) Item, the Item we want to find in the collection
'OUTPUT : True if Key or Item is found, False if not
'SPECIAL CASE: If both Key and Item are missing, return False
Option Explicit
Public Function CollectionContains(Kollection As Collection, Optional Key As Variant,
Optional Item As Variant) As Boolean
Dim strKey As String
Dim var As Variant

'First, investigate assuming a Key was provided


If Not IsMissing(Key) Then

strKey = CStr(Key)

'Handling errors is the strategy here


On Error Resume Next
CollectionContains = True
var = Kollection(strKey) '<~ this is where our (potential) error will occur
If Err.Number = 91 Then GoTo CheckForObject
If Err.Number = 5 Then GoTo NotFound
On Error GoTo 0
Exit Function

CheckForObject:
If IsObject(Kollection(strKey)) Then
CollectionContains = True
On Error GoTo 0
Exit Function
End If

NotFound:
CollectionContains = False
On Error GoTo 0
Exit Function

'If the Item was provided but the Key was not, then...
ElseIf Not IsMissing(Item) Then

CollectionContains = False '<~ assume that we will not find the item

'We have to loop through the collection and check each item against the passed-
in Item
For Each var In Kollection
If var = Item Then
CollectionContains = True
Exit Function
End If
Next var

'Otherwise, no Key OR Item was provided, so we default to False


Else
CollectionContains = False

https://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba 8/10
10/8/2020 Determining whether an object is a member of a collection in VBA - Stack Overflow
End If

End Function

edited Feb 9 '18 at 12:25 answered Feb 9 '18 at 10:25


Ister
4,739 11 24

I did it like this, a variation on Vadims code but to me a bit more readable:

-1 ' 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

answered Jul 16 '15 at 14:52


DrBuck
646 6 19

I wrote this code. I guess it can help someone...

-1 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

answered Aug 5 '15 at 14:09


Joao Louzada
73 8

https://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba 9/10
10/8/2020 Determining whether an object is a member of a collection in VBA - Stack Overflow

https://stackoverflow.com/questions/137845/determining-whether-an-object-is-a-member-of-a-collection-in-vba 10/10

You might also like