2016-06-24 12 views
3

私のコードには異なるコレクションがあります。オブジェクトの中には(さまざまな種類の)オブジェクトを保持するものもあれば、Longなどの型を持つものもあります。Excel VBAのコレクションにキーが含まれているかどうかを確認する一般的な方法

オブジェクトとオブジェクトの両方で機能するコレクションにキーが含まれているかどうかを確認する方法はありますか?

これまでのところ私は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 

セカンド機能:

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 

二つの機能の理由は、私はロングスのペアを持っているコレクション(関数を渡す場合ContainsObjectが動作するようには思えないということです常にFalseを返します)

PS:最初の機能は、Test or check if sheet exists

から3番目の回答のコピーです。
+0

入力ミスがあるようです。同様に 'CheckForKeyInCollection =(Err.Number = 0)'は 'ContainsLong =(Err.Number = 0) 'でなければなりません。' ContainsObject =(Err.Number = 0) ' – skkakkar

+0

編集ありがとう!すぐに私の問題を説明し解決する答えを受け入れました。他の回答もありがとうございます。解決策もそこにありますが、もう少し微妙です... – user2606240

答えて

9

最初の機能にはVariantを使用してください。 VariantObjectを割り当てることができます。これはエラーではないでしょう。

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に関連しています。

+0

あなたの事実とポイント・ツー・ワンの回答を高く評価して、私はそれに投票しました。 – skkakkar

+0

@skkakkar - 私が同意する 'Dictionary'オブジェクトを使用することをお勧めします。 OPは 'Collection'オブジェクトを使用しており、' Dictionary'に切り替える機会がありません。彼らが言うように、いつも '馬の中流を切り替える'ことはできません: –

2

あなたの投稿の編集中にコメントごとにいくつかタイプミスが修正されました。 あなたの質問に答えて、私は関連する側面をカバーしたいと思います。
コレクションのキーを使用すると、主に3つの利点
を有しているが - 順序が変更された場合、あなたのコードは正しい項目 にアクセスします - あなたは直接全体 コレクションを
を読まずにアイテムにアクセスすることができます - それはあなたを作ることができますコードをより読みやすくする。

*しかし同時に、キーはあなたが

