Board logo

標題: [發問] 不規則資料,如何重整..... [打印本頁]

作者: b31978    時間: 2015-7-21 16:48     標題: 不規則資料,如何重整.....

請教各位先進:

如何用vba程式,將資料重整為右側的格式
困難點在於:每日最多5筆,最少為0筆,每筆位置不一致~

尚請不吝提供想法,謝謝~
[attach]21443[/attach][attach]21443[/attach]
作者: lpk187    時間: 2015-7-21 17:43

回復 1# b31978


    試試看,也不知對不對!
  1. Public Sub test()
  2. Dim arr()
  3. aa = Cells(Rows.Count, 10).End(xlUp).Row
  4. xx = WorksheetFunction.CountA(Range("J3:J" & aa))
  5. i = 1
  6. ReDim arr(1 To xx, 1 To 4)
  7. For Each Rng In Range("C3:i" & aa)
  8.     If Rng <> "" Then
  9.         ss = Cells(Rng.Row, 1).MergeArea
  10.         arr(i, 1) = ss(1, 1)
  11.         arr(i, 2) = Cells(2, Rng.Column)
  12.         arr(i, 3) = Rng
  13.         arr(i, 4) = Cells(Rng.Row, 10)
  14.         i = i + 1
  15.     End If
  16. Next
  17. Range("M3").Resize(xx, 4) = arr
  18. End Sub
複製代碼

作者: b31978    時間: 2015-7-22 07:54

回復 2# lpk187

感謝,想了很久,一直沒有有效的思路,謝謝大大~ 感恩:D
作者: GBKEE    時間: 2015-7-22 14:01

回復 3# b31978
試試看
  1. '一般模組程式碼
  2. Option Explicit
  3. Sub Ex()
  4.     Dim Rng As Range, C As Range, S, Ar(), At(), i As Integer
  5.     Set Rng = ActiveSheet.Range("A3")
  6.     Do While Rng <> ""
  7.         With Rng.Offset(, 2).Resize(Rng.MergeArea.Count, 7)
  8.         'Rng.MergeArea 儲存格的合併範圍
  9.         'Rng.MergeArea.Count 合併範圍的Cells總計
  10.             If Application.CountA(.Cells) > 0 Then '.Cells :這 With 物件範圍Range的Cells
  11.                 '工作表函數 CountA 計算範圍內有資料的Cells個數
  12.                 For Each C In .SpecialCells(xlCellTypeConstants)
  13.                     'SpecialCells 特殊儲存格 (xlCellTypeConstants :字串,數字 )
  14.                     ReDim Ar(1 To 4)      '重置陣列
  15.                     Ar(1) = Rng.Value
  16.                     Ar(2) = Cells(2, C.Column)
  17.                     Ar(3) = C
  18.                     Ar(4) = Cells(C.Row, "j")
  19.                     i = i + 1
  20.                     ReDim Preserve At(1 To i)  '重置陣列:Preserve保留原有的元素
  21.                     At(i) = Ar
  22.                 Next
  23.             End If
  24.         End With
  25.         Set Rng = Rng.End(xlDown) '下一個有合併範圍的Range
  26.     Loop
  27.     If i > 0 Then [M3].Resize(i, 4) = Application.Transpose(Application.Transpose(At))
  28. End Sub
複製代碼

作者: b31978    時間: 2015-7-22 18:04

回復 4# GBKEE

謝謝 各位大大的協助,幫了大忙了,謝謝~
作者: t_t7225    時間: 2015-7-23 17:34

本帖最後由 t_t7225 於 2015-7-23 17:36 編輯
For Each Rng In Range("C3:i" & aa)
    If Rng <> "" Then
        ss = Cells(Rng.Row, 1).MergeArea
        arr(i, 1) = ss(1, 1)
        arr(i, 2) = Cells(2, Rng.Column)
        arr(i, 3) = Rng
        arr(i, 4) = Cells(Rng.Row, 10)
        i = i + 1
    End If
Next


想請問b31978大大
ss = Cells(Rng.Row, 1).MergeArea
        arr(i, 1) = ss(1, 1)
這段程式碼ss的意思是什麼?
為什麼可以上面那句ss 下面那句卻可以變成ss(x,y)型式
可否幫小弟解惑一下

不好意思,在問題中衍伸問題
但真的很想知道...
作者: t_t7225    時間: 2015-7-23 17:42

回復 6# t_t7225

另外還想問一下 為什麼arr(i,1)=ss(1,1)
ss(1,1)維持不變卻可以有day1,day2,day3的變化
真的百思不得其解
還麻煩大大解惑

抱歉超過3分鐘來不及編輯...
作者: lpk187    時間: 2015-7-23 20:36

本帖最後由 lpk187 於 2015-7-23 20:42 編輯

回復 7# t_t7225


    ss = Cells(Rng.Row, 1).MergeArea
        arr(i, 1) = ss(1, 1)
這一段正確是寫成
arr(i, 1) =Cells(Rng.Row, 1).MergeArea(1)
.MergeArea為合併儲存格的Value
既然是合併儲存格也就是多個儲存格組成的一個陣列其陣列一般都只有第一格有其Value
ss = Cells(Rng.Row, 1).MergeArea那ss也是MergeArea的陣列,只是方便在區域變數視窗中觀察MergeArea陣列的維數及內容,無其他意義!
ss會變化其實是MergeArea的陣列在變化
作者: t_t7225    時間: 2015-7-23 21:51

