Check if a record exists in a VB6 collection?
我在当前的工作场所继承了一个大型VB6应用程序。 我在工作中正在学习VB6,遇到很多问题。 目前的主要问题是我不知道如何检查Collection对象中是否存在键。 有人可以帮忙吗?
我的标准功能非常简单。无论元素类型如何,它都将起作用,因为它不会理会任何分配,它仅执行collection属性get。
1 2 3 4 5 6 7 8
| 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 |
@Mark Biek您的keyExists与我的标准Exists()函数非常匹配。为了使该类对暴露于COM的集合和检查数字索引更有用,我建议将sKey和myCollection更改为不键入。如果该函数将与对象集合一起使用,则需要" set"(在设置val的行上)。
编辑:令我感到困惑的是,我从未注意到基于对象和基于值的Exists()函数有不同的要求。我很少将集合用于非对象,但这似乎是一个缺陷的完美瓶颈,当我需要检查存在性时很难跟踪。因为如果错误处理程序已经处于活动状态,错误处理将失败,因此需要两个函数来获取新的错误范围。只需调用Exists()函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 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 |
并验证功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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 |
我一直用这样的功能来做到这一点:
1 2 3 4 5 6 7 8 9 10 11
| 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 |
正如Thomas所指出的,您需要设置一个对象而不是Let。这是我的库中用于值和对象类型的常规函数??:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 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)语法,因此实际上可能有用。
编辑好像我被托马斯本人打败了。但是,为了更容易重用,我个人更喜欢没有私有依赖项的单个函数。
语句"如果错误处理程序已经处于活动状态,错误处理将失败"只是部分正确的说法。
您的例程中可以有多个错误处理程序。
因此,一个功能只能在一个功能中提供相同的功能。
只是这样重写代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| Public Function Exists(col, index) As Boolean
Dim v As Variant
TryObject:
On Error GoTo ExistsTryObject
Set v = col(index)
Exists = True
Exit Function
TryNonObject:
On Error GoTo ExistsTryNonObject
v = col(index)
Exists = True
Exit Function
ExistsTryObject:
' This will reset your Err Handler
Resume TryNonObject
ExistsTryNonObject:
Exists = False
End Function |
但是,如果仅将代码合并到例程的TryNonObject部分中,则将产生相同的信息。
对于对象和非对象都将成功。
但是,这将加快非对象代码的执行速度,因为您只需执行一个语句即可断言该项目存在于集合中。
如果在Collection中不存在该键时使用错误处理程序来捕获情况,则使用"打破所有错误"选项进行调试会很烦人。为了避免不必要的错误,我经常创建一个类,该类在Collection中具有存储的对象,而在Dictionary中具有所有键。字典具有exist(key)-function,因此我可以在尝试从集合中获取对象之前调用它。您只能将字符串存储在字典中,因此如果需要存储对象,则仍然需要Collection。
看到
http://www.visualbasic.happycodings.com/Other/code10.html
该实现的优点是还可以选择返回找到的元素,并且可以使用对象/本机类型(根据注释)。
转载于此,因为该链接不再可用:
确定项目是否存在于集合中
以下代码显示了如何确定集合中是否存在某个项目。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| 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
更好的解决方案是编写TryGet函数。很多时候,您将要进行检查,然后再获取项目。同时执行可节省时间。
1 2 3 4 5 6 7
| 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 |
在寻找这样的功能时,我将其设计如下。
这应该适用于对象和非对象,而无需分配新变量。
1 2 3 4 5 6 7 8 9 10 11 12 13
| Public Function Exists(ByRef Col As Collection, ByVal Key) As Boolean
On Error GoTo KeyError
If Not Col(Key) Is Nothing Then
Exists = True
Else
Exists = False
End If
Exit Function
KeyError:
Err.Clear
Exists = False
End Function |
|