前提
1か月前からVBAを勉強し、仕事で使用をしています。
自分の至らなさにより、ここ数回こちらで質問させていただいております。今回も1日悩んで解決できず、悔しいのですが質問しました。
以前質問した内容と連動した質問となります。
https://teratail.com/questions/n9z6ktrk2v0403
実現したいこと
データが3つあります(実際にはデータ数は変動します)
また、本来は1つのファイルにデータが約10万件あります。
なので高速化できることが望ましいです。
また、カラム数やカラム名もその時々により変化します。
1ファイル目(wearデータ)
2ファイル目(oralデータ)
IDはユニークとなります。
この3つのデータをジョインし、二次元配列の中に以下のように加工したいです。
加工内容としてはFULL JOINにあたります。
データの持ち方
ユニークなIDのキーとして、以下の値の一次元配列を持っています。
[ "ID", "1", "2", "3", "4", "5", "6", "7"]
また、一次元配列arrsがあります。
arrsの中には、dict型のwear, oral gadgetがそれぞれ代入されています。
dict型のkeyは画像でいうところのA列になり、itemは["ID","性別","年齢"…]という感じで配列となっています。
データスクリプト
vba
1Dim keyArr(7) As Variant 2keyArr(0) = "ID" 3keyArr(1) = "1" 4keyArr(2) = "2" 5keyArr(3) = "3" 6keyArr(4) = "4" 7keyArr(5) = "5" 8keyArr(6) = "6" 9keyArr(7) = "7" 10 11 12Dim a(6) As Variant 13Dim b(6) As Variant 14Dim c(6) As Variant 15Dim d(6) As Variant 16Dim e(6) As Variant 17Dim f(6) As Variant 18Dim g(6) As Variant 19Dim h(6) As Variant 20Dim i(6) As Variant 21Dim j(5) As Variant 22Dim k(5) As Variant 23Dim l(5) As Variant 24Dim m(5) As Variant 25Dim n(5) As Variant 26Dim o(5) As Variant 27 28a(0) = "ID" 29a(1) = "性別" 30a(2) = "年齢" 31a(3) = "肌着" 32a(4) = "ニット" 33a(5) = "シャツ" 34a(6) = "帽子" 35 36b(0) = "1" 37b(1) = "男" 38b(2) = "20" 39b(3) = "1" 40b(4) = "0" 41b(5) = "2" 42b(6) = "1" 43 44c(0) = "2" 45c(1) = "女" 46c(2) = "21" 47c(3) = "1" 48c(4) = "2" 49c(5) = "0" 50c(6) = "1" 51 52d(0) = "3" 53d(1) = "女" 54d(2) = "19" 55d(3) = "1" 56d(4) = "1" 57d(5) = "1" 58d(6) = "" 59 60e(0) = "6" 61e(1) = "男" 62e(2) = "22" 63e(3) = "1" 64e(4) = "1" 65e(5) = "1" 66e(6) = "1" 67 68f(0) = "ID" 69f(1) = "性別" 70f(2) = "年齢" 71f(3) = "化粧水" 72f(4) = "乳液" 73f(5) = "歯ブラシ" 74f(6) = "整髪料" 75 76g(0) = "1" 77g(1) = "男" 78g(2) = "20" 79g(3) = "1" 80g(4) = "0" 81g(5) = "1" 82g(6) = "1" 83 84h(0) = "4" 85h(1) = "女" 86h(2) = "22" 87h(3) = "1" 88h(4) = "1" 89h(5) = "1" 90h(6) = "0" 91 92i(0) = "3" 93i(1) = "女" 94i(2) = "19" 95i(3) = "1" 96i(4) = "1" 97i(5) = "1" 98i(6) = "0" 99 100j(0) = "ID" 101j(1) = "性別" 102j(2) = "年齢" 103j(3) = "PC" 104j(4) = "スマホ" 105j(5) = "モバイルバッテリー" 106 107k(0) = "1" 108k(1) = "男" 109k(2) = "20" 110k(3) = "1" 111k(4) = "1" 112k(5) = "1" 113 114l(0) = "2" 115l(1) = "女" 116l(2) = "21" 117l(3) = "1" 118l(4) = "1" 119l(5) = "1" 120 121m(0) = "5" 122m(1) = "男" 123m(2) = "19" 124m(3) = "1" 125m(4) = "1" 126m(5) = "" 127 128n(0) = "6" 129n(1) = "男" 130n(2) = "22" 131n(3) = "1" 132n(4) = "1" 133n(5) = "1" 134 135o(0) = "7" 136o(1) = "女" 137o(2) = "20" 138o(3) = "1" 139o(4) = "1" 140o(5) = "1" 141 142 143 144 145Dim wear As Object 146Set wear = CreateObject("Scripting.Dictionary") 147wear.Add "1", a 148wear.Add "2", b 149wear.Add "3", c 150wear.Add "6", d 151 152Dim oral As Object 153Set oral = CreateObject("Scripting.Dictionary") 154oral.Add "1", e 155oral.Add "4", f 156oral.Add "3", g 157 158Dim gadget As Object 159Set gadget = CreateObject("Scripting.Dictionary") 160gadget.Add "1", h 161gadget.Add "2", i 162gadget.Add "5", j 163gadget.Add "6", k 164gadget.Add "7", l 165 166Dim arrs(2) As Variant 167Set arrs(0) = wear 168Set arrs(1) = oral 169Set arrs(2) = gadget 170
該当のソースコード
vba
1 2' ジョインする為の土台となるテンプレート1列分だけ作成(ID) 3Dim keyNum As Long 4keyNum = UBound(keyArr, 1) 5Dim template As Variant 6ReDim template(keyNum, 0) 7Dim keyCnt As Long 8 9For keyCnt = 0 To keyNum 10 template(keyCnt, 0) = keyArr(keyCnt) 11Next 12 13'arrsに格納されているdict型のデータをループさせる 14Dim fileNum, file As Integer 15fileNum = UBound(arrs, 1) 16For file = 0 To fileNum 17 18 19' マージしていく 20 Dim varItems As Variant 21 Dim varItem As Variant 22 Dim columnNum, iDel, varItemsNum As Integer 23 Dim iNum, kNum As Long 24 Dim ce As Variant 25 Dim num, jNum As Long 26 Dim addArr As Variant 27 Dim temp As Variant 28 29 varItems = arrs(fileNum).Items 30 varItemsNum = UBound(varItems) 31 32 33 34'ジョインする為にtemplateを拡張 35 varItem = varItems(0) 36 '削除したい項目に次の項目を入力していく 37 For iDel = 0 To UBound(varItem) - 1 38 varItem(iDel) = varItem(iDel + 1) 39 Next 40 '配列を1つだけ小さくする 41 ReDim Preserve varItem(UBound(varItem) - 1) 42 ReDim Preserve varItem(1 To UBound(varItem) + 1) 43 44 columnNum = UBound(varItem) - 1 45 ReDim Preserve template(keyNum, columnNum) 46 47 48' データを貼り付けていく 49 iNum = 1 50 jNum = 0 51 kNum = 0 52 For kNum = 0 To UBound(template, 2) 53 If arrs(0).Exists(template(kNum, 0)) Then 54 For Each ce In varItems(0) 55 If jNum = 0 Or jNum = 1 Then 56 jNum = jNum + 1 57 Else 58 template(kNum, iNum) = ce 59 iNum = iNum + 1 60 End If 61 Next 62 63 Else 64 For num = 1 To columnNum 65 template(kNum, num) = "" 66 num = num + 1 67 Next 68 End If 69 iNum = 1 70 jNum = 0 71 72 Next 73 Next 74 75 76
理解が難しいこと
ループを回しすぎて、頭がこんがらがってしまいました。
1つ1つ切り分けて考えてみたのですが、それでも解決できませんでした。複雑に考えすぎてしまっているのかもしれないです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/10/29 14:04 編集
2022/10/29 13:55
2022/10/29 15:16
2022/10/29 16:10 編集
2022/11/01 02:57