回復 8# lpk187


感謝lpk187大大的回覆
知道arr(i,1)=ss
那我就瞭解這段程式碼的意思了

但是唯一還是不解的地方是
ss我當時也是揣測為陣列

但是不明白的地方是ss(1,1)
如果ss為陣列其陣列值應為ss(day1,day2,day3)
那ss(1,1)不是應該固定為‘’day1‘’
ss(2,1)=”day2”這樣才對嗎?
還是這部分我有認知錯誤呢?
作者: lpk187    時間: 2015-7-23 22:12

本帖最後由 lpk187 於 2015-7-23 22:15 編輯

回復 9# t_t7225


    SS只是一個變數,是一個沒有定格子的陣列,每次執行時並不相同
不像arr(1 to 3)這種,而是會像下面例子一樣
把下面代碼執行看看再看區域變數視窗就了解了
Public Sub ex1()
'第一次執行ar
ar = Array("1", "2", "3", "4")
'ar為ar(0)="1",ar(1)= "2" ,ar(2) = "3",ar(3) = "4"
'第二次執行ar
ar = Array("1", "2")
'ar為ar(0)="1",ar(1)= "2"
End Sub
以原來的代碼是跑迴圈的所以執行起來就有點類似上面例子的樣子
作者: t_t7225    時間: 2015-7-24 08:49

回復 10# lpk187

總算了解意思了
謝謝大大精闢的解說
又釐清了更多的觀念了
作者: Andy2483    時間: 2023-12-4 07:55

本帖最後由 Andy2483 於 2023-12-4 08:54 編輯

謝謝論壇,謝謝各位前輩
後學藉此帖練習陣列,學習方案如下,請各位前輩指教
執行前:
[attach]37098[/attach]

執行結果:
[attach]37099[/attach]


Option Explicit
Sub TEST()
Dim Brr, Crr, i&, j%, R&, T$
'↑宣告變數
Brr = Intersect(ActiveSheet.UsedRange, [A:K])
'↑令Brr變數是 裝盛指定儲存格值的二維陣列
ReDim Crr(1 To 1000, 1 To 4)
'↑宣告Crr變數是二維 空陣列
For i = 3 To UBound(Brr)
'↑設順迴圈!i從3到Brr陣列縱向最大索引列號
   If T <> Trim(Brr(i, 1)) And Trim(Brr(i, 1)) <> "" Then T = Trim(Brr(i, 1))
   '↑如果T變數與 i迴圈列第1欄Brr陣列值(且不是空值)不同??就令T是該值
   If Val(Brr(i, 10)) = 0 Then GoTo i01 Else R = R + 1: Crr(R, 1) = T
   '↑如果i迴圈列第10欄Brr陣列值轉乘的數值是0?? 就跳到標示 i01位置繼續執行,
   '否則就令R變數累加1,令R變數列第1欄Crr陣列值是 T變數

   For j = 3 To 9
   '↑設順迴圈!j從3到9
      If Trim(Brr(i, j)) <> "" Then
      '↑如果逐欄判定其值不是空值
         Crr(R, 2) = Brr(2, j)
         '↑令第2欄Crr陣列值以Brr陣列第2列第j迴圈欄值帶入
         Crr(R, 3) = Brr(i, j)
         '↑令第3欄Crr陣列值以Brr陣列第i迴圈列第j迴圈欄值帶入
         Crr(R, 4) = Brr(i, 10)
         '↑令第4欄Crr陣列值以Brr陣列第i迴圈列第10欄值帶入
         Exit For
         '↑令跳出j變數的迴圈
      End If
   Next
i01: Next
[R:U].ClearContents
'↑令結果欄內容清除
If R = 0 Then Exit Sub
'↑如果R變數是 0(代表沒有符合的資料),就結束程式執行
[R3].Resize(R, 4) = Crr
'↑令指定儲存格擴展剛好的範圍儲存格值以Crr陣列值帶入
End Sub
作者: hcm19522    時間: 2023-12-4 16:47

(輸入編號12096) google網址:https://hcm19522.blogspot.com/
作者: singo1232001    時間: 2023-12-8 09:30

本帖最後由 singo1232001 於 2023-12-8 09:35 編輯

Sub t5()
I = Split("Provider=Microsoft.,Jet.OLEDB.4,.0;Extended Properties=Excel ,8,.0;Data Source=", ",")
If Application.Version > 12 Then I(1) = "ACE.OLEDB.12": I(3) = 12
Set cn = CreateObject("adodb.connection"): cn.Open Join(I, "") & ThisWorkbook.FullName
q = "select F1,left(B,1),B,I from( select F1,F3&F4&F5&F6&F7&F8&F9 "
q = q & "as B,I FROM [" & ActiveSheet.Name & "$A1:K] where I is not NULL)"
[S:V].ClearContents: [s3].CopyFromRecordset cn.Execute(q)
For Each Z In [s3].CurrentRegion
If Z.Value = "" Then Z.Value = Z.Offset(-1, 0)
Next
End Sub




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)