返回列表 上一主題 發帖

[發問] 重新排序

回復 10# cowww


    謝謝前輩回復,感覺前輩上班樂在其中
看得懂是應該的,懂得應用才像學生,臉皮厚點學會更謹慎積極

TOP

本帖最後由 Andy2483 於 2023-5-26 16:34 編輯

回復 10# cowww


    謝謝論壇,謝謝前輩一起學習
後學藉此帖練習陣列與字典,將排序放到最後,方案與心得註解如下,請前輩參考,一起學習


Option Explicit
Sub TEST()
Application.ScreenUpdating = False
Dim Brr, Crr, V, A, Y, R&, i&, j%, C%, TT$, T1$, T3$, T4 As Date, T9$, N&, MC%
'↑宣告變數
Set Y = CreateObject("Scripting.Dictionary")
'↑令Y變數是 字典
Brr = Range([sheet1!I3], [sheet1!A65536].End(3))
'↑令Brr變數是 二維陣列,以儲存格值帶入陣列中
ReDim Crr(1 To UBound(Brr), 1 To 100)
'↑宣告Crr變數是 二維空陣列,縱向範圍同Brr陣列,橫向1~100
For i = 1 To UBound(Brr)
'↑設順迴圈
   If i = 1 Then
      Crr(1, 1) = "工號": Crr(1, 2) = "姓名 | Display Name": Crr(1, 3) = "天數": N = 1
   End If
   '↑如果處理第1列時,特別先處理結果表的標題列
   T1 = Brr(i, 1): T3 = Brr(i, 3): T4 = Brr(i, 4): T9 = Brr(i, 9): TT = T1 & "|" & T3
   '↑令陣列值以變數盛裝,可定義變數類型,又可精簡程式碼
   If T9 <> "國假" Then GoTo i01
   '↑如果假別不是 "國假" 就不處理跳過
   If Y(TT) = "" Then N = N + 1: Y(TT) = N: Crr(N, 1) = T1: Crr(N, 2) = T3: Y(TT & "|C") = 3
   '↑如果關鍵字是初次納入字典,必須先處理標題欄
   R = Y(TT): C = Y(TT & "|C"): C = C + 1: Y(TT & "|C") = C: If MC < C Then MC = C
   '↑將字典中紀錄的欄位,列位提取出來,並判定最後寫入儲存格時的欄數MC
   Crr(R, C) = T4: Crr(R, 3) = Crr(R, 3) + 1
   '↑將新日期放入Crr陣列中,天數要累加
i01: Next
For i = 4 To MC: Crr(1, i) = i - 3: Next
'↑將標題列天數填入
With Sheets("工作表1")
   .UsedRange.ClearContents
   '↑清除結果表內容
   .Columns(1).NumberFormatLocal = "@"
   '↑令結果表第1欄格式是文字
   .Rows(1).NumberFormatLocal = "@"
   '↑令結果表第1列格式是文字
   With .[A1].Resize(N, MC)
      .Value = Crr
      '↑令Crr陣列值寫入結果表中
      .Sort KEY1:=.Item(1), Order1:=1, Header:=1
      '↑令該範圍儲存格以第1欄為基準,做有標題列的順排序
   End With
End With
Set Y = Nothing: Erase Brr, Crr
'↑令釋放變數
End Sub


=============================================
補充:
   .Columns(1).NumberFormatLocal = "@"
   .Rows(1).NumberFormatLocal = "@"
可合併為:
   Union(.Columns(1), .Rows(1)).NumberFormatLocal = "@"
看得懂是應該的,懂得應用才像學生,臉皮厚點學會更謹慎積極

TOP

回復 12# Andy2483

非常感謝Andy2483大大的熱心解惑

這段語法無法執行
請問這段語法跟#9的語法有何不同

TOP

回復 12# Andy2483


忘記將錯誤訊息發上來了

錯誤2.PNG
2023-5-28 15:57

錯誤.PNG
2023-5-28 15:57

TOP

本帖最後由 Andy2483 於 2023-5-29 11:59 編輯

回復 14# cowww


    謝謝前輩回復
1.資料表表名是 sheet1,請查看資料表表明是否更改
2.資料表欄位是否變動
3.再不行,請上傳範例檔

Brr = Range([sheet1!I3], [sheet1!A65536].End(3))
'↑令Brr變數是 二維陣列,以儲存格值帶入陣列中
看得懂是應該的,懂得應用才像學生,臉皮厚點學會更謹慎積極

TOP

回復 15# Andy2483

非常感謝Andy2483大大的幫忙
錯誤訊息.PNG
2023-5-29 13:47

錯誤訊息2.PNG
2023-5-29 13:47


2023國假-VBA.zip (407.59 KB)
裡面有我正在練習的下拉式選單的聯動

TOP

回復 16# cowww


If T9 <> "國假" Then GoTo i01
改成
If T9 <> "National Holiday" Then GoTo i01
看得懂是應該的,懂得應用才像學生,臉皮厚點學會更謹慎積極

TOP

回復 17# Andy2483

成功了
非常感謝Andy2483大大的解惑

TOP

謝謝論壇,謝謝各位前輩
後學藉此帖複習直式呈現方式,方案學習心得註解如下,請各位前輩指教

20230530_1.jpg
7 天前 08:20




Option Explicit
Sub TEST()
Dim Brr, Crr(1 To 1000, 1 To 2), A, Y, R&, i&, TT$, T1$, T3$, T4 As Date, T9$
'↑宣告變數
Set Y = CreateObject("Scripting.Dictionary")
'↑令Y變數是 字典
Brr = Range([sheet1!I3], [sheet1!A65536].End(3))
'↑令Brr變數是 二維陣列,以sheet1 表的A~I欄儲存格值帶入陣列中
With Sheets("工作表1").[A2].Resize(UBound(Brr), UBound(Brr, 2))
'↑以下是關於名為 "工作表1" 工作表擴展Brr陣列範圍的程序
   .Value = Brr
   '↑令儲存格值是 Brr陣列值
   .Sort KEY1:=.Item(1), Order1:=1, _
         Key2:=.Item(4), Order2:=1, Header:=2
   '↑令該範圍做2層次,無標題列的縱向順排序
   Brr = .Value
   '↑令Brr二維陣列值是該範圍排序後的陣列值
End With
For i = 1 To UBound(Brr)
'↑設順迴圈
   T1 = Brr(i, 1): T3 = Brr(i, 3): T4 = Brr(i, 4): T9 = Brr(i, 9)
   '↑令變數裝入陣列值,一方面定義其值,一方面可以縮短程式碼
   If T9 <> "國假" Then GoTo i00
   '↑如果T9變數不是 "國假"字串,就跳到i00位置繼續執行
   TT = T1 & "|" & T3: A = Y(TT)
   '↑令TT變數是 組合字串,令A變數是 以TT變數查Y字典回傳的item
   If Not IsArray(A) Then A = Crr: Y(TT & "/編") = T1: Y(TT & "/名") = T3
   '↑如果item不是陣列?? 就令A變數是Crr陣列(空陣列),
   '令TT變數連接 "/編"組成的新字串當key,item是T1變數,納入Y字典裡,
   '令TT變數連接 "/名"組成的新字串當key,item是T3變數,納入Y字典裡

   R = Y(TT & "/R"): R = R + 1: Y(TT & "/R") = R
   '↑令R變數是 TT變數連接 "/R"組成的新字串查Y字典的回傳值,
   '令R變數累加 1,
   '令TT變數連接 "/R"組成的新字串當key,item是 R變數,納入Y字典裡

   A(R, 1) = T4: A(R, 2) = T9: Y(TT) = A
   '↑令R變數列第1欄A陣列值是 T4變數值,令R變數列第2欄A陣列值是 T4變數值,
   '令TT變數當key,item是A二維陣列納入Y字典中

i00: Next
With Sheets("工作表1")
'↑以下是關於名為 "工作表1" 工作表的程序
   .UsedRange.Offset(1, 0).Clear: R = 1
   '↑令使用的儲存格往下偏移1列範圍的儲存格清除,令R變數是 1
   .Columns(1).NumberFormatLocal = "@"
   '↑令A欄格式是 文字
   For Each A In Y.KEYS
   '↑設逐項迴圈,令A變數是Y字典裡的key
      If Not IsArray(Y(A)) Then GoTo i01
      '↑如果以A變數查Y字典回傳得item不是 陣列,就跳到i01位置執行
      R = R + 1
      '↑令R變數累加1
      .Cells(R, 1) = Y(A & "/編"): .Cells(R, 2) = Y(A & "/名")
      '↑令儲存格寫入 員工編號與姓名
      .Cells(R, 3).Resize(Y(A & "/R"), 2) = Y(A): R = R + Y(A & "/R") - 1
      '↑令適當範圍寫入Y字典所回傳item二維陣列值
i01: Next
End With
Set Y = Nothing: Erase Brr, Crr
'↑令釋放變數
End Sub
看得懂是應該的,懂得應用才像學生,臉皮厚點學會更謹慎積極

TOP

回復 19# Andy2483

非常感謝Andy2483大大的註解

TOP

        靜思自在 : 閒人無樂趣,忙人無是非。
返回列表 上一主題