Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 11全般 : Excel 2016)
ディクショナリーについて
投稿日時: 23/10/23 12:04:56
投稿者: aSh998

ディクショナリーでアイテムを複数持たせることは可能でしょうか。
 
CSV読み込みで同じ名称があった場合、そのCSVに持つ2つの金額と個数を格納していきたいと考えております。
(同じ名称のものの場合すでに読み込んでいる場合は加算する)
下記のような表があり、結果に記載の通りの数が算出できるようにしたいです。
 
ご説明がわかりづらく申し訳ございません。
【表】
名称,金額1,金額2,個数
 A ,100, 200 , 5
 B ,50, 100 , 3
 B ,50, 100 , 3
 C ,200, 200 , 4
 
【結果】
A,100,200,5
B,100,200,6
C,200,200,4
 
以下記載している途中のコードです。
   
          Open SourcePath For Input As #FileNum
             Do While Not EOF(FileNum)
          Line Input #FileNum, myRec
 
                'ヘッダ行飛ばして読込
                If lCnt > 0 Then
                    'ダブルクォーテーションクリア
                    sCurrLine = Replace(sCurrLine, Chr(34), "")
                    '行読み込む
                    myStr = Split(myRec, ",") 'カンマ区切
                     
                    '名称をキーとする
                    KeyStr = myStr(1)
                ’dicに存在するか
                    If dic.Exists(KeyStr) Then
                      '登録されている場合
                        '金額・個数を加算する
            (どのようにすれば加算できるか教えていただけないでしょうか。)
              Else
                  '未登録の場合
                  dic.Add KeyStr, Array(myStr(2),myStr(3), myStr(4))
        End If

回答
投稿日時: 23/10/23 13:47:05
投稿者: WinArrow

↓が参考になると思います。
 
https://vba-create.jp/vba-dictionary-array/

回答
投稿日時: 23/10/23 13:51:47
投稿者: Suzu

Dictionary で行わなければならない事情がおありでしょうか?
  
無いのであれば、
ExcelにCSVデータを展開し
「データ」タブ の データツール 内 「統合」を使えば良いと思います。
  
1.A1から CSV のデータを展開後
2.G2あたりを選択した状態で、「データ」タブ の データツール 内 「統合」
3. 集計の方法 合計
  統合元範囲 に CSVの読込データ範囲(タイトルを含まない)を選択し、「追加」
  統合の基準で、「左端列」を選択し OK
  
希望の集計結果を得る事ができます。
  
  
必要なら、タイトル行を追加し、CSVとして保存すれば良いかと。

回答
投稿日時: 23/10/23 14:10:26
投稿者: Suzu

PowerQueryを使うなら
  
1. 新規シートにて、「データ」タブ データの取得と変換 から 「テキストまたは CSVから」
2. ファイル選択ダイアログが表示されますから、目的のCSVを選択し インポート
3. CSVファイル内容が表示されますから、「データの変換」選択
4. PowerQuery エディターが表示されますので ホーム「グループ化」
5. グループ化 の画面が出ますから
   基本/詳細設定 から 詳細設定を選択
   最初のテキストボックスには、名称が選択されているはず
  
   新しい列名    操作   列
-------------------------------------------------
   金額12     合計   金額1
   金額22     合計   金額2
   個数2      合計   個数
      として、OK
6.PowerQueryエディター画面に戻り、希望の数値が得られている事を確認し
  「ファイル」-「閉じて読み込む」にて、Excelに出力されます。
  
必要に応じCSVに出力します。

回答
投稿日時: 23/10/24 07:42:07
投稿者: simple

既にご紹介があったように、dictionaryのItemに配列を使えば可能です。
 
  【参考コード例】

   ...前略....
 Do While Not EOF(FileNum)
      Line Input #FileNum, myRec
      If lCnt > 0 Then        'ヘッダ行は読飛ばす。
          sCurrLine = Replace(myRec, " ", "")
          myArray = Split(sCurrLine, ",")
          key = myArray(0)
          If dic.Exists(key) Then
              ary = dic(key)
              ary(0) = ary(0) + CLng(myArray(1))
              ary(1) = ary(1) + CLng(myArray(2))
              ary(2) = ary(2) + CLng(myArray(3))
              dic(key) = ary
          Else
              dic.Add key, Array(CLng(myArray(1)), CLng(myArray(2)), CLng(myArray(3)))
          End If
      End If
      lCnt = lCnt + 1
  Loop

【補足】
更新するには、Itemをいったん配列に読み込み、加算更新して、改めてItemにセットする必要があります。
つまり、
  dic(key)(0) = dic(key)(0) + CLng(myArray(1))
といった書き方では更新を実現できません。配列として全体をセットする必要があります。これは仕様です。
 
# なお、Itemを配列ではなく、dictinaryにすれば、下記のように直接操作できます。
  しかし、そこまでする必要もないでしょう。
  dic(key)("金額1") = dic(key)("金額1") + CLng(myArray(1))

 
つい最近の下記スレッドも参考になると思います。test2というプロシージャで同様のことを行っています。
https://www.moug.net/faq/viewtopic.php?t=82504
出力の方法なども参考になるでしょう。
 
【まとめ】
質問にはお答えしましたが、
既に指摘いただいているように、dictionaryに余りこだわらず他の方法も含め幅広く検討して下さい。
dictionariでゴリゴリ書くのはメンテナンス性も低いですし、余りお薦めしません。

投稿日時: 23/10/24 08:35:08
投稿者: aSh998

みなさま
代替案などいろいろご教示いただきありがとうございます!
とても参考になり、解決できました。