检查VB6集合中是否存在记录?
我在当前的工作场所继承了一个大型VB6应用程序。我在工作中正在学习VB6,遇到很多问题。目前的主要问题是我不知道如何检查Collection对象中是否存在键。有人可以帮忙吗?
解决方案
回答
我一直用这样的功能来做到这一点:
public function keyExists(myCollection as collection, sKey as string) as Boolean on error goto handleerror: dim val as variant val = myCollection(sKey) keyExists = true exit sub handleerror: keyExists = false end function
回答
@Mark BiekkeyExists与我的标准Exists()函数非常匹配。为了使该类对暴露于COM的集合和检查数字索引更有用,我建议将sKey和myCollection更改为不键入。如果该函数将与对象集合一起使用,则需要" set"(在设置val的行上)。
编辑:令我感到困惑的是,我从未注意到基于对象和基于值的Exists()函数有不同的要求。我很少将集合用于非对象,但这似乎是一个缺陷的完美瓶颈,当我需要检查存在性时将很难找到它。因为如果错误处理程序已经处于活动状态,则错误处理将失败,因此需要两个函数来获取新的错误范围。只需调用Exists()函数:
Public Function Exists(col, index) As Boolean On Error GoTo ExistsTryNonObject Dim o As Object Set o = col(index) Exists = True Exit Function ExistsTryNonObject: Exists = ExistsNonObject(col, index) End Function Private Function ExistsNonObject(col, index) As Boolean On Error GoTo ExistsNonObjectErrorHandler Dim v As Variant v = col(index) ExistsNonObject = True Exit Function ExistsNonObjectErrorHandler: ExistsNonObject = False End Function
并验证功能:
Public Sub TestExists() Dim c As New Collection Dim b As New Class1 c.Add "a string", "a" c.Add b, "b" Debug.Print "a", Exists(c, "a") ' True ' Debug.Print "b", Exists(c, "b") ' True ' Debug.Print "c", Exists(c, "c") ' False ' Debug.Print 1, Exists(c, 1) ' True ' Debug.Print 2, Exists(c, 2) ' True ' Debug.Print 3, Exists(c, 3) ' False ' End Sub
回答
正如Thomas所指出的,我们需要设置一个对象而不是Let。这是我库中的通用函数,适用于值和对象类型:
Public Function Exists(ByVal key As Variant, ByRef col As Collection) As Boolean 'Returns True if item with key exists in collection On Error Resume Next Const ERR_OBJECT_TYPE As Long = 438 Dim item As Variant 'Try reach item by key item = col.item(key) 'If no error occurred, key exists If Err.Number = 0 Then Exists = True 'In cases where error 438 is thrown, it is likely that 'the item does exist, but is an object that cannot be Let ElseIf Err.Number = ERR_OBJECT_TYPE Then 'Try reach object by key Set item = col.item(key) 'If an object was found, the key exists If Not item Is Nothing Then Exists = True End If End If Err.Clear End Function
就像Thomas所建议的那样,我们可以将Collection类型更改为Object来概括这一点。大多数集合类都共享.Item(key)语法,因此实际上可能很有用。
编辑好像我被托马斯本人打败了。但是,为了更容易重用,我个人更喜欢没有私有依赖项的单个函数。
回答
当集合中不存在该键时,使用错误处理程序来捕获情况可能会使使用"中断所有错误"选项进行调试变得很烦人。为了避免不必要的错误,我经常创建一个类,该类在Collection中具有存储的对象,而在Dictionary中具有所有键。字典具有exist(key)-function,因此我可以在尝试从集合中获取对象之前调用它。我们只能将字符串存储在Dictionary中,因此如果需要存储对象,则仍然需要Collection。
回答
更好的解决方案是编写TryGet函数。很多时候,我们将要进行检查,然后再获取项目。同时执行可节省时间。
public Function TryGet(key as string, col as collection) as Variant on error goto errhandler Set TryGet= col(key) exit function errhandler: Set TryGet = nothing end function
回答
看
http://www.visualbasic.happycodings.com/Other/code10.html
这里的实现的优点是还可以选择返回返回的元素,并且可以处理对象/本机类型(根据注释)。
由于链接不再可用,因此在此处转载:
确定项目是否存在于集合中
以下代码显示了如何确定集合中是否存在某个项目。
Option Explicit 'Purpose : Determines if an item already exists in a collection 'Inputs : oCollection The collection to test for the existance of the item ' vIndex The index of the item. ' [vItem] See Outputs 'Outputs : Returns True if the item already exists in the collection. ' [vItem] The value of the item, if it exists, else returns "empty". 'Notes : 'Example : Function CollectionItemExists(vIndex As Variant, oCollection As Collection, Optional vItem As Variant) As Boolean On Error GoTo ErrNotExist 'Clear output result If IsObject(vItem) Then Set vItem = Nothing Else vItem = Empty End If If VarType(vIndex) = vbString Then 'Test if item exists If VarType(oCollection.Item(CStr(vIndex))) = vbObject Then 'Return an object Set vItem = oCollection.Item(CStr(vIndex)) Else 'Return an standard variable vItem = oCollection.Item(CStr(vIndex)) End If Else 'Test if item exists If VarType(oCollection.Item(Int(vIndex))) = vbObject Then 'Return an object Set vItem = oCollection.Item(Int(vIndex)) Else 'Return an standard variable vItem = oCollection.Item(Int(vIndex)) End If End If 'Return success CollectionItemExists = True Exit Function ErrNotExist: CollectionItemExists = False On Error GoTo 0 End Function 'Demonstration routine Sub Test() Dim oColl As New Collection, oValue As Variant oColl.Add "red1", "KEYA" oColl.Add "red2", "KEYB" 'Return the two items in the collection Debug.Print CollectionItemExists("KEYA", oColl, oValue) Debug.Print "Returned: " & oValue Debug.Print "-----------" Debug.Print CollectionItemExists(2, oColl, oValue) Debug.Print "Returned: " & oValue 'Should fail Debug.Print CollectionItemExists("KEYC", oColl, oValue) Debug.Print "Returned: " & oValue Set oColl = Nothing End Sub
- 详情请参见:https://web.archive.org/web/20140723190623/http://visualbasic.happycodings.com/other/code10.html#sthash.MlGE42VM.dpuf
回答
我的标准功能非常简单。无论元素类型如何,它都将起作用,因为它不会理会任何分配,它仅执行collection属性get。
Public Function Exists(ByVal oCol As Collection, ByVal vKey As Variant) As Boolean On Error Resume Next oCol.Item vKey Exists = (Err.Number = 0) Err.Clear End Function