派遣事務員の迷走

派遣事務員コロ子。会社の犬。顔出しNG。常に迷走している。

VBA Dictionaryオブジェクトのアイテムが複数欲しい(アイテム配列編)

こんにちは。
派犬事務員のコロ子です。

「Dictionaryオブジェクトのアイテムが複数欲しい!」場合、アイテムを配列にする方法が分かった。


1回目(クラス編)
koroko.hatenablog.com

2回目(Dictionaryオブジェクト配列編)
koroko.hatenablog.com

アイテムを配列にする

Dictionaryオブジェクトのアイテムに配列をいれてみたところ、早速つまずいた。
アイテムに配列をセットして、配列の0番目を書き換えたい。

Sub Sample()

Dim dic As Dictionary
Set dic = New Dictionary

dic.Add "test", Array(10, 20, 30)
dic("test")(0) = 100

Debug.Print dic("test")(0)
Debug.Print dic("test")(1)
Debug.Print dic("test")(2)

End Sub

イミディエイトウインドウ

 10 
 20 
 30

dic("test")(0)に100を入れたはずなのに、なぜか10のまま・・・。
どうやらアイテムに入れた配列を書き換えるには、一度外に出して編集して、再度格納する必要があるらしい。

Dim dic As Dictionary
Set dic = New Dictionary

dic.Add "test", Array(10, 20, 30)
dic("test") = Array(100, 200, 300)

Debug.Print dic("test")(0)
Debug.Print dic("test")(1)
Debug.Print dic("test")(2)

イミディエイトウインドウ

 100 
 200 
 300

おお!できた!
しかし、こんなの絶対に分からないよー。どこが間違っているか分からなくて相当悩んだ。(もちろん自力解決できずにノンプロ研で教えてもらった)
理由は「参照してる時は配列のコピーが取得されていて、更新ができないのだと思われる」とのこと。この辺は理解できないので「アイテムの配列はまるごと入れ替える」と覚えよう。

やり方が分かったので、前回の表で集計してみよう。

f:id:SNegishi:20210328151846p:plain

この表で会社ごとに各商品の金額を合計する。

キー:社名
アイテム(0):商品A
アイテム(1):商品B
アイテム(2):商品C

Enum 項目名
    en社名 = 1
    en商品A
    en商品B
    en商品C
End Enum

Sub TEST()
Dim arr() As Long

Dim dic As Dictionary
Set dic = New Dictionary
Dim i As Long

For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row

    Dim dickey As String
    dickey = Cells(i, en社名).Value
    
    If dic.Exists(dickey) Then
    
        Dim sampleA As Long
        Dim sampleB As Long
        Dim sampleC As Long
        
        'アイテムが配列の場合は一度外に出して計算し、再度格納する
        sampleA = dic(dickey)(0) + Cells(i, en商品A)
        sampleB = dic(dickey)(1) + Cells(i, en商品B)
        sampleC = dic(dickey)(2) + Cells(i, en商品C)

        dic(dickey) = Array(sampleA, sampleB, sampleC)
        
    Else

        dic.Add dickey, Array(Cells(i, en商品A), Cells(i, en商品B), Cells(i, en商品C))
        
    End If


Next i

'確認
Dim buf As Variant
For Each buf In dic.Keys

    Debug.Print dic(buf)(0), dic(buf)(1), dic(buf)(2)

Next
End Sub

もしかしたら、この方法が一番すっきりして分かりやすいかも!

Infomentさん、ExcelVBAerさん、Tanaka_Hiroakiさん、みなさんどうもありがとうございました!