VBAには辞書構造がありますか?key <> value array?
VBAには辞書構造がありますか?key <> value array?
回答:
はい。
MSスクリプトランタイム(「Microsoftスクリプトランタイム」)への参照を設定します。@regjoのコメントに従って、[ツール]→[参照]に移動し、[Microsoft Scripting Runtime]のボックスをオンにします。
以下のコードを使用して辞書インスタンスを作成します。
Set dict = CreateObject("Scripting.Dictionary")
または
Dim dict As New Scripting.Dictionary
使用例:
If Not dict.Exists(key) Then
dict.Add key, value
End If
Nothing
使い終わったら、必ず辞書を設定してください。
Set dict = Nothing
keyed
ます。
Dim dict As New Scripting.Dictionary
参考までに、リファレンスなしでを使用することはできません。参照がなければ、CreateObject
このオブジェクトをインスタンス化する遅延バインディングメソッドを使用する必要があります。
VBAにはコレクションオブジェクトがあります。
Dim c As Collection
Set c = New Collection
c.Add "Data1", "Key1"
c.Add "Data2", "Key2"
c.Add "Data3", "Key3"
'Insert data via key into cell A1
Range("A1").Value = c.Item("Key2")
Collection
それは速いですので、ハッシュを使用してオブジェクトを実行するキーベースの検索。
あなたは使うことができます Contains()
関数を、特定のコレクションにキーが含まれているかどうかを確認ます。
Public Function Contains(col As Collection, key As Variant) As Boolean
On Error Resume Next
col(key) ' Just try it. If it fails, Err.Number will be nonzero.
Contains = (Err.Number = 0)
Err.Clear
End Function
2015年6月24日を編集:Contains()
@TWiStErRobのおかげで短くなりました。
2015年9月25日編集:Err.Clear()
@scipilotへの感謝を追加。
ContainsKey
ます。呼び出しだけを読んでいる人は、特定の値が含まれていることを確認するために、呼び出しを混乱させる可能性があります。
出現頻度を含めるのに役立つ追加の辞書の例。
ループの外:
Dim dict As New Scripting.dictionary
Dim MyVar as String
ループ内:
'dictionary
If dict.Exists(MyVar) Then
dict.Item(MyVar) = dict.Item(MyVar) + 1 'increment
Else
dict.Item(MyVar) = 1 'set as 1st occurence
End If
頻度を確認するには:
Dim i As Integer
For i = 0 To dict.Count - 1 ' lower index 0 (instead of 1)
Debug.Print dict.Items(i) & " " & dict.Keys(i)
Next i
オフの構築cjrhの答え、私たちは(私はラベルを使用して好きではない)は、ラベルを必要としない機能が含まれて構築することができます。
Public Function Contains(Col As Collection, Key As String) As Boolean
Contains = True
On Error Resume Next
err.Clear
Col (Key)
If err.Number <> 0 Then
Contains = False
err.Clear
End If
On Error GoTo 0
End Function
私のプロジェクトでは、Collection
動作をのようにするための一連のヘルパー関数を作成しましたDictionary
。それでも再帰的なコレクションが可能です。キーは必須であり、私の実装ではより理にかなっているため、キーが常に最初に来ることに気付くでしょう。私も使っただけString
キー使用しました。必要に応じて元に戻すことができます。
古い値を上書きするため、この名前をsetに変更しました。
Private Sub cSet(ByRef Col As Collection, Key As String, Item As Variant)
If (cHas(Col, Key)) Then Col.Remove Key
Col.Add Array(Key, Item), Key
End Sub
err
を使用set
してオブジェクトを渡し、それを使用せずに変数を渡すため、これらはオブジェクト用です。対象物かどうかはチェックできると思いますが、時間を要しました。
Private Function cGet(ByRef Col As Collection, Key As String) As Variant
If Not cHas(Col, Key) Then Exit Function
On Error Resume Next
err.Clear
Set cGet = Col(Key)(1)
If err.Number = 13 Then
err.Clear
cGet = Col(Key)(1)
End If
On Error GoTo 0
If err.Number <> 0 Then Call err.raise(err.Number, err.Source, err.Description, err.HelpFile, err.HelpContext)
End Function
この投稿の理由...
Public Function cHas(Col As Collection, Key As String) As Boolean
cHas = True
On Error Resume Next
err.Clear
Col (Key)
If err.Number <> 0 Then
cHas = False
err.Clear
End If
On Error GoTo 0
End Function
存在しない場合はスローしません。削除されたことを確認するだけです。
Private Sub cRemove(ByRef Col As Collection, Key As String)
If cHas(Col, Key) Then Col.Remove Key
End Sub
キーの配列を取得します。
Private Function cKeys(ByRef Col As Collection) As String()
Dim Initialized As Boolean
Dim Keys() As String
For Each Item In Col
If Not Initialized Then
ReDim Preserve Keys(0)
Keys(UBound(Keys)) = Item(0)
Initialized = True
Else
ReDim Preserve Keys(UBound(Keys) + 1)
Keys(UBound(Keys)) = Item(0)
End If
Next Item
cKeys = Keys
End Function
何らかの理由で、Excelに追加機能をインストールできない場合、またはインストールしたくない場合は、少なくとも単純な問題に対しては配列も使用できます。WhatIsCapitalとして国の名前を入力すると、関数はその首都を返します。
Sub arrays()
Dim WhatIsCapital As String, Country As Array, Capital As Array, Answer As String
WhatIsCapital = "Sweden"
Country = Array("UK", "Sweden", "Germany", "France")
Capital = Array("London", "Stockholm", "Berlin", "Paris")
For i = 0 To 10
If WhatIsCapital = Country(i) Then Answer = Capital(i)
Next i
Debug.Print Answer
End Sub
Dim
のキーワードを、Country
そしてCapital
必要性が原因の使用にバリアントとして宣言されるようにArray()
、i
宣言する(と場合でなければならないはずOption Explicit
のセットがある)、およびループカウンタは、バインドされたエラーのうちをスローするように起こっている-より安全な値に使用UBound(Country)
しTo
ます。また、Array()
関数は便利なショートカットですが、VBAで配列を宣言する標準的な方法ではないことにも注意してください。
他のすべての人は、Dictionaryクラスのscripting.runtimeバージョンの使用についてすでに述べています。このDLLを使用できない場合は、このバージョンも使用できます。コードに追加するだけです。
https://github.com/VBA-tools/VBA-Dictionary/blob/master/Dictionary.cls
Microsoftのバージョンと同じです。