web-dev-qa-db-ja.com

キーがExcel VBAのコレクションにあるかどうかを確認する一般的な方法

コードに異なるコレクションがあります。オブジェクトの中には(さまざまな種類の)オブジェクトを保持するものと、その中にタイプ(Longなど)を持つものがあります。

タイプだけでなくオブジェクトに対しても機能するキーがコレクションに含まれているかどうかを確認する方法はありますか?

これまでのところ、2つの機能があります。

最初の機能:

Private Function ContainsObject(objCollection As Object, strName As String) As Boolean
    Dim o As Object
    On Error Resume Next
    Set o = objCollection(strName)
    ContainsObject = (Err.Number = 0)
    Err.Clear
End Function

2番目の機能:

Private Function ContainsLong(AllItems As Collection, TheKey As String) As Boolean
    Dim TheValue As Long
    On Error Resume Next
    TheValue = AllItems.Item(TheKey)
    ContainsLong = (Err.Number = 0)
    Err.Clear
End Function

2つの関数の理由は、Longsのペアを持つコレクションを渡すと、ContainsObjectが機能しないように見えるためです(関数は常にFalseを返します)。

追伸:最初の機能は、 シートが存在するかどうかをテストまたは確認する

10
user2606240

最初の関数でVariantを使用する必要があります。 ObjectVariantに割り当てることができます。これはエラーになりません:

Sub Test()
    Dim var As Variant
    Dim obj As Object
    Set obj = Application
    var = Application
    Debug.Print var
End Sub

しかし、これはType Mismatchコンパイルエラー、つまりLongObjectに割り当てようとしています:

Sub Test()
    Dim obj As Object
    Dim lng As Long
    lng = 3
    Set obj = lng
End Sub

そのため、Collectionキーが有効かどうかを確認するための汎用関数(コードの行に沿った)には、次を使用できます。

Function HasKey(coll As Collection, strKey As String) As Boolean
    Dim var As Variant
    On Error Resume Next
    var = coll(strKey)
    HasKey = (Err.Number = 0)
    Err.Clear
End Function

テストコード:

Sub Test()
    Dim coll1 As New Collection
    coll1.Add Item:=Sheet1.Range("A1"), Key:="1"
    coll1.Add Item:=Sheet1.Range("A2"), Key:="2"
    Debug.Print HasKey(coll1, "1")

    Dim coll2 As New Collection
    coll2.Add Item:=1, Key:="1"
    coll2.Add Item:=2, Key:="2"
    Debug.Print HasKey(coll2, "1")
End Sub

これに関する [〜#〜] msdn [〜#〜] に関する有用な記事があります。コンテキストはVB6ですが、VBAに関連しています。

13
Robin Mackenzie

使徒は彼らの答えでほとんど正しいです。 Robinの答えは汎用オブジェクトでは機能しませんが、ExcelのRangeオブジェクトはセルの値を返すため、書かれたとおりに機能します。私は、使徒がIsObjectを使用するのが大好きです(主に、これも私が理解したものだからです)。ただし、コードは少し複雑すぎます。

キーがコレクションに存在する場合、IsObjectはバリアントをTrueまたはFalseに設定します。そうでない場合、エラーは無視され、バリアントは空のままになります。

Function HasKey(col As Collection, Key As String) As Boolean
    Dim v As Variant
  On Error Resume Next
    v = IsObject(col.Item(Key))
    HasKey = Not IsEmpty(v)
End Function
1
PaulE

コレクションにプリミティブ型ではなくオブジェクトが含まれる場合、Robinのメソッドは失敗します。これらのオブジェクトは、Setを使用して割り当てる必要があるためです。ここに小さな調整があります:

'Test if a key is available in a collection
Public Function HasKey(coll As Collection, strKey As String) As Boolean
    On Error GoTo IsMissingError
        Dim val As Variant
'        val = coll(strKey)
        HasKey = IsObject(coll(strKey))
        HasKey = True
        On Error GoTo 0
        Exit Function
IsMissingError:
        HasKey = False
        On Error GoTo 0
End Function
0
Apostle