空腹おやじのログと備忘録

VBA(主にExcel)でいろいろな実験的な事とか、Linuxのコマンドとか設定とかについて忘れないように、あれこれと・・・

VBAのDictionary の Key について実験してみた

VBAのDictionaryのKeyには、数値、文字(数字を含む)、オブジェクト等が使えます。
そんな中で、ちょっと気になったことがあったので、実験してみました。

データ型が異なる同一値の数値を指定してみる

データ型が異なる別々の値」をKeyとしてDictionaryに追加した後、それぞれのItemを、「値が同じで、異なるデータ型」のKeyを指定して呼び出してみる。

1.呼び出し検証コード

Public Sub 数値型追加テスト()

    Dim dic As New Dictionary
    Dim v   As Variant

    dic.Add CByte(0), "Byte"
    dic.Add 1, "Integer"
    dic.Add 2&, "Long"
    dic.Add 3@, "Currency"
    dic.Add 4!, "Single"
    dic.Add 5#, "Double"

    For Each v In dic.Keys
        Debug.Print TypeName(v), v
    Next v

    Debug.Print "----- " & "Integer" & " -----"
    Debug.Print dic(0)
    Debug.Print dic(1)
    Debug.Print dic(2)
    Debug.Print dic(3)
    Debug.Print dic(4)
    Debug.Print dic(5)

    Debug.Print "----- " & "Long" & " -----"
    Debug.Print dic(0&)
    Debug.Print dic(1&)
    Debug.Print dic(2&)
    Debug.Print dic(3&)
    Debug.Print dic(4&)
    Debug.Print dic(5&)

    Debug.Print "----- " & "Currency" & " -----"
    Debug.Print dic(0@)
    Debug.Print dic(1@)
    Debug.Print dic(2@)
    Debug.Print dic(3@)
    Debug.Print dic(4@)
    Debug.Print dic(5@)

    Debug.Print "----- " & "Single" & " -----"
    Debug.Print dic(0!)
    Debug.Print dic(1!)
    Debug.Print dic(2!)
    Debug.Print dic(3!)
    Debug.Print dic(4!)
    Debug.Print dic(5!)

    Debug.Print "----- " & "Double" & " -----"
    Debug.Print dic(0#)
    Debug.Print dic(1#)
    Debug.Print dic(2#)
    Debug.Print dic(3#)
    Debug.Print dic(4#)
    Debug.Print dic(5#)

    Debug.Print "----- " & "Type Name" & " -----"
    Debug.Print TypeName(dic.Keys(0))
    Debug.Print TypeName(dic.Keys(1))
    Debug.Print TypeName(dic.Keys(2))
    Debug.Print TypeName(dic.Keys(3))
    Debug.Print TypeName(dic.Keys(4))
    Debug.Print TypeName(dic.Keys(5))

End Sub

実行結果

call 数値型追加テスト
Byte           0 
Integer        1 
Long           2 
Currency       3 
Single         4 
Double         5 
----- Integer -----
Byte
Integer
Long
Currency
Single
Double
----- Long -----
Byte
Integer
Long
Currency
Single
Double
----- Currency -----
Byte
Integer
Long
Currency
Single
Double
----- Single -----
Byte
Integer
Long
Currency
Single
Double
----- Double -----
Byte
Integer
Long
Currency
Single
Double
----- Type Name -----
Byte
Integer
Long
Currency
Single
Double
  • 同一値であれば、データ型が異なっていてもItemを呼び出しできる。
  • 呼び出したItemは、Addした際のデータ型を保持している。

おまけのテスト

Public Sub hoge()

    Dim v1
    Dim v2

    v1 = 10
    v2 = 10&

    Debug.Print v1 = v2
    Debug.Print TypeName(v1) = TypeName(v2)

    Debug.Print 10 = 10&
    Debug.Print TypeName(10) = TypeName(10&)

End Sub

実行結果

call hoge
True
False
True
False

これなら、上のような結果になるのは納得。


2.追加検証コード
データ型が異なる同一値をKeyとしてDictionaryに追加してみる。

Public Sub 数値型追加テスト2()

    Dim dic As New Dictionary
    Dim v   As Variant

    dic.Add CByte(0), "Byte"
    dic.Add 0, "Integer"
    dic.Add 0&, "Long"
    dic.Add 0@, "Currency"
    dic.Add 0!, "Single"
    dic.Add 0#, "Double"

End Sub

実行結果
f:id:Z1000S:20190422215754j:plain
f:id:Z1000S:20190422215819j:plain

  • データ型が異なっていても、値が同一であれば追加はできない。
Nullを指定してみる

検証コード

Public Sub Null追加テスト()

    Dim dic As New Dictionary

    dic.Add Null, "NULL"

    Debug.Print dic.Exists(Null), dic.Item(Null)

End Sub

実行結果

call Null追加テスト
True          NULL
  • NullはKeyとして追加できる。
  • NullがKeyとして存在するか確認できる。
  • Nullをキーとして、Itemを呼び出せる。
空文字列を指定してみる
Public Sub NullString追加テスト()

    Dim dic As New Dictionary

    dic.Add "", "Null String"

    Debug.Print dic.Exists(""), dic.Item("")

End Sub

実行結果

call NullString追加テスト
True          Null String
  • 空文字はKeyとして追加できる。
  • 空文字がKeyとして存在するか確認できる。
  • 空文字をKey指定してItemを呼び出せる。
Binaryを指定してみる

検証コード

Public Sub Binary追加テスト()

    Dim dic As New Dictionary

    dic.Add vbTab, "Tab"
    dic.Add vbCr, "CR"
    dic.Add vbLf, "LF"
    dic.Add vbCrLf, "CRLF"
    dic.Add vbNullChar, "\0"

    Debug.Print dic.Exists(vbTab), dic.Item(vbTab)
    Debug.Print dic.Exists(vbCr), dic.Item(vbCr)
    Debug.Print dic.Exists(vbLf), dic.Item(vbLf)
    Debug.Print dic.Exists(vbCrLf), dic.Item(vbCrLf)
    Debug.Print dic.Exists(vbNullChar), dic.Item(vbNullChar)

End Sub

実行結果

call Binary追加テスト
True          Tab
True          CR
True          LF
True          CRLF
True          \0
  • BinaryはKeyとして追加できる。
  • BinaryがKeyとして存在するか確認できる。
  • BinaryをKey指定してItemを呼び出せる。

テスト後に気が付いたけど、Binaryって、要はByteデータなので、当たり前なのかも。

配列を指定してみる

検証コード

Public Sub 配列追加テスト()

    Dim dic As New Dictionary
    Dim ar11(1)     As Long

    ar11(0) = 11
    ar11(1) = 12

    dic.Add ar11(0), ar11(0) * 10
    dic.Add ar11(1), ar11(1) * 10

    Debug.Print dic.Exists(ar11(0)), dic.Item(ar11(0))
    Debug.Print dic.Exists(ar11(1)), dic.Item(ar11(0))
    Debug.Print dic.Exists(11), dic.Item(11)
    Debug.Print dic.Exists(12), dic.Item(12)


    dic.Add ar11, ar11(0) * 100 + ar11(1) * 100

    Debug.Print dic.Exists(ar11), dic.Item(ar11)

End Sub

実行結果
f:id:Z1000S:20190424210945j:plain
f:id:Z1000S:20190424210959j:plain

  • 配列の要素は、Keyとして追加できる。
  • 配列の要素がKeyとして存在するか確認できる。
  • 配列の要素をKey指定してItemを呼び出せる。
  • 配列は、Keyとして追加できない。