キーを変更することはできません

  • を存在するかどうかをチェックすることはできません コレクション

    • にキーを使用して主に3つの問題があります

    • キーを取得できません。

    Pearsonsの記事では、コレクションのキーは書き込み専用です。コレクションの既存のキーのリストを取得する方法はありません。また、引用された段落を経由: -

    Here, Coll is a Collection object in which we will store multiple CFile objects. The CollKeys Collection is used to store the keys of the CFile objects stored in the Coll Collection. We need this second Collection because the Keys of a Collection are write-only -- there is no way to get a list of existing Keys of a Collection. One of the enhancements provided by CFiles is the ability to retrieve a list of Keys for the Collection.

    Custom Collection Classes

    することは一つの方法は、コレクションのメンバーを反復処理し、あなたが探しているものの一致があるかどうかを確認することであり、他の方法は、キャッチすることですItem not in collectionエラーを表示し、項目が存在しないと言うフラグを設定します。これらのアプローチでは意見が異なりますが、一部の人々はエラーをキャッチするための良い方法ではないと感じている一方で、他のセクションでは、中規模から大規模のコレクションの繰り返しよりも大幅に高速になると感じています。
    エラーを捕捉するメソッドに進むと、エラー番号はエラーの原因によって異なります。エラーをチェックするコードルーチンが必要です。最も単純な方法でそれが可能性があります。彼らは重要と考えるとコレクションオブジェクトに関連付けられている彼らのroutine.Various一般的に発生するエラー番号に含まれたエラー数が異なる様々な専門家によって提案されたルーチンを引く

    'c1 is the collection 
    For i = 1 To c1.Count 
        Debug.Print Err.Number, Err.Description 
        If Err.Number <> 0 Then Err.Clear 
    Next i 
    

    エラーは以下のとおりです。 -

    • Error 5無効なプロシージャ呼び出しまた、 現在のプラットフォームで有効でないプロシージャを呼び出そうとすると、このエラーが発生することがあります。 たとえば、一部の手順は、Microsoft Windowsの場合は 、Macintoshの場合は有効です。
    • error 438「オブジェクトは、オブジェクト がクラスのインスタンスであるこのプロパティまたはメソッドをサポートしていません。このクラスのインスタンスは、そのクラス型定義で定義されたいくつかのプロパティ をサポートしており、これをサポートしていません。
    • Error 457このキーがすでにありますこの collection.Youの要素に関連付けられた既に コレクションの別のメンバーを識別する収集部材のためのキーを指定した。このメンバーのために異なる鍵 を選択する。
    • Error 91オブジェクト変数またはブロック変数set.Thereないと作成するステップは2つです。 オブジェクト変数。最初に オブジェクト変数を宣言する必要があります。次に、Setステートメントを使用してオブジェクト 変数に有効な参照を割り当てる必要があります。有効なオブジェクトをまだ参照していないオブジェクトの変数 を使用しようとしました。
    • Error 450引数が間違っているか、無効なプロパティ が割り当てられています。手順 への呼び出しの引数の数が、なか

    あなたは読み取り専用のプロパティに値を代入しようとした procedure.Ifによって期待される必要な引数の数と同じではありませんでした上記のエラーのエラー番号438は重要であると考えられ、もう1つは5となっています。私は、2008年にMark Noldによって7年前に投稿されたサンプルテストプログラムにFunctionルーチンを組み込んでいますので、ご質問にDetermining whether an object is a member of a collection in VBAを記入してください。

    エラー457のようないくつかのエラーは、プログラムテスト実行時には許可されません。私は、重複したキーデータを入力しようとしましたが、スナップショットに示されているように、プログラムのテスト時にエラーが発生しました。 error 457

    スナップショットに示されているように、取り外した後に正しい出力が表示されています。

    no error

    独立した配列のキー値を格納することなくバニラコレクションとコレクションのキーのリストを取得することはできないかもしれません。これを行う最も簡単な方法は、Microsoft Scripting Runtime &への参照を追加することです。 私はプログラムのキーのリストを取得するために、このアプローチを含んでいます。
    コレクションを作成する際に、キーが2番目のパラメーターであり、一意のストリングでなければなりません。

    私のプログラムの完全なコードはです。

    Sub Generic_key_check() 
        Dim arr As Variant 
        Dim c1 As New Collection 
        Dim dic As Object 
        With Application 
        .ScreenUpdating = False 
        End With 
    
    
        Set dic = CreateObject("Scripting.Dictionary") 
        dic.CompareMode = vbTextCompare 
    
        'Populate the collection 
        c1.Add "sheet1", "sheet1" 
        c1.Add "sheet2", "sheet2" 
        c1.Add "sheet3", "sheet3" 
        c1.Add "sheet4", "sheet4" 
        c1.Add "sheet5", "sheet5" 
        c1.Add 2014001, "Long1" 
        c1.Add 2015001, "Long2" 
        c1.Add 2016001, "Long3" 
        c1.Add 2015002, "Long4" 
        c1.Add 2016002, "Long5" 
    
        'Populate the dictionary 
        dic.Add "sheet1", "sheet1" 
        dic.Add "sheet2", "sheet2" 
        dic.Add "sheet3", "sheet3" 
        dic.Add "sheet4", "sheet4" 
        dic.Add "sheet5", "sheet5" 
        dic.Add "Long1", 2014001 
        dic.Add "Long2", 2015001 
        dic.Add "Long3", 2016001 
        dic.Add "Long4", 2015002 
        dic.Add "Long5", 2016002 
        ' Get a list of key items by Dictionary Method 
        Dim N As Variant 
        For Each N In dic.Keys 
        Debug.Print "Key: " & N, "Value: " & dic.item(N) 
        Next 
        'Test for two types of data whether key exists or not. 
        If InCollection(c1, "Long1") Then 
        'If Exists("Long1", c1) Then 
        Debug.Print "Good" 
    
        Else 
        ' If there is error then print out the error number and its description. 
        Debug.Print Err.Number, Err.Description 
        Debug.Print "Not Good" 
        End If 
        If InCollection(c1, "sheet2") Then 
        Debug.Print "Good" 
    
        Else 
        Debug.Print Err.Number, Err.Description 
        Debug.Print "Not Good" 
        End If 
    
        'Checking whether desired key has populated correctly 
        Debug.Print c1("Sheet1") 
        Debug.Print c1("Long3") 
    
    
    
        'Listing out collection items to check theyexist in the collection. 
        For i = 1 To c1.Count 
        Debug.Print c1.item(i) 
        Next i 
        With Application 
        .ScreenUpdating = True 
        End With 
        Set c1 = Nothing 
    End Sub 
    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 
    

    [イミディエイト]ウィンドウに表示されるプログラムごとの最終出力がスナップショットに表示されています。
    enter image description here

  • +0

    Scripting Runtimeライブラリから 'Dictionary'のアプリケーションを表示するための+1。これは、Excel VBAのデフォルト部分ではないことは残念です。 –

    関連する問題