(字典物件)單格多行儲存格分隔為多行單格儲存格問題
各位前輩好,小弟最近在練習時遇到一個問題,
附上檔案以供前輩參考:
[attach]25815[/attach]
將問題以文字簡述如下:
假設有兩直欄資料,
A欄為一般文字,B欄的每個儲存格均有多筆資料,每筆資料有換行,
示意如下:
B欄
111
222
333
以上三筆數字均在同一個儲存格中.
希望可以將B欄的每筆資料分隔至單一儲存格,貼至F欄,
並將A欄的資料依據B欄的資料去貼上,
承上例,
假設上例之B欄對應之A欄儲存格為"AAA",
則期望結果如下:
A欄 B欄
AAA 111
AAA 222
AAA 333
小弟冒昧借用論壇前輩以及網上其他朋友的程式碼進行修改,
修改之程式碼如下:[code]Sub test()
'此為參考論壇前輩及網上其他朋友所提供之程式碼進行修改,
'非我原創
'論壇網址;http://forum.twbts.com/thread-18600-1-1.html
Dim Arr, Brr(1 To 65536, 1 To 1), myD, C, UC
'關閉螢幕更新
Application.ScreenUpdating = False
Set myD = CreateObject("scripting.dictionary")
Arr = Range("a2:c" & Cells(Rows.Count, "a").End(3).Row).Value
'清除結果欄的資料
Range("e2", Cells(Rows.Count, "f")).ClearContents
For Each A In Range("b2:b" & Cells(Rows.Count, "b").End(3).Row).Value
For Each B In Split(A, Chr(10))
'將B欄多行儲存格內的值分割並代入陣列,
'使用字典物件將重複值刪除
If myD(B) = 1 Then GoTo 101
N = N + 1
Brr(N, 1) = B
myD(B) = 1
101: Next B
Next A
[f2].Resize(N, 1) = Brr
'"---"虛線範圍內的程式碼在B欄多行儲存格有重複資料或空行時會出現問題
'-------------------------------------------------------
'計算B欄多行儲存格內的值的總數量並顯示於C欄
For i = 1 To UBound(Arr)
C = Split(Arr(i, 2), Chr(10))
UC = UBound(C) + 1
Arr(i, 3) = UC
Next i
[a2].Resize(UBound(Arr), 3) = Arr
'將A欄的資料依C欄的次數貼至E欄
For j = 2 To UBound(Arr) + 1
Cells(j, 1).Copy _
Cells(Rows.Count, 5).End(xlUp).Offset(1, 0).Resize(Cells(j, 3), 1)
Next j
'-------------------------------------------------------
'C欄的數字使用者用不到,故在最後清除C欄
Columns(3).ClearContents
'開啟螢幕更新
Application.ScreenUpdating = True
End Sub
[/code]以上程式碼若遇到B欄資料有空行或是有重複之情形時則會出現問題,
問題情形煩請參考附檔所示.
小弟苦思許久,還是無法解決,斗膽上來求助,
還望前輩不吝指點迷津,十分感謝 試試[code]Sub test()
Dim Arr, Brr(1 To 65536, 1 To 2), C, UC
Application.ScreenUpdating = False
Arr = Range("a2:b" & Cells(Rows.Count, "a").End(3).Row).Value
Range("e2", Cells(Rows.Count, "f")).ClearContents
For Each A In Range("b2:b" & Cells(Rows.Count, "b").End(3).Row).Value
For Each b In Split(A, Chr(10))
If Len(b) > 0 Then
n = n + 1
UC = UC + 1
Brr(n, 1) = b
End If
Next b
m = m + 1
Brr(m, 2) = UC
UC = 0
Next A
[f2].Resize(n, 1) = Brr
For j = 2 To UBound(Arr) + 1
Cells(j, 1).Copy _
Cells(Rows.Count, 5).End(xlUp).Offset(1, 0).Resize(Brr(j - 1, 2), 1)
Next j
Application.ScreenUpdating = True
End Sub[/code] [b]回復 [url=http://forum.twbts.com/redirect.php?goto=findpost&pid=95511&ptid=18764]2#[/url] [i]葉國洲[/i] [/b]
十分感謝葉國洲前輩提供解答,小弟再研究一下. [b]回復 [url=http://forum.twbts.com/redirect.php?goto=findpost&pid=95506&ptid=18764]1#[/url] [i]greetingsfromtw[/i] [/b]
請測試
Sub newtest()
Dim Arr, Brr(), myD As Object
Set myD = CreateObject("Scripting.Dictionary")
Arr = Range("a2:c" & Cells(Rows.Count, "a").End(3).Row).Value
For i = 1 To UBound(Arr)
For j = 0 To UBound(Split(Arr(i, 2), Chr(10)))
If Split(Arr(i, 2), Chr(10))(j) <> "" Then myD(Split(Arr(i, 2), Chr(10))(j)) = ""
Next j
For Each C In myD
n = n + 1
ReDim Preserve Brr(1 To 2, 1 To n)
Brr(1, n) = Arr(i, 1)
Brr(2, n) = C
Next C
myD.RemoveAll
Next i
[E2:F65536].ClearContents
[E2].Resize(n, 2) = Application.Transpose(Brr)
End Sub [b]回復 [url=http://forum.twbts.com/redirect.php?goto=findpost&pid=95515&ptid=18764]4#[/url] [i]Kubi[/i] [/b]
十分感謝Kubi前輩無私提供解答,
跟葉國洲前輩所提供之程式碼均可有效解決問題,再次感謝.
可以的話,
是否允許小弟進一步詢問相關細節,
假設要讓B欄分割後的資料均不重覆,不知是否可行?
舉例而言,
假設現在B直欄只有兩筆資料,B2與B3,
其中B2儲存格資料為:
111
222
333,
B3儲存格資料為:
111
555
777,
因111有重複,是否有辦法將111此筆資料只顯示一次?
小弟斗膽,還請前輩不吝指點迷津,十分感謝. http://blog.xuite.net/hcm19522/twblog/468529807 [b]回復 [url=http://forum.twbts.com/redirect.php?goto=findpost&pid=95523&ptid=18764]6#[/url] [i]hcm19522[/i] [/b]
十分感謝hcm19522前輩以公式提供解答,小弟再研究一下.
前輩的網站小弟有加入最愛,主題能得到前輩關注,甚感榮幸. 注釋的部分解除可實現去重[code]Sub test11()
Dim Arr, Brr(1 To 100, 1 To 2), n%, rg As Range, d
Set d = CreateObject("scripting.dictionary")
Application.ScreenUpdating = False
Arr = Range("a2:b" & Cells(Rows.Count, "a").End(3).Row).Value
Range("e2", Cells(Rows.Count, "f")).ClearContents
Set rg = Range("b2:b" & Cells(Rows.Count, "b").End(3).Row)
For Each a In rg
For Each b In Split(a, Chr(10))
' If Not d.exists(b) Then
' d(b) = ""
If Len(b) > 0 Then
n = n + 1
Brr(n, 1) = a.Offset(0, -1)
Brr(n, 2) = b
End If
' End If
Next b
Next a
Range("f2").Resize(UBound(Brr), UBound(Brr, 2)) = Brr
Application.ScreenUpdating = True
End Sub
[/code] [b]回復 [url=http://forum.twbts.com/redirect.php?goto=findpost&pid=95531&ptid=18764]8#[/url] [i]葉國洲[/i] [/b]
十分感謝葉國洲前輩費心指點,
程式碼可確實解決問題,小弟獲益良多,再次感謝. 謝謝論壇,謝謝各位前輩
後學藉此帖練習陣列與字典,學習方案如下,請各位前輩指教
執行前:
[attach]36358[/attach]
執行結果:
[attach]36359[/attach]
Option Explicit
Sub TEST() '↑
Dim Brr, Crr, V, Y, R&, i&
[color=SeaGreen]'↑ 宣告變數[/color]
Set Y = CreateObject("Scripting.Dictionary")
[color=SeaGreen]'↑令Y變數是字典[/color]
Brr = Range([B2], Cells(Rows.Count, 1).End(xlUp))
[color=SeaGreen]'↑令Brr變數是 二維陣列,以儲存格值帶入陣列中[/color]
ReDim Crr(1 To 1000, 1 To 2)
[color=SeaGreen]'↑宣告 Crr變數是二維空陣列,縱向索引號1~1000,橫向索引號1~2[/color]
For i = 1 To UBound(Brr)
[color=SeaGreen]'↑設順迴圈!i從1到Brr縱向最大索引列號[/color]
For Each V In Split(Brr(i, 2) & vbLf, vbLf)
[color=SeaGreen] '↑設逐項迴圈!令V變數是以換行字元分割Brr陣列第2欄字串的一維陣列值之一[/color]
If Trim(V) = "" Then GoTo v01
[color=SeaGreen] '↑如果V變數去除頭尾空字元後是 空字元!就跳到v01標示位置繼續執行[/color]
If Y(Brr(i, 1) & "|" & V) <> "" Then GoTo v01
[color=SeaGreen] '↑如果Brr陣列第1欄字串連接"|",再連接V變數所組成的字串查Y字典item值,
'item值不是空字元!就跳到v01標示位置繼續執行[/color]
R = R + 1: Y(Brr(i, 1) & "|" & V) = 1
[color=SeaGreen] '↑令R變數累加1
'令在Y字典裡的(key:Brr陣列第1欄字串連接"|",再連接V變數所組成的字串),
'item="" 改為 1,[/color]
Crr(R, 1) = Brr(i, 1): Crr(R, 2) = V
[color=SeaGreen] '↑令R變數列第1欄Crr陣列是 i迴圈列第1欄Brr陣列值,
'↑令R變數列第2欄Crr陣列是 V變數[/color]
v01: Next
Next
[E2].Resize(R, 2) = Crr
[color=SeaGreen]'↑令[E2]擴展向下R變數列,向右擴展2欄範圍儲存格值以Crr陣列值帶入[/color]
Set Y = Nothing: Erase Brr, Crr
[color=SeaGreen]'↑令釋放變數[/color]
End Sub
頁:
[1]