<p>I've inherited a large VB6 app at my current workplace. I'm kinda learning VB6 on the job and there are a number of problems I'm having. The major issue at the moment is I can't figure out how to check if a key exists in a Collection object. Can anyone help?</p>

[{'answer_id': 40659, 'author': 'Mark Biek', 'author_id': 305, 'author_profile': 'https://Stackoverflow.com/users/305', 'pm_score': 3, 'selected': False, 'text': "<p>I've always done it with a function like this:</p>\n\n<pre><code>public function keyExists(myCollection as collection, sKey as string) as Boolean\n  on error goto handleerror:\n\n  dim val as variant\n\n  val = myCollection(sKey)\n  keyExists = true\n  exit sub\nhandleerror:\n  keyExists = false\nend function\n</code></pre>\n"}, {'answer_id': 40751, 'author': 'Tom Mayfield', 'author_id': 2314, 'author_profile': 'https://Stackoverflow.com/users/2314', 'pm_score': 5, 'selected': False, 'text': '<p>@Mark Biek Your keyExists closely matches my standard Exists() function. To make the class more useful for COM-exposed collections and checking for numeric indexes, I\'d recommend changing sKey and myCollection to not be typed.  If the function is going to be used with a collection of objects, \'set\' is required (on the line where val is set).</p>\n\n<p><strong>EDIT</strong>: It was bugging me that I\'ve never noticed different requirements for an object-based and value-based Exists() function. I very rarely use collections for non-objects, but this seemed such a perfect bottleneck for a bug that would be so hard to track down when I needed to check for existence.  Because error handling will fail if an error handler is already active, two functions are required to get a new error scope.  Only the Exists() function need ever be called:</p>\n\n<pre><code>Public Function Exists(col, index) As Boolean\nOn Error GoTo ExistsTryNonObject\n    Dim o As Object\n\n    Set o = col(index)\n    Exists = True\n    Exit Function\n\nExistsTryNonObject:\n    Exists = ExistsNonObject(col, index)\nEnd Function\n\nPrivate Function ExistsNonObject(col, index) As Boolean\nOn Error GoTo ExistsNonObjectErrorHandler\n    Dim v As Variant\n\n    v = col(index)\n    ExistsNonObject = True\n    Exit Function\n\nExistsNonObjectErrorHandler:\n    ExistsNonObject = False\nEnd Function\n</code></pre>\n\n<p>And to verify the functionality:</p>\n\n<pre><code>Public Sub TestExists()\n    Dim c As New Collection\n\n    Dim b As New Class1\n\n    c.Add "a string", "a"\n    c.Add b, "b"\n\n    Debug.Print "a", Exists(c, "a") \' True \'\n    Debug.Print "b", Exists(c, "b") \' True \'\n    Debug.Print "c", Exists(c, "c") \' False \'\n    Debug.Print 1, Exists(c, 1) \' True \'\n    Debug.Print 2, Exists(c, 2) \' True \'\n    Debug.Print 3, Exists(c, 3) \' False \'\nEnd Sub\n</code></pre>\n'}, {'answer_id': 40831, 'author': 'jevakallio', 'author_id': 4333, 'author_profile': 'https://Stackoverflow.com/users/4333', 'pm_score': 3, 'selected': False, 'text': "<p>As pointed out by Thomas, you need to Set an object instead of Let. Here's a general function from my library that works for value and object types:</p>\n\n<pre><code>Public Function Exists(ByVal key As Variant, ByRef col As Collection) As Boolean\n\n'Returns True if item with key exists in collection\n\nOn Error Resume Next\n\nConst ERR_OBJECT_TYPE As Long = 438\nDim item As Variant\n\n'Try reach item by key\nitem = col.item(key)\n\n'If no error occurred, key exists\nIf Err.Number = 0 Then\n    Exists = True\n\n'In cases where error 438 is thrown, it is likely that\n'the item does exist, but is an object that cannot be Let\nElseIf Err.Number = ERR_OBJECT_TYPE Then\n\n    'Try reach object by key\n    Set item = col.item(key)\n\n    'If an object was found, the key exists\n    If Not item Is Nothing Then\n        Exists = True\n    End If\n\nEnd If\n\nErr.Clear\n\nEnd Function\n</code></pre>\n\n<p>As also advised by Thomas, you can change the Collection type to Object to generalize this. The .Item(key) syntax is shared by most collection classes, so that might actually be useful.</p>\n\n<p><strong>EDIT</strong> Seems like I was beaten to the punch somewhat by Thomas himself. However for easier reuse I personally prefer a single function with no private dependencies.</p>\n"}, {'answer_id': 52752, 'author': 'Kaniu', 'author_id': 3236, 'author_profile': 'https://Stackoverflow.com/users/3236', 'pm_score': 2, 'selected': False, 'text': '<p>Using the error handler to catch cases when the key does not exists in the Collection can make debugging with "break on all errors" option quite annoying. To avoid unwanted errors I quite often create a class which has the stored objects in a Collection and all keys in a Dictionary. Dictionary has exists(key) -function so I can call that before trying to get an object from the collection. You can only store strings in a Dictionary, so a Collection is still needed if you need to store objects.</p>\n'}, {'answer_id': 883192, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 2, 'selected': False, 'text': '<p>Better solution would be to write a TryGet function.  A lot of the time you are going to be checking exists, and then getting the item.  Save time by doing it at the same time.</p>\n\n<pre><code>public Function TryGet(key as string, col as collection) as Variant\n  on error goto errhandler\n  Set TryGet= col(key)\n  exit function\nerrhandler:\n  Set TryGet = nothing  \nend function\n</code></pre>\n'}, {'answer_id': 1825403, 'author': 'Vijay', 'author_id': 107537, 'author_profile': 'https://Stackoverflow.com/users/107537', 'pm_score': 2, 'selected': False, 'text': '<p>see\n<a href="http://www.visualbasic.happycodings.com/Other/code10.html" rel="nofollow noreferrer">http://www.visualbasic.happycodings.com/Other/code10.html</a>\nthe implementation here has the advantage of also optionally returning the found element, and works with object/native types (according to the comments).</p>\n\n<p>reproduced here since the link is no longer available:</p>\n\n<p>Determine if an item exists in a collection</p>\n\n<p>The following code shows you how to determine if an item exists within a collection.</p>\n\n<pre><code>Option Explicit\n\n\'Purpose     :  Determines if an item already exists in a collection\n\'Inputs      :  oCollection         The collection to test for the existance of the item\n\'               vIndex              The index of the item.\n\'               [vItem]             See Outputs\n\'Outputs     :  Returns True if the item already exists in the collection.\n\'               [vItem] The value of the item, if it exists, else returns "empty".\n\'Notes       :\n\'Example     :\n\nFunction CollectionItemExists(vIndex As Variant, oCollection As Collection, Optional vItem As Variant) As Boolean\n    On Error GoTo ErrNotExist\n\n    \'Clear output result\n    If IsObject(vItem) Then\n        Set vItem = Nothing\n    Else\n        vItem = Empty\n    End If\n\n    If VarType(vIndex) = vbString Then\n        \'Test if item exists\n        If VarType(oCollection.Item(CStr(vIndex))) = vbObject Then\n            \'Return an object\n            Set vItem = oCollection.Item(CStr(vIndex))\n        Else\n            \'Return an standard variable\n            vItem = oCollection.Item(CStr(vIndex))\n        End If\n    Else\n        \'Test if item exists\n        If VarType(oCollection.Item(Int(vIndex))) = vbObject Then\n            \'Return an object\n            Set vItem = oCollection.Item(Int(vIndex))\n        Else\n            \'Return an standard variable\n            vItem = oCollection.Item(Int(vIndex))\n        End If\n    End If\n    \'Return success\n    CollectionItemExists = True\n    Exit Function\nErrNotExist:\n    CollectionItemExists = False\n    On Error GoTo 0\nEnd Function\n\n\'Demonstration routine\nSub Test()\n    Dim oColl As New Collection, oValue As Variant\n\n    oColl.Add "red1", "KEYA"\n    oColl.Add "red2", "KEYB"\n    \'Return the two items in the collection\n    Debug.Print CollectionItemExists("KEYA", oColl, oValue)\n    Debug.Print "Returned: " &amp; oValue\n    Debug.Print "-----------"\n    Debug.Print CollectionItemExists(2, oColl, oValue)\n    Debug.Print "Returned: " &amp; oValue\n    \'Should fail\n    Debug.Print CollectionItemExists("KEYC", oColl, oValue)\n    Debug.Print "Returned: " &amp; oValue\n    Set oColl = Nothing\nEnd Sub\n</code></pre>\n\n<ul>\n<li>See more at: <a href="https://web.archive.org/web/20140723190623/http://visualbasic.happycodings.com/other/code10.html#sthash.MlGE42VM.dpuf" rel="nofollow noreferrer">https://web.archive.org/web/20140723190623/http://visualbasic.happycodings.com/other/code10.html#sthash.MlGE42VM.dpuf</a></li>\n</ul>\n'}, {'answer_id': 1825433, 'author': 'Christian Hayter', 'author_id': 115413, 'author_profile': 'https://Stackoverflow.com/users/115413', 'pm_score': 5, 'selected': False, 'text': "<p>My standard function is very simple. This will work regardless of the element type, since it doesn't bother doing any assignment, it merely executes the collection property get.</p>\n\n<pre><code>Public Function Exists(ByVal oCol As Collection, ByVal vKey As Variant) As Boolean\n\n    On Error Resume Next\n    oCol.Item vKey\n    Exists = (Err.Number = 0)\n    Err.Clear\n\nEnd Function\n</code></pre>\n"}, {'answer_id': 9535221, 'author': 'R. van Drie', 'author_id': 1245312, 'author_profile': 'https://Stackoverflow.com/users/1245312', 'pm_score': 2, 'selected': False, 'text': '<p>The statement "error handling will fail if an error handler is already active" is only partly right.</p>\n\n<p>You can have multiple error handlers within your routine.<br/>\nSo, one could accommodate the same functionality in only one function.<br/>\nJust rewrite your code like this:</p>\n\n<pre><code>Public Function Exists(col, index) As Boolean\nDim v As Variant\n\nTryObject:\n    On Error GoTo ExistsTryObject\n        Set v = col(index)\n        Exists = True\n        Exit Function\n\nTryNonObject:\n    On Error GoTo ExistsTryNonObject\n\n        v = col(index)\n        Exists = True\n        Exit Function\n\nExistsTryObject:\n   \' This will reset your Err Handler\n   Resume TryNonObject\n\nExistsTryNonObject:\n        Exists = False\nEnd Function\n</code></pre>\n\n<p>However, if you were to only incorporate the code in the TryNonObject section of the routine, this would yield the same information.<br/>\nIt will succeed for both Objects, and non-objects.\nIt will speed up your code for non-objects, however, since you would only have to perform one single statement to assert that the item exists within the collection.</p>\n'}, {'answer_id': 15221341, 'author': 'Martin', 'author_id': 1261136, 'author_profile': 'https://Stackoverflow.com/users/1261136', 'pm_score': 0, 'selected': False, 'text': '<p>While looking for a function like this i designed it as following.\nThis should work with objects and non-objects without assigning new variables.</p>\n\n<pre><code>Public Function Exists(ByRef Col As Collection, ByVal Key) As Boolean\n    On Error GoTo KeyError\n    If Not Col(Key) Is Nothing Then\n        Exists = True\n    Else\n        Exists = False\n    End If\n\n    Exit Function\nKeyError:\n    Err.Clear\n    Exists = False\nEnd Function\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/40651', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4315/']