後學的程式碼如下:
Option Explicit
Sub TEST_直式梯次名單()
Dim Arr, Brr, xR, i&, j&, S&, N&, M&, R&, C&
Dim Y, D As Date
Set Y = CreateObject("Scripting.Dictionary")
Sheets("Sheet1").UsedRange.Copy [Sheet3!A1]
With Sheets("Sheet3").UsedRange
.Replace What:=" ", Replacement:="", LookAt:=xlPart
.Sort KEY1:=.Item(1), Order1:=1, Header:=1
Arr = .Value
Brr = Range(.Cells(2, 2), .Cells(UBound(Arr), UBound(Arr, 2))).Value
.Clear
End With
For Each xR In Brr
If Trim(xR) <> "" Then
S = InStr(xR, "梯") + 1
N = InStr(xR, "(")
D = Mid(xR, S, N - S)
Y(D) = Trim(xR)
End If
Next
[Sheet3!A1].Resize(Y.Count, 1) = Application.Transpose(Y.KEYS)
[Sheet3!B1].Resize(Y.Count, 1) = Application.Transpose(Y.ITEMS)
With Sheets("Sheet3").UsedRange
.Sort KEY1:=.Item(1), Order1:=1, Header:=2
Brr = .Value
.Clear
End With
Y.RemoveAll
For i = 1 To UBound(Brr)
M = M + 1
Y(Brr(i, 2)) = M
Next
ReDim Brr(1 To UBound(Arr), 1 To Y.Count)
For i = 2 To UBound(Arr)
For j = 2 To UBound(Arr, 2)
If Arr(i, j) <> "" Then
R = Y(Arr(i, j) & "|")
R = R + 1
C = Y(Arr(i, j) & "")
Brr(R, C) = Arr(i, 1)
Y(Arr(i, j) & "|") = R
End If
Next j
Next i
[Sheet3!A1].Resize(1, M) = Application.Transpose(Application.Transpose(Y.KEYS))
[Sheet3!A2].Resize(UBound(Brr), M) = Brr
Application.Goto [Sheet3!A1]
Set Arr = Nothing
Set Arr = Nothing
Set Y = Nothing
End Sub
PS:有兩個 高O芬 不同梯次
Option Explicit
Sub TEST_排除資料表重複列_直式梯次名單_先整理再排序()
Dim Brr, Crr, xR, Z, xA, V, W, P, Sh1, SH3
Dim i&, j&, S&, N&, R&, C&, X&, Y&, Q&
Dim D As Date, Da$, T$
Set W = CreateObject("Scripting.Dictionary")
Set Z = CreateObject("Scripting.Dictionary")
Set P = CreateObject("Scripting.Dictionary")
Set Sh1 = Sheets("Sheet1")
Set SH3 = Sheets("Sheet3")
SH3.UsedRange.Clear
Crr = Range(Sh1.[A1], Sh1.UsedRange).Offset(1, 0)
R = UBound(Crr) - 1
C = UBound(Crr, 2)
ReDim Brr(1 To R, 1 To C)
ReDim V(R - 1)
For i = 1 To R
Da = ""
For j = 1 To C
Da = Da & "/" & Crr(i, j)
Next
If W.Exists(Da) = Empty Then
Q = Q + 1
For j = 1 To C
Brr(Q, j) = Trim(Crr(i, j))
Next
W(Da) = ""
End If
Next
W.RemoveAll
For Each xR In Brr
If InStr(xR, "(") Then
S = InStr(xR, "梯") + 1
N = InStr(xR, "(")
D = Mid(xR, S, N - S)
W(D) = xR
P(xR) = D
End If
Next
For Each xA In W.KEYS
Z(xA) = V
Next
For i = 1 To Q
For j = 2 To C
T = Brr(i, j)
If T <> "" Then
V = Z(P(T))
X = W(T & "|") + 1
V(X - 1) = Brr(i, 1)
W(T & "|") = X
Z(P(T)) = V
End If
Next j
Next i
SH3.[A1].Resize(1, Z.Count) = Application.Transpose(Application.Transpose(Z.KEYS))
SH3.[A2].Resize(Q, Z.Count) = Application.Transpose(Z.ITEMS)
For i = 1 To SH3.UsedRange.Columns.Count
With Range(SH3.Cells(1, i), SH3.Cells(Rows.Count, i).End(3))
.Sort KEY1:=.Item(1), Order1:=1, Header:=2, Orientation:=xlTopToBottom
End With
Next
With SH3.UsedRange
.Sort KEY1:=.Item(1), Order1:=1, Header:=2, Orientation:=xlLeftToRight
For i = 1 To .Columns.Count
D = .Cells(1, i)
.Cells(1, i) = W(D)
Next
End With
Application.Goto [Sheet3!A1]
Set Crr = Nothing
Set Brr = Nothing
Set W = Nothing
Set Z = Nothing
Set P = Nothing
End Sub作者: Andy2483 時間: 2022-12-7 16:44
Option Explicit
Sub TEST_排除資料表重複列_直式梯次名單_先整理再排序()
Dim Brr, Crr, xR, Z, xA, V, W, P, Sh1, SH3
'↑宣告通用型變數
Dim i&, j&, S&, N&, R&, C&, X&, Y&, Q&
'↑宣告長整數變數
Dim D As Date, Da$, T$
'↑宣告變數!(D)是日期變數,(Da,T)是字串變數
Set W = CreateObject("Scripting.Dictionary")
Set Z = CreateObject("Scripting.Dictionary")
Set P = CreateObject("Scripting.Dictionary")
'↑令W,Z,P各是字典
Set Sh1 = Sheets("Sheet1")
'↑令Sh1是 "Sheet1" 工作表
Set SH3 = Sheets("Sheet3")
'↑令Sh1是 "Sheet3" 工作表
SH3.UsedRange.Clear
'↑令 "Sheet3" 工作表涵蓋有使用的儲存格最小方正區域清除
Crr = Range(Sh1.[A1], Sh1.UsedRange).Offset(1, 0)
'↑令Crr是 表1[A1]到有使用儲存格的最小方正範圍儲存格往下偏移1列範圍的值
R = UBound(Crr) - 1
'↑令R是 Crr陣列縱向最大列號數減 1
C = UBound(Crr, 2)
'↑令C是 Crr陣列橫向最大列號數
ReDim Brr(1 To R, 1 To C)
'↑宣告Brr陣列範圍!縱向從1到R,橫向從1到C
ReDim V(R - 1)
'↑宣告V是一維陣列!索引範圍從0到R - 1
For i = 1 To R
'↑設外順迴圈!i從1到R
Da = ""
'↑令Da字串變數是空字元
For j = 1 To C
'↑設內順迴圈!j從1到C
Da = Da & "/" & Crr(i, j)
'↑令Da字串變數是 自己連接"/"符號,再連接i迴圈列j迴圈欄的Crr陣列值
Next
If W.Exists(Da) = Empty Then
'↑如果以Da當key查察W字典裡是初始值
Q = Q + 1
'↑令Q變數累加1
For j = 1 To C
'↑設內順迴圈!j從1到C
Brr(Q, j) = Trim(Crr(i, j))
'↑令Q變數列第j迴圈欄的Brr陣列值是 i迴圈列第迴圈j欄的值去掉頭尾的空白字元
Next
W(Da) = ""
'↑令以Da字串變數值當key,item是空字元倒入W字典裡
End If
Next
W.RemoveAll
'↑清空W字典
For Each xR In Brr
'↑設順迴圈!令xR 是Brr陣列的一員
If InStr(xR, "(") Then
'↑如果xR值裡有包含"("符號?
S = InStr(xR, "梯") + 1
'↑令S是xR判斷 "梯"字元所在字元位置數
N = InStr(xR, "(")
'↑令N 是 xR判斷 "("字元所在字元位置數
D = Mid(xR, S, N - S)
'↑令D是 xR值從S字元開始取 N - S個字的字串再變為日期
W(D) = xR
'↑令D這日期當key,item是xR的值
P(xR) = D
'↑令xR這日期當key,item是D的值
End If
Next
For Each xA In W.KEYS
'↑設順迴圈!令xA 是W字典裡keys的一員
Z(xA) = V
'↑令以xA為key,item是V一維陣列,倒入Z字典裡
Next
For i = 1 To Q
'↑設外順迴圈!i從1到Q
For j = 2 To C
'↑設內順迴圈!j從1到Q
T = Brr(i, j)
'↑令T字串變數是i迴圈列j迴圈欄的Brr陣列值
If T <> "" Then
'↑如果T字串變數不等於空字元??
V = Z(P(T))
'↑令V這通用型變數是 以T字串查察P字典的item值再查察Z字典得到的item(一維陣列)
X = W(T & "|") + 1
'↑令X這數字變數是 以T字串連接"|"符號查察字典的item值累加 1
V(X - 1) = Brr(i, 1)
'↑令V這一維陣列的索引號是 X-1的元素是 是i迴圈列第一欄的Brr陣列值
W(T & "|") = X
'↑令以T字串連接"|"符號為key的item是 數字變數X
Z(P(T)) = V
'↑令以T字串查察P字典的item值再查察Z字典得到的item是 一維陣列V
End If
Next j
Next i
SH3.[A1].Resize(1, Z.Count) = Application.Transpose(Application.Transpose(Z.KEYS))
'↑令表三[A1]擴展向下擴展1列(A1自身列),向右擴展Z字典鍵數欄是 Z字典key轉置兩次的值
SH3.[A2].Resize(Q, Z.Count) = Application.Transpose(Z.ITEMS)
'↑令表三[A2]擴展向下擴展 Q列,向右擴展Z字典鍵數欄是 Z字典key轉置兩次的值
For i = 1 To SH3.UsedRange.Columns.Count
'↑設順迴圈!i從1到 表三使用範圍的欄數
With Range(SH3.Cells(1, i), SH3.Cells(Rows.Count, i).End(3))
'↑以下是有關於表三 每一欄有內容的儲存格程序
.Sort KEY1:=.Item(1), Order1:=1, Header:=2, Orientation:=xlTopToBottom
'↑排序:基準是範圍裡第一格欄位,大到小,沒有標題列,縱向排序從上到下
End With
Next
With SH3.UsedRange
'↑以下是有關於表三使用範圍的儲存格程序
.Sort KEY1:=.Item(1), Order1:=1, Header:=2, Orientation:=xlLeftToRight
'↑排序:基準是範圍裡第一格列位,大到小,沒有標題列,縱向排序從左到右
For i = 1 To .Columns.Count
'↑設順迴圈!i從1 到表三使用範圍的欄數
D = .Cells(1, i)
'↑令D日期變數是 表三使用範圍的相對儲存格第1列第i迴圈變數欄的值轉成日期
.Cells(1, i) = W(D)
'↑令以 表三使用範圍的相對儲存格第1列第i迴圈變數欄的值查察W字典得到的item值(字串)
'的值放入當格
Next
End With
Application.Goto [Sheet3!A1]
Set Crr = Nothing
Set Brr = Nothing
Set W = Nothing
Set Z = Nothing
Set P = Nothing
End Sub
Sub Item的規則()
Dim Area As Range
Set Area = [A1:J10]
MsgBox Area.Item(1).Address
MsgBox Area.Item(5).Address
MsgBox Area.Item(10).Address
MsgBox Area.Item(11).Address
MsgBox Area.Item(100).Address
MsgBox Area.Item(101).Address
'↑範圍內由左到右,上到下標儲存格索引
MsgBox Area.Item(1, 1).Address
MsgBox Area.Item(1, 5).Address
MsgBox Area.Item(1, 10).Address
MsgBox Area.Item(2, 1).Address
MsgBox Area.Item(10, 10).Address
MsgBox Area.Item(1, 11).Address
'↑範圍內的座標方式標儲存格索引
End Sub作者: singo1232001 時間: 2022-12-7 22:36
Sub test()
Dim Arr, Brr, Crr, xD, xR, i&, j&, S&, N&, M&, R&, C&, D As Date
Set xD = CreateObject("Scripting.Dictionary")
Sheets("Sheet1").UsedRange.Copy [Sheet3!A1]
With Sheets("Sheet3").UsedRange
.Replace What:=" ", Replacement:="", LookAt:=xlPart
.Sort Key1:=.Item(1), Order1:=1, Header:=1
Arr = .Value
Brr = Range(.Cells(2, 2), .Cells(UBound(Arr), UBound(Arr, 2))).Value
.Clear
End With
ReDim Crr(1 To UBound(Arr), 1 To 2)
For Each xR In Brr
If InStr(xR, "梯") Then
S = InStr(xR, "梯") + 1
N = InStr(xR, "(")
D = Mid(xR, S, N - S)
If Not xD.Exists(D) Then
i = i + 1: xD(D) = i
Crr(i, 1) = D: Crr(i, 2) = Trim(xR)
End If
End If
Next
With Sheets("Sheet3").[a1].Resize(i, 2)
.Value = Crr
.Sort Key1:=.Item(1), Order1:=1, Header:=2, Orientation:=xlTopToBottom
Brr = .Value
.Clear
End With
xD.RemoveAll
ReDim Crr(1 To UBound(Arr), 1 To i)
For i = 1 To UBound(Brr)
M = M + 1: xD(Brr(i, 2)) = M
Crr(1, M) = Brr(i, 2)
Next
For i = 2 To UBound(Arr)
For j = 2 To UBound(Arr, 2)
If Arr(i, j) <> "" Then
If Not xD.Exists(Arr(i, j) & "|" & Arr(i, 1)) Then
R = xD(Arr(i, j) & "|R")
If R = 0 Then R = R + 2 Else R = R + 1
C = xD(Arr(i, j) & "")
Crr(R, C) = Arr(i, 1)
xD(Arr(i, j) & "|R") = R
xD(Arr(i, j) & "|" & Arr(i, 1)) = ""
End If
End If
Next j
Next i
[Sheet3!A1].Resize(UBound(Crr), M) = Crr
Application.Goto [Sheet3!A1]
End Sub作者: Andy2483 時間: 2022-12-8 16:01
'Orientation:=xlTopToBottom這 縱向排序的陳述最好加上!
'不然EXCEL好像會儲存最後一次的排序方式:
'例如 前次如果做Orientation:=xlLeftToRight,此次以為的縱向排序是做橫向排序
'學習這帖得到的以為EXCEL壞掉的可笑經驗
Arr = .Value
'↑令Arr是 二維陣列!貼入排序後的整個範圍儲存格值
Brr = Range(.Cells(2, 2), .Cells(UBound(Arr), UBound(Arr, 2))).Value
'↑令Brr是 二維陣列!貼入排序後的整個範圍的不含標題列也不含標題欄(姓名欄)儲存格 值
.Clear
'令 表三涵蓋有使用的儲存格最小方正區域儲存格清除
End With
ReDim Crr(1 To UBound(Arr), 1 To 2)
'宣告Crr二維陣列的範圍!縱向從1到 Arr陣列縱向最大列號數 列,橫向從1到2欄
For Each xR In Brr
'↑設順迴圈!令xR是Brr的一個陣列值從左到右/下到上 跑
If InStr(xR, "梯") Then
'↑如果xR的字串值裡有包含"梯"字元??
S = InStr(xR, "梯") + 1
'↑令S數字變數是 "梯"字元在xR字串裡字元位置數+1
N = InStr(xR, "(")
'↑令N數字變數是 "("字元在xR字串裡字元位置數
D = Mid(xR, S, N - S)
'↑令D是 xR字串裡從S位置開始,取N - S個字元的字串後,轉化為日期,
'原來擷取的字串是沒有年分的日期字串,EXCEL會自動加上今年的年份,
'如果日期是跨年分,排序就可能出問題了,使用者要注意!!
'可以改用完整的年/月/日登錄做改善
If Not xD.Exists(D) Then
'↑如果以D日期變數查察xD字典結果是不存在這key??
i = i + 1
'↑令i數字變數累加1
xD(D) = i
'↑令以D日期變數為key,item是 i變數,放入xD字典裡
Crr(i, 1) = D
'↑令i迴圈列第1欄Crr陣列值是 D日期變數
Crr(i, 2) = Trim(xR)
'↑令i迴圈列第1欄Crr陣列值是 xR字串去除頭尾空白字元
'這Trim()應該可以省略,被後學誤導了
End If
End If
Next
With Sheets("Sheet3").[a1].Resize(i, 2)
'↑以下是關於表三[A1]儲存格開始擴展向下i列,向右擴展2欄的儲存格集
.Value = Crr
'↑令Crr陣列值倒入儲存格集裡
.Sort Key1:=.Item(1), Order1:=1, Header:=2, Orientation:=xlTopToBottom
'↑.整個範圍排序:key基準是整個範圍的索引編號 1的儲存格所在的欄位
'Order1:=1排序方式是 由小到大
'Header:=2 沒有標題列
'縱向排序
Brr = .Value
'令原Brr二維陣列初始化後,重新裝入排序後的儲存格集 值
.Clear
'令 表三儲存格集 清除
End With
xD.RemoveAll
'↑清空xD字典
ReDim Crr(1 To UBound(Arr), 1 To i)
'↑令原Crr二維陣列初始化後,宣告Crr二維陣列的範圍!縱向從1到Arr陣列縱向最大列號數列,
'橫向從1到i變數欄
For i = 1 To UBound(Brr)
'↑設順迴圈!變數i從1到Brr陣列縱向最大列號數
M = M + 1
'↑M數字變數累加 1
xD(Brr(i, 2)) = M '@@1
'↑令以i迴圈列第2欄的Brr陣列值當key,item是 M數字變數!倒入xD字典裡
Crr(1, M) = Brr(i, 2)
'↑令第1列M數字變數欄Crr陣列值是 i迴圈列第2欄的Brr陣列值 PS:處裡結果表標題列
Next
For i = 2 To UBound(Arr)
'↑設外順迴圈!i變數從2到 Arr陣列縱向最大列號數
For j = 2 To UBound(Arr, 2)
'↑設外順迴圈!j變數從2到 Arr陣列橫向最大欄號數
If Arr(i, j) <> "" Then
'↑如果i迴圈列j迴圈欄的Arr陣列值 不是空的
If Not xD.Exists(Arr(i, j) & "|" & Arr(i, 1)) Then
'↑再如果 以梯次日期星期字串連接"|"符號,再連接 姓名的組合字串,
'查察xD字典結果是不存在這key ??
R = xD(Arr(i, j) & "|R")
'↑令R數字變數是 以梯次日期星期字串連接"|R"字串的新字串,
'查察xD字典得到的item值
If R = 0 Then
'↑如果R這數字變數是 0 ??
R = R + 2
'↑If條件成立!就令R數字變數累加 2 (放結果的列號)
'因為每欄姓名是從第2列開始擺放!所以加 2
Else
R = R + 1
'↑If條件不成立!就令R數字變數累加 1 (放結果的列號)
End If
C = xD(Arr(i, j) & "")
'↑令C數字變數是 梯次日期星期字串連接""的新字串,
'查察xD字典得到的item值 (放結果的欄號,如上方 @@1標註位置)
Crr(R, C) = Arr(i, 1)
'↑令R變數列C變數欄的Crr陣列值是 i迴圈的姓名
xD(Arr(i, j) & "|R") = R
'↑令以梯次日期星期字串連接"|R"字串的字串為key,item是 放結果的列號,
'放入xD字典裡或置換該key對應的item值
xD(Arr(i, j) & "|" & Arr(i, 1)) = ""
'↑令以梯次日期星期字串連接"|"符號,再連接 姓名的組合字串為key,
'item是空字元,放入xD字典裡 排除重複報名
End If
End If
Next j
Next i
[Sheet3!A1].Resize(UBound(Crr), M) = Crr
'↑令表三[A1]擴展向下 Crr陣列縱向最大列號數列,向右擴展M欄的儲存格,倒入Crr陣列值
Application.Goto [Sheet3!A1]
End Sub作者: Andy2483 時間: 2022-12-19 14:46
Option Explicit
Sub TEST_直式梯次名單_20221219()
Dim Arr, Brr, xR, i&, j&, S&, N&, M&, R&, C&
Dim Y, D As Date, T$
Set Y = CreateObject("Scripting.Dictionary")
Sheets("Sheet1").UsedRange.Copy [Sheet3!A1]
With Sheets("Sheet3").UsedRange
.Replace What:=" ", Replacement:="", Lookat:=xlPart
.Sort Key1:=.Item(1), Order1:=1, Header:=1, Orientation:=xlTopToBottom
Arr = .Value
Brr = Range(.Cells(2, 2), .Cells(UBound(Arr), UBound(Arr, 2))).Value
.Clear
End With
For Each xR In Brr
If Trim(xR) <> "" Then
S = InStr(xR, "梯") + 1
N = InStr(xR, "(")
D = Mid(xR, S, N - S)
Y(D) = xR
End If
Next
[Sheet3!A2].Resize(1, Y.Count) = Application.Transpose(Application.Transpose(Y.KEYS))
[Sheet3!A1].Resize(1, Y.Count) = Application.Transpose(Application.Transpose(Y.ITEMS))
With Sheets("Sheet3").UsedRange
.Sort Key1:=.Item(2, 1), Order1:=1, Header:=2, Orientation:=xlLeftToRight
Brr = .Resize(UBound(Arr))
End With
Y.RemoveAll
For i = 1 To UBound(Brr, 2)
Y(Brr(1, i)) = i
Next
For i = 2 To UBound(Arr)
For j = 2 To UBound(Arr, 2)
If Arr(i, j) <> "" Then
Y(i & "|" & Arr(i, j)) = Arr(i, 1)
End If
Next
Next
For Each xR In Y.KEYS
If InStr(xR, "|") Then
T = Mid(xR, InStr(xR, "|") + 1)
If Y(T & Y(xR)) = "" Then
S = Y(T & "/a") + 1
Brr(S + 1, Y(T)) = Y(xR)
Y(T & "/a") = S
Y(T & Y(xR)) = 1
End If
End If
Next
[Sheet3!A1].Resize(UBound(Brr), UBound(Brr, 2)) = Brr
Application.Goto [Sheet3!A1]
Set Arr = Nothing
Set Brr = Nothing
Set Y = Nothing
End Sub作者: Andy2483 時間: 2022-12-19 15:24
Option Explicit
Sub TEST_直式梯次名單_20221219_1()
Dim Arr, Brr, xR, i&, j&, S&, N&, M&, R&, C&
Dim Y, D As Date, T$
Set Y = CreateObject("Scripting.Dictionary")
Sheets("Sheet1").UsedRange.Copy [Sheet3!A1]
With Sheets("Sheet3").UsedRange
.Replace What:=" ", Replacement:="", Lookat:=xlPart
.Sort Key1:=.Item(1), Order1:=1, Header:=1, Orientation:=xlTopToBottom
Arr = .Value
Brr = Range(.Cells(2, 2), .Cells(UBound(Arr), UBound(Arr, 2))).Value
.Clear
End With
For Each xR In Brr
If Trim(xR) <> "" Then
S = InStr(xR, "梯") + 1
N = InStr(xR, "(")
D = Mid(xR, S, N - S)
Y(D) = xR
End If
Next
[Sheet3!A2].Resize(1, Y.Count) = Application.Transpose(Application.Transpose(Y.KEYS))
[Sheet3!A1].Resize(1, Y.Count) = Application.Transpose(Application.Transpose(Y.ITEMS))
With Sheets("Sheet3").UsedRange
.Sort Key1:=.Item(2, 1), Order1:=1, Header:=2, Orientation:=xlLeftToRight
Brr = .Resize(UBound(Arr))
End With
Y.RemoveAll
For i = 1 To UBound(Brr, 2)
Y(Brr(1, i)) = i
Next
For i = 2 To UBound(Arr)
For j = 2 To UBound(Arr, 2)
If Arr(i, j) <> "" Then
Y(Arr(i, 1) & "|" & Arr(i, j)) = ""
End If
Next
Next
For Each xR In Y.KEYS
If InStr(xR, "|") And Y(xR) = "" Then
T = Split(xR, "|")(1)
S = Y(T & "/a") + 1
Brr(S + 1, Y(T)) = Split(xR, "|")(0)
Y(T & "/a") = S
Y(xR) = 1
End If
Next
[Sheet3!A1].Resize(UBound(Brr), UBound(Brr, 2)) = Brr
Application.Goto [Sheet3!A1]
Set Arr = Nothing
Set Brr = Nothing
Set Y = Nothing
End Sub