[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『複数キーのDictionary』(zunzun)
こんにちは
下記に示すようにGからJ列にデータがあります。これを期と名称の2つの条件で集計するマクロを検討しています。
G H I J K L M N O
3 期 名称 個数 金額 期 名称 個数 金額
4 20 AA 2 1000 20 AA 5 1800
5 20 AA 3 800 21 BB 2 1000
6 21 BB 2 1000 22 AA 2 1000
7 22 AA 2 1000
NETを参考に、以下のコードを書き実行しましたが、L、M列でKEYが重なった状態で表示されます。個数と金額は正確に表示出来ています。
L M N O
期 名称 個数 金額
20AA 20AA 5 1800
改善点のヒントを教えていただけないでしょうか?
Dictinaryは、初心者です。
Sub 集計2()
Dim dco_Count As Object
Dim dco_Sum As Object
Dim wRow As Long
Dim wKey As String
Dim varKeys As Variant
Dim var As Variant
Dim i As Long
Worksheets(8).Select
'エクセルの列
Const COL_I_ITEM1 = 7
Const COL_I_ITEM2 = 8
Const COL_I_PRICE = 10
Const COL_O_ITEM1 = 12
Const COL_O_ITEM2 = 13
Const COL_O_CNT = 14
Const COL_O_SUM = 15
'ディクショナリオブジェクトの生成
Set dco_Count = CreateObject("Scripting.Dictionary")
Set dco_Sum = CreateObject("Scripting.Dictionary")
wRow = 4 '入力データ開始行
Do Until Cells(wRow, COL_I_ITEM1).Value = ""
wKey = Cells(wRow, COL_I_ITEM1).Value & vbTab & Cells(wRow, COL_I_ITEM2)
If dco_Count.Exists(wKey) Then
'カウントアップ
dco_Count.Item(wKey) = CLng(dco_Count.Item(wKey)) + 1
'金額加算
dco_Sum.Item(wKey) = CLng(dco_Sum.Item(wKey)) + _
CLng(Cells(wRow, COL_I_PRICE).Value)
Else
'未登録の場合は新規登録
dco_Count.Add wKey, 1
dco_Sum.Add wKey, Cells(wRow, COL_I_PRICE).Value
End If
wRow = wRow + 1
Loop
'キー項目の配列を取得
varKeys = dco_Count.Keys
wRow = 4 '出力データ開始行
'集計項目の表示
For Each var In varKeys
Cells(wRow, COL_O_ITEM1).Value = var
Cells(wRow, COL_O_ITEM2).Value = var
Cells(wRow, COL_O_CNT).Value = dco_Count.Item(var)
Cells(wRow, COL_O_SUM).Value = dco_Sum.Item(var)
wRow = wRow + 1
Next
'ディクショナリオブジェクトの破棄
Set dco_Count = Nothing
Set dco_Sum = Nothing
End Sub
< 使用 Excel:Excel2013、使用 OS:Windows10 >
Dictionary の Item を配列にして出し入れすれば
Sub test()
Dim r As Range, ii As Long, myKey As String, dic As Object, w
Set dic = CreateObject("Scripting.Dictionary")
dic(0) = Application.Index(Range("g3").Resize(, 4), 1, 0)
For Each r In Range("g4", Range("g" & Rows.Count).End(xlUp))
myKey = r.Value & Chr(2) & r(, 2).Value
If Not dic.exists(myKey) Then
ReDim w(1 To 4) '<-配列を用意する
For ii = 1 To 4 '<-Col.GからCol.Jまでを配列に格納
w(ii) = r.Offset(, ii - 1).Value
Next
dic(myKey) = w '<-dictionaryのItemに格納
Else
w = dic(myKey) '<-配列を一旦取り出す
w(3) = w(3) + r.Offset(, 2).Value '<- 個数列を加算
w(4) = w(4) + r.Offset(, 3).Value '<- 金額列を加算
dic(myKey) = w '<-配列を戻す
End If
Next
Range("o3").Resize(dic.Count, 4).Value = Application.Index(dic.items, 0, 0)
End Sub
(seiya) 2017/10/12(木) 12:32
(zunzun) 2017/10/12(木) 13:04
2箇所...
1)
'カウントアップ これは個数の加算でしょ?
dco_Count.Item(wKey) = CLng(dco_Count.Item(wKey)) + Cells(wRow, 9).Value
2)
'未登録の場合は新規登録
dco_Count.Add wKey, Cells(wRow, 9).Value
だと思いますが? (seiya) 2017/10/12(木) 13:26
試してみましたが、期と名称が合体されたままでした。
seiyaさんのコードを勉強してみます。
ありがとうございました。
(zunzun) 2017/10/12(木) 13:44
ああ、そこですか...
Cells(wRow, COL_O_ITEM1).Value = var
Cells(wRow, COL_O_ITEM2).Value = var
を
Cells(wRow, COL_O_ITEM1).resize(,2).Value = split(var,vbtab)
かな?
(seiya) 2017/10/12(木) 13:49
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.