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

ing*_*esp 60 collections ms-access vba object access-vba

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

具体来说,我需要找出表定义是否是TableDefs集合的成员.

Vad*_*dim 71

不够好吗?

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
Run Code Online (Sandbox Code Playgroud)

  • 如果键的值是对象而不是基元,则这不起作用 - 如果值是对象,则会得到赋值错误(对象引用需要使用"Set"赋值),因此返回"False"甚至如果密钥存在.用obObject(col(key))替换obj = col(key)行来处理对象和原始值. (22认同)
  • 这是一个很好的解决方案,成千上万的人必须重新实现它才有点愚蠢.VB/VBA应该比这更高. (3认同)

Mar*_*old 39

不完全优雅,但我能找到的最好(也是最快)的解决方案是使用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
Run Code Online (Sandbox Code Playgroud)

  • 我不认为这是非优雅的...它是一种尝试捕获的方法,在C++和Java中非常正常,例如我认为迭代整个集合的速度要快得多,因为VB计算了提供的哈希值键,并在哈希表上搜索,而不是在项目的集合中搜索. (9认同)
  • 这个实现不合适:即如果发生#5以外的任何其他错误,它将返回True (3认同)
  • errNumber在这里不是5,它是3265而不是:( ...从这方面来说它不优雅 - 依赖于硬编码的错误代码 (3认同)

Gil*_*gan 22

您最好的选择是迭代集合的成员,看看是否匹配您正在寻找的东西.相信我,我必须多次这样做.

第二个解决方案(更糟糕的是)捕获"Item not in collection"错误,然后设置一个标志,表示该项目不存在.

  • 这真的是唯一的方法吗? (12认同)
  • 说实话,我发现Access本身作为一般的编程平台并不令人满意.但我们必须玩我们处理的牌.:-) (11认同)
  • 也许"正确",但仍然非常不满意.谢谢两位. (5认同)
  • Mark Nold在下面提供的解决方案要优越得多 (4认同)
  • VB6/VBA集合不仅仅是你可以迭代的东西.它还提供可选的密钥访问. (3认同)

Zyg*_*ygD 11

这是一个老问题.我仔细阅读了所有答案和评论,测试了性能解决方案.

我想出了我的环境中最快的选项,当集合包含对象和基元时,它不会失败.

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
Run Code Online (Sandbox Code Playgroud)

此外,该解决方案不依赖于硬编码的错误值.因此参数col As Collection可以被其他一些集合类型变量替换,并且该函数仍然可以工作.例如,在我目前的项目中,我会将其作为col As ListColumns.