返回列表 上一主題 發帖

請教資料彙整問題

本帖最後由 Andy2483 於 2022-10-17 13:53 編輯

謝謝 Hsieh 前輩
謝謝 n7822123 前輩
以下心得註解,懇請前輩們指正與指導!
Option Explicit
Sub TEST()
Dim Arr, Brr, C&, i&, R&, T, Y, Z, Q
Set Y = CreateObject("Scripting.Dictionary")
Sheets("Sheet5").Cells = ""
'↑令 工作表 "Sheet5" 所有儲存個都是空字元
''''''''''''''''''''''''''''''''''''''''''''''''''''''

With Sheets("Sheet1")
   Set Brr = .[A1].CurrentRegion
  '↑令 Brr是 [A1]相鄰非空格所串連起來的儲存格,擴展到方正區域的最小範圍儲存格
   C = .[A1].End(xlToRight).Column
   '↑令C是此表的欄數
   R = .[A1].End(xlDown).Row
   '↑令R是此表的列數
End With
For i = 1 To R
'↑設迴圈把一維陣列倒入字典裡當item
   T = Brr(i, 1)
   Q = Brr(i, 2)
   Arr = Brr(i, 1).Resize(, C)
   Arr = Application.Transpose(Application.Transpose(Arr))
   Y(T & "|" & Q) = Arr
   '↑令此KEY的ITEM是Arr一維陣列
Next
With Sheet5
   .[A1].Resize(Y.Count, C) = Application.Transpose(Application.Transpose(Y.items))
   '↑把Y字典的一維陣列ITEM值從[A1]開始貼入
End With
''''''''''''''''''''''''''''''''''''''''''''''''''''''
With Sheets("Sheet2")
   Set Brr = .Range(.[D1], .[A1].End(xlDown))
   C = .[A1].End(xlToRight).Column - 2
   R = .[A1].End(xlDown).Row
End With
For Each Z In Y.KEYS
'↑設迴圈把item的一維陣列改變陣列大小
'這裡很重要!
'因為如果最後轉置貼上時!字典ITEM的集合不是方正的
'就沒辦法轉置貼上

   Y(Z) = Array("", "")
Next
For i = 1 To R
'↑設迴圈把一維陣列倒入字典裡當item
   T = Brr(i, 1)
   Q = Brr(i, 2)
   Arr = Brr(i, 3).Resize(, C)
   Arr = Application.Transpose(Application.Transpose(Arr))
   If Y.Exists(T & "|" & Q) Then
   '↑如果組合字串在字典裡有!
      Y(T & "|" & Q) = Arr
      '↑條件成立就令此KEY的ITEM是Arr一維陣列
   End If
Next
With Sheet5
   .[I1].Resize(Y.Count, C) = Application.Transpose(Application.Transpose(Y.items))
   '↑把Y字典的一維陣列ITEM值從[I1]開始貼入
End With
''''''''''''''''''''''''''''''''''''''''''''''''''''''
With Sheets("Sheet3")
   Set Brr = .Range(.[K1], .[A1].End(xlDown))
   C = .[A1].End(xlToRight).Column
   R = .[A1].End(xlDown).Row
End With
For Each Z In Y.KEYS
'↑設迴圈把item的一維陣列改變陣列大小
'這裡很重要!
'因為如果最後轉置貼上時!字典ITEM的集合不是方正的
'就沒辦法轉置貼上

   Y(Z) = Split(",,,,,,,,,,", ",")
Next
For i = 1 To R
'↑設迴圈把一維陣列倒入字典裡當item
   T = Brr(i, 1)
   Q = Brr(i, 2)
   Arr = Brr(i, 1).Resize(, C) '
   Arr = Application.Transpose(Application.Transpose(Arr))
   If Y.Exists(T & "|" & Q) Then
   '↑如果組合字串在字典裡有!
      Y(T & "|" & Q) = Arr
      '↑條件成立就令此KEY的ITEM是Arr一維陣列
   End If
Next
With Sheet5
   .[K1].Resize(Y.Count, C) = Application.Transpose(Application.Transpose(Y.items))
   '↑把Y字典的一維陣列ITEM值從[K1]開始貼入
End With
''''''''''''''''''''''''''''''''''''''''''''''''''''''
With Sheets("Sheet4")
   Set Brr = .Range(.[R1], .[A1].End(xlDown))
   C = .[A1].End(xlToRight).Column - 2
   R = .[A1].End(xlDown).Row
End With
For Each Z In Y.KEYS
'↑設迴圈把item的一維陣列改變陣列大小
'這裡很重要!
'因為如果最後轉置貼上時!字典ITEM的集合不是方正的
'就沒辦法轉置貼上

   Y(Z) = Split(",,,,,,,,,,,,,,,", ",")
Next
For i = 1 To R
   T = Brr(i, 1)
   Q = Brr(i, 2)
   Arr = Brr(i, 3).Resize(, C)
   Arr = Application.Transpose(Application.Transpose(Arr))
   If Y.Exists(T & "|" & Q) Then
   '↑如果組合字串在字典裡有!
      Y(T & "|" & Q) = Arr
     '↑條件成立就令此KEY的ITEM是Arr一維陣列
   End If
Next
With Sheet5
   .[V1].Resize(Y.Count, C) = Application.Transpose(Application.Transpose(Y.items))
  '↑把Y字典的一維陣列ITEM值從[V1]開始貼入
End With
Set Arr = Nothing
Set Brr = Nothing
Set Y = Nothing
End Sub

TOP

本帖最後由 Andy2483 於 2022-10-17 14:58 編輯

各位前輩好:
後學發現一個很有意思的現象
請教各位前輩這是什麼邏輯?

1.不轉置貼入沒有資料
.[V1].Resize(Y.Count, C) = Y.items

2.轉置一次!資料是橫放
.[V1].Resize(Y.Count, C) = Application.Transpose(Y.items)

3.轉置兩次才會是我們要的資料!
.[V1].Resize(Y.Count, C) = Application.Transpose(Application.Transpose(Y.items))

4.轉置三次同2.
.[V1].Resize(Y.Count, C) = Application.Transpose(Application.Transpose(Application.Transpose(Y.items)))

5.轉置4次又同3.
.[V1].Resize(Y.Count, C) = Application.Transpose(Application.Transpose(Application.Transpose(Application.Transpose(Y.items))))

一開始未轉置的資料是什麼樣的狀態?
為什麼不能直接貼上就好?還要轉置兩次?才是我們要的資料?
謝謝前輩們指點!
大概只有後學這種傻子才會去試轉4次的結果!
哈!

TOP

回復 12# Andy2483
Andy2483前輩好!
小弟才疏學淺,若有解釋不對地方再請其他前輩指正,
是否item是一維陣列,為水平排列,但該範例中對應不止一個item,
所以必須使用兩次的轉置(Transpose)動作,才會變成真正的二維陣列可直接寫入工作表,
該段解釋也是其他前輩留下的足跡,我也還在參透中,在此給你參考....

TOP

本帖最後由 Andy2483 於 2022-10-19 08:11 編輯

回復 13# shuo1125


    謝謝 shuo1125 前輩
很有道理歐!
" item是一維陣列,為水平排列,但該範例中對應不止一個item,"
1.如果 item一維陣列,在空間概念是水平X軸方向排列
2.範例中對應不止一個item,猜item與item應該是空間Z軸方向排列
3.所以先轉置一次讓所有元素併成一個二維陣列,並且繞X軸旋轉90度
4.第二次轉置是繞Z軸
5.如果是第三次轉置也是繞Z軸
6.如果是第四次轉置再是繞Z軸轉回來
7. item轉置為陣列技巧會使用比較重要!真理留給高手解答!
亦師亦友 謝謝

以下是猜測的示意圖!請前輩們指正並指導!謝謝!
每個顏色代表每個  item一維陣列:


併成一個二維陣列!繞X軸旋轉90度:


第二次轉置是繞Z軸:


如果是第三次轉置也是繞Z軸


如果是第四次轉置再是繞Z軸轉回來

TOP

回復 13# shuo1125

以下兩種方式在資料少的時候用! 資料多就用別的方式取代它!
太耗時間了!

1.多次 提取陣列的欄/列:Application.Index()
2.多次 陣列的轉置:Application.Transpose()

TOP

回復 15# Andy2483
Andy2483前輩好!
追求效率對我來說路還太遠...
謝謝您的指導!

TOP

回復 16# shuo1125
分享前輩心得
http://forum.twbts.com/viewthrea ... mp;extra=#pid119783
上列連結裡的學習有測試到
如果要轉置字典的item一維陣列成為二維陣列!必須要所有item一維陣列完整!

Sub TEST()
Workbooks.Add
[A1].Resize(1, 5) = Array("合計", , , , 5000)
End Sub
上述一般的一維陣列寫入儲存格是可以的!

但是放入字典裡的一維陣列裡中間3個空元素卻是不被承認
如下:
TT = "總計"
Y(TT) = Array(TT, , , , V)

雖然沒有辦法執行!

但是以下方式是可以的!
TT = "總計,,,," & V
Y(TT) = Split(TT, ",")
'↑用","分割字串


以下方式也可以
TT = "總計"
Y(TT) = Array(TT, "", "", "", V)

TOP

        靜思自在 : 口說好話、心想好意、身行好事。
返回列表 上一主題