返回列表 上一主題 發帖

請教資料彙整問題

回復 2# Hsieh


    謝謝前輩
太厲害了!後學覺得很難!
後學在此帖學到很多知識!
將心得在此註解一下
如有冒犯請見諒!也懇請前輩指正並指導!

Sub Ex_Hsieh()
Dim Sh As Worksheet, Ar(), A As Range, B As Range, C As Range, s&, i%
'↑宣告變數

Set d = CreateObject("Scripting.Dictionary")
'↑令d 是字典

Set d1 = CreateObject("Scripting.Dictionary")
'↑令d1 是字典

For Each Sh In Sheets(Array("Sheet1", "Sheet2", "Sheet3", "Sheet4"))
'↑設外迴圈,令 Sh 是4個工作表之一,順著跑

   With Sh
   '↑以下關於Sh 工作表的程序
   
      Set C = IIf(i = 0 Or i = 2, .[A1], .[C1])
      '↑令C儲存格物件變數:如果i這變數是0或2, C儲存格=Sh的[A1]儲存格
      ',如果i這變數不是0或2, C儲存格=Sh的[C1]儲存格

      
      For Each A In .Range(C, .[IV1].End(xlToLeft))
      '↑設中迴圈,令A 儲存格物件變數是??
      '當i=0(初始值):C是[A1]儲存格,.[IV1].End(xlToLeft)是第一列最左邊的儲存格
      '所以A 是 Sheet1 的[A1:H1]的儲存格之一

      
         ReDim Preserve Ar(s)
         '↑調整Ar陣列大小,保留陣列內部資料
         '一開始Ar 是一維陣列,s初始值是0,Ar(0) 是沒有資料

         
         Ar(s) = A.Value
         '↑令Ar是標題列的值
         
         s = s + 1
         '↑令累加1,讓Ar陣列往右 排入標題列的值
         
         DDD = .Range(A.Offset(1, 0), .Cells(65536, A.Column).End(xlUp)).Address
         For Each B In .Range(A.Offset(1, 0), .Cells(65536, A.Column).End(xlUp))
         '↑設內迴圈,令 B儲存格物件變數:A標題列格偏下1格到 當欄的最後一格
         '當i=0(初始值);Sh=Sheet1;A=[A1];B=[A2:A105]
         '所以 B Sheet1 的[A2:A105]的儲存格之一

         
            If i = 0 Then
            '↑如果i是初始值0,也就是工作表是 Sheet1 時
            '目的是要收集標題欄兩欄的值與 日期&股代號&標題列格 拚字串的key,Item是 CreditMoney欄值

            
               d1(.Cells(B.Row, 1) & .Cells(B.Row, 2)) = Array(.Cells(B.Row, 1), .Cells(B.Row, 2))
               '↑條件成立時 d1字典裝入 日期&股代號 拚字串的 key ,Item是朗元素的一維陣列 日期;股代號
               
               d(.Cells(B.Row, 1) & .Cells(B.Row, 2) & A) = B.Value
               '↑條件成立時 d字典裝入 日期&股代號&標題列格 拚字串的key,Item是 CreditMoney欄值
               
               ElseIf d1.exists(.Cells(B.Row, 1) & .Cells(B.Row, 2)) = True Then
               '↑如果i不是是初始值0:工作表不是 Sheet1 時
               ',而且 d1字典裡有 日期&股代號 拚字串的 key時

                  
                  d(.Cells(B.Row, 1) & .Cells(B.Row, 2) & A) = B.Value
                  '↑條件成立時 d字典裝入 日期&股代號&標題列格 拚字串的key,Item是 CreditMoney欄值
                  
            End If
         Next
      Next
      i = i + 1
   End With
Next
With Sheet5
'↑以下關於 第5個工作表的程序

   .Cells = ""
   '↑令所有儲存個都是空字元
   
   .[A1].Resize(, s) = Ar
   '↑把收集到的Ar標題一維陣列從[A1]開始的儲存格放進值
   
   r = d1.Count
   '↑令r 是d1字典裡元素數量104
   
   .[A2].Resize(d1.Count, 2) = Application.Transpose(Application.Transpose(d1.items))
   '↑把收集到d1字典的item(兩欄標題) 從[A2]開始的儲存格放進值
   
   For Each C In .Range(.[C1], .[IV1].End(xlToLeft))
   '↑設外迴圈令 C儲存格物件變數是 Sheet5 的[C1:AK1]的儲存格之一
   '也就是結果表的標提列儲存格

      
      For Each A In C.Offset(1, 0).Resize(d1.Count, 1)
      '↑設內迴圈令 A儲存格物件變數是 C標題列儲存格偏下一格開始,
      '往下匡列 (d1字典裡元素數量) 的儲存格 104格 的儲存格之一

      
         A = d(.Cells(A.Row, 1) & .Cells(A.Row, 2) & C)
         '↑用兩標題欄兩格值與標題列格拚的字串當key,
         '調出d字典裡的Item 值放到儲存格理

         
      Next
   Next
End With
End Sub

TOP

回復 2# Hsieh

謝謝前輩分享 把字典中的item一維陣列 轉至貼入工作表
D1(.Cells(B.Row, 1) & .Cells(B.Row, 2)) = Array(.Cells(B.Row, 1), .Cells(B.Row, 2))
~~~
.[A2].Resize(d1.Count, 2) = Application.Transpose(Application.Transpose(d1.items))
這很實用!
謝謝!

TOP

各位前輩好
後學今天運用了兩主題的重要技巧,拼湊出下列範例
http://forum.twbts.com/thread-22560-1-1.html
與本主題
http://forum.twbts.com/thread-513-1-1.html
Book1_20001017_7.zip (33.21 KB)
懇請前輩們指正與指導! 謝謝
執行前:


執行後:

TOP

本帖最後由 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

本帖最後由 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

回復 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

        靜思自在 : 有願放在心裡,沒有身體力行,正如耕田不播種,皆是空過因緣。
返回列表 上一主題