67

オブジェクトが VBA のコレクションのメンバーであるかどうかを判断するにはどうすればよいですか?

具体的には、テーブル定義がTableDefsコレクションのメンバーであるかどうかを確認する必要があります。

4

15 に答える 15

40

正確にはエレガントではありませんが、私が見つけた最良の (そして最も速い) 解決策は、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
于 2008-10-20T14:56:34.660 に答える
27

あなたの最善の策は、コレクションのメンバーを反復処理して、探しているものと一致するものがあるかどうかを確認することです。私はこれを何度もしなければならなかったと信じてください。

2 番目の解決策 (さらに悪い方法) は、「アイテムがコレクションにありません」というエラーをキャッチし、アイテムが存在しないことを示すフラグを設定することです。

于 2008-09-26T05:00:26.883 に答える
2

コレクションを反復処理するためのマイクロソフトのソリューションと混合した上記の提案からこのソリューションを作成しました。

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
    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
于 2012-11-23T16:36:51.617 に答える
2

あなたの特定のケース(TableDefs)では、コレクションを繰り返し処理して名前を確認するのが良い方法です。コレクションのキー (Name) はコレクション内のクラスのプロパティであるため、これで問題ありません。

しかし、VBA コレクションの一般的なケースでは、キーはコレクション内のオブジェクトの一部であるとは限りません (たとえば、コレクション内のオブジェクトとは関係のないキーを使用して、コレクションを辞書として使用することができます)。この場合、アイテムにアクセスしてエラーをキャッチするしかありません。

于 2008-09-26T17:50:28.237 に答える
1

コレクション内のアイテムがオブジェクトではなく配列である場合は、追加の調整が必要です。それ以外はうまくいきました。

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

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

于 2012-02-29T10:34:32.210 に答える
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()
    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
于 2014-02-06T10:03:56.600 に答える
-1

私はこのようにしました.Vadimsコードのバリエーションですが、私にはもう少し読みやすいです:

' 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
于 2015-07-16T14:52:31.063 に答える