VBAは辞書構造を持っていますか?キー<>値の配列が好きですか?
はい。
MS Scripting runtime( 'Microsoft Scripting Runtime')への参照を設定します。 @ 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
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日編集:@TWiStErRobのおかげでContains()
が短くなりました。
2015年9月25日編集:@scipilotのおかげでErr.Clear()
を追加しました。
VBAには辞書の内部実装はありませんが、VBAからはMS Scripting Runtime Libraryの辞書オブジェクトを使用できます。
Dim d
Set d = CreateObject("Scripting.Dictionary")
d.Add "a", "aaa"
d.Add "b", "bbb"
d.Add "c", "ccc"
If d.Exists("c") Then
MsgBox d("c")
End If
出現頻度を含めるのに役立つ追加の辞書の例。
ループの外側:
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's answer 、ラベルを必要としないContains関数を構築することができます(ラベルを使うのは嫌いです)。
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
のように動作させるためのヘルパー関数のセットを書きました。それはまだ再帰的なコレクションを可能にします。 Keyは必須であり、私の実装ではより理にかなっているので、Keyが常に最初に来ることに気付くでしょう。私も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
他のすべての人はすでにscripting.runtimeバージョンのDictionaryクラスの使用について言及しています。このDLLを使用できない場合は、このバージョンも使用できます。単にコードに追加してください。
https://github.com/VBA-tools/VBA-Dictionary/blob/master/Dictionary.cls
マイクロソフトのバージョンと同じです。