プロが教えるわが家の防犯対策術!

いつもお世話になっております
下記は以前教えて頂いたコードですが
こちらを利用してさらに多段配列は可能でしょうか。
添付ファイルのようにやりたいのですが。
さすがに無理でしょうか。
①シートは商品ごとあります。ばなな みかん ぶどう りんご
②サイズが S M SS L あります。

例)シート ばなな
  購入月 昇順です
  あとはサイズごとわかれていれば
  よいのですが。


Dim myDic As Object
Dim r As Range, r2 As Range
Dim key1, key2, mon As String

Set myDic = CreateObject("Scripting.Dictionary")

With ActiveSheet
For Each r In .Range("A2", .Cells(Rows.Count, "A").End(xlUp))

If Not myDic.Exists(r.Value) Then myDic.Add r.Value, _
CreateObject("Scripting.Dictionary")

mon = Month(r.Range("B1").Value) & "月"

If Not myDic(r.Value).Exists(mon) Then myDic(r.Value).Add mon, _
CreateObject("System.Collections.ArrayList")

myDic(r.Value)(mon).Add (r.Range("C1:E1").Value)

Next
End With

For Each key1 In myDic.Keys
With Worksheets(key1)
Set r2 = .Range("A2")
For Each key2 In myDic(key1).Keys

r2.Value = key2
r2.Offset(, 1).Resize(myDic(key1)(key2).Count, 3).Value = _
Application.Transpose(Application.Transpose(myDic(key1)(key2).ToArray()))
Set r2 = r2.Offset(5)

Next
End With
Next

Set myDic = Nothing
Set r2 = Nothing

これを利用してもう一つ多段階にすることは可能でしょうか
わたしなりにやりましたが
いろいろ試しましたがどこをどうすれば
よいのか答えがでませんです。
おしえてくれませんでしょうか
下記のコードはだめです

With ActiveSheet
For Each r In .Range("A2", .Cells(Rows.Count, "A").End(xlUp))

If Not Dic.Exists(r.Value) Then _
Dic.Add r.Value, CreateObject("Scripting.Dictionary")
Size = r.Range("B1").Value

If Not Dic(r.Value).Exists(Size) Then _
Dic(r.Value).Add Size, CreateObject("System.Collections.ArrayList")
Dic(r.Value)(Size).Add (r.Range("C1").Value)

If Not Dic(r.Value)(Size).Exists(mon) Then _
Dic(r.Value)(Size)(mon).Add Size, CreateObject("System.Collections.ArrayList")
Dic(r.Value)(mon).Add (r.Range("C1").Value)

Next
End With

「ジャグ配列」の質問画像

質問者からの補足コメント

  • うれしい

    データ的に既に並べ替える必要がないです。
    普通にやるとしたら1・2番目がDictionary、3番目にArrayList
    がんばってやれるだけやってみます

    No.1の回答に寄せられた補足コメントです。 補足日時:2020/05/30 18:57
  • めぐみん様
    頂戴しました、コードに
    With Worksheets(key1)   ------------------ここの部分
    を付け加えました。
    ただ、おもいどおりにならないのがあります。
    画像添付のように日付のとなりの列に金額
    を表示させたいです。
    Dic(r.Value)(r.Range("B1").Value).Add (r.Range("C1:D1").Value) '-------------ここの部分
    でやっても表示されないのです。
    2回にわけます。文字数の制限です。

    「ジャグ配列」の補足画像2
    No.2の回答に寄せられた補足コメントです。 補足日時:2020/05/31 16:38
  • すみません。コードです。もう一回です。
    For Each r In Range("A2", Cells(Rows.Count, "A").End(xlUp))
    If Not Dic.Exists(r.Value) Then _
    Dic.Add r.Value, CreateObject("Scripting.Dictionary")

    If Not Dic(r.Value).Exists(r.Range("B1").Value) Then _
    Dic(r.Value).Add r.Range("B1").Value, _
    CreateObject("System.Collections.ArrayList")
    Dic(r.Value)(r.Range("B1").Value).Add (r.Range("C1:D1").Value) '-------------ここの部分
    Next

      補足日時:2020/05/31 16:39
  • うーん・・・

    For Each key1 In Dic.keys
    With Worksheets(key1)
    Set rr = .Range("A1")
    rr.Value = key1

    For Each key2 In Dic(key1).keys
    Set rr = rr.Offset(1)
    rr.Offset(, 1).Value = key2
    Set rr = rr.Offset(1)

    For i = 0 To Dic(key1)(key2).Count - 1
    rr.Offset(i, 2).Value = Dic(key1)(key2)(i)
    Next
    Set rr = rr.Offset(Dic(key1)(key2).Count - 1)
    Next
    Set rr = rr.Offset(1)
    End With
    Next
    Set Dic = Nothing
    よろしくお願いいたします。

      補足日時:2020/05/31 16:40
  • うーん・・・

    いつも有難うございます。
    Dic(r.Value)(r.Range("B1").Value).Add (r.Range("C1").Resize(, 2).Value)
    だけど上のコードで試したのですが、表示されませんでした。金額が

    No.3の回答に寄せられた補足コメントです。 補足日時:2020/05/31 18:15

A 回答 (4件)

お疲れ様です。



結構ほしいですね。
1番目にDictionary、2・3番目にArrayListを用いられているようですけど、普通にやるとしたら1・2番目がDictionary、3番目にArrayListでしょうね。
ArrayListは通常の配列と似てて書き込んだ順に1次元的に値等を格納するのであって、今回のサイズ毎による値と言うKeyとItemを対で格納する事は出来ません。
強引に1つ目のDictionaryでKeyを”月とサイズ”で連結するってのは良いのかもしれませんけど。

ただここで引っかかるとしたら、

>購入月 昇順です

でしょうか。
データ的に既に並べ替える必要がないって事ならば上記で宜しいのでしょうけど、データの月がバラバラになってて書き出す際にはそれを並べ替える必要があるって事ならもう一工夫必要かもです。

事実データは前者と後者のどちらなのでしょう?
この回答への補足あり
    • good
    • 0
この回答へのお礼

いつもお世話になっております
わたしなりに考えました。
購入月 昇順です --->はあらかじめSortで並び替えることにしました。
そして以前ジャグ配列もどきというのを頂戴していたのを
保存していました。それにwith worksheets(key1)を
書き出しコードにいれて最初は間違ってた場所にいれて
大変でしたが落ち着いてひとつひとつやったらできましたが、
keyがずれていたのですこしまた考えます。

お礼日時:2020/05/30 20:57

No.1です。



最初の Set ~ Dictionary を入れてなかった。
これを入れると
1~3番目がDictionary
4番目がArrayList
ですね。

ただ最初の Dictionary の Key を 商品_納入日_サイズ とすれば、Dictionary ArrayList は1個ずつで出来ます。
Key を吐き出した後で Split を使い分けられた値を上手く使い分けていけば可能かな?と。
前回そのような使い方をすればわかりやすかったのかもですね。(他の回答者でも稀にそう使ってますし)
この回答への補足あり
    • good
    • 0

えっと。


補足の画像の右側(列で行がズレている)表を『サイズ』『日付』『金額』で揃えれば良いのでしょうか?
ちなみに『金額』が表示されないのは表示させるために行うセル範囲の拡張 Resize(~) が使われていないだけですね。
ダミーデータ作成に少々お待ちください。
この回答への補足あり
    • good
    • 0

For i = 0 To Dic(key1)(key2).Count - 1


rr.Offset(i, 2).Value = Dic(key1)(key2)(i)
Next

ここで

For i = 0 To Dic(key1)(key2).Count - 1
rr.Offset(i, 2).Resize(, 2).Value = Dic(key1)(key2)(i)
Next

だと思います。

あと

Set rr = rr.Offset(1)
rr.Offset(, 1).Value = key2
Set rr = rr.Offset(1)

この上下の Offset は共に不要では?
頭に ' を付けて試してみるとか?
    • good
    • 0
この回答へのお礼

丸一日中考えてもだめしたのに
ありがとうございました。
このごろできるまでとにかくかきまっくています。
すると少しずつですが納得できるようになりました。
ありがとうございました

Set rr = rr.Offset(1)
rr.Offset(, 1).Value = key2
Set rr = rr.Offset(1)

この上下の Offset は共に不要では?
頭に ' を付けて試してみるとか?
を検証いたします。
ありがとうございました

お礼日時:2020/05/31 18:28

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!