關於寫巨集程式自動篩選判斷區的代碼複製成該代碼單獨活頁簿
- 帖子
- 2035
- 主題
- 24
- 精華
- 0
- 積分
- 2031
- 點名
- 0
- 作業系統
- Win7
- 軟體版本
- Office2010
- 閱讀權限
- 100
- 性別
- 男
- 註冊時間
- 2012-3-22
- 最後登錄
- 2024-2-1
|
回復 10# 學到老死
回復 9# yen956
為配合實務上的實際應用,將它整理了一下,
並引用一些可能因素,以及步局考量、而做
出的範例,提供參考看看!- ' 請貼到 "彙總表"
- Sub 彙入總表()
- Dim sh1 As Worksheet, sh2 As Worksheet
- Dim Lst1 As Integer
- Dim J As Integer
- Dim msg As Boolean
-
- Set sh1 = Sheets("彙總表")
- sh1.Cells.Clear
- msg = False
-
- For J = 1 To Sheets.Count
- If Sheets(J).Name <> "彙總表" Then
- Set sh2 = Sheets(J)
- Lst1 = IIf(sh1.[B65536].End(xlUp).Row = 1, 1, sh1.[B65536].End(xlUp).Row + 1)
- ' sh2.UsedRange.Address = "$B$4:$E$7" : String
- ' sh2.UsedRange.Offset(1, 0).Address = "$B$5:$E$8" : String
- ' 第一次需先連同標題及其內容一併彙入到總表內,之後僅複製每一工作表單之內容 (不含標題在內)。
- sh2.UsedRange.Offset(IIf(msg, 1, 0), 0).Copy sh1.Cells(Lst1, 2)
- msg = True
- End If
- Next
- End Sub
- ' 彙出到分頁
- ' 應用範圍: 建立字典、大小排序、貼製複製內容、如何檢查工作表單已否存在、動態產生工作表單、
- ' 清除暫存工作區塊、以及字典的實務應用與技巧。
- Sub 彙出到分頁()
- Dim sh1 As Worksheet, sh2 As Worksheet, rng As Range, dic As Object
- Dim Lst1 As Integer, v As Variant
- Dim J As Integer, I As Integer
-
- Set dic = CreateObject("scripting.dictionary")
- Set sh1 = Sheets("彙總表")
- Lst1 = sh1.[B65536].End(xlUp).Row
-
- sh1.Range("B1:E" & Lst1).Copy sh1.[W1] ' 另闢戰場 (B 欄先按照字母大小排序後再行彙出到各相關工作表單)
- With [W2].Resize(Lst1 - 1, 4)
- .Cells.Sort Key1:=.Cells(1), Key2:=.Cells(3), Order1:=xlAscending, Header:=xlNo ' xlDescending
- End With
-
- For J = 2 To Lst1
- dic(sh1.Range("W" & J).Text) = dic(sh1.Range("W" & J).Text) + 1
- Next J
-
- Set rng = Sheets("彙總表").[W2]
- For Each v In dic.KEYS ' v = "A" : Variant/String
- I = dic.Item(v) ' I = 3 : Integer
- J = checkShts(CStr(v))
-
- If J > 0 Then
- Set sh2 = Sheets(J)
- Else
- Set sh2 = Sheets.Add(After:=Sheets(Sheets.Count))
- sh2.Name = v
- End If
-
- With sh2
- .Cells.Clear
- sh1.[W1:Z1].Copy .[B1]
- rng.Resize(I, 4).Copy .[B2]
- Set rng = rng.Offset(I) ' Rng.Address = "$B$5" : Rng.Address = "$B$7" : String
- End With ' Rng.Address = "$B$8" : String
- Next
- sh1.[W:Z].Clear ' 清除另闢之戰場 (W 至 Z 欄間內容)
- End Sub
- Function checkShts(vSht As String) As Integer
- Dim flg As Integer
-
- For flg = 1 To Sheets.Count
- If Sheets(flg).Name = vSht Then checkShts = flg: Exit Function
- Next flg
- checkShts = 0
- End Function
複製代碼 |
|
|
|
|
|
|
|
- 帖子
- 522
- 主題
- 36
- 精華
- 1
- 積分
- 603
- 點名
- 0
- 作業系統
- win xp sp3
- 軟體版本
- Office 2003
- 閱讀權限
- 50
- 性別
- 男
- 註冊時間
- 2012-12-13
- 最後登錄
- 2021-7-11
|
12#
發表於 2016-2-21 13:40
| 只看該作者
'借用 c大 的概念, 新增分頁, 這樣較有彈性
'請貼到 "彙總表"
'彙出到分頁3
'判判分頁是否存在
Function shExist(ByVal shName As String) As Boolean
Dim I As Integer
shExist = False
For I = 1 To Sheets.Count
If Sheets(I).Name = shName Then
shExist = True
Exit Function
End If
Next
End Function
Sub 彙出到分頁3()
Dim sh1 As Worksheet
Dim Lst1 As Integer, shNameCnt As Integer
Dim I As Integer, J As Integer
'********************
'清除分頁內容, 如有其他重要分頁, 如"統計"等, 兩列*****間, 請註解掉或刪掉
For J = 1 To Sheets.Count
If Sheets(J).Name <> "彙總表" Then Sheets(J).Cells.Clear
Next
'**************
'加入原序號, 方便恢復原狀(暫放欄A,可改放別欄)
Lst1 = [B65536].End(xlUp).Row
[A5] = 1: Range("A5:A" & Lst1).DataSeries
'按工作表名稱排序
[A5].Resize(Lst1 - 5, 5).Sort Key1:=[B5], Order1:=xlAscending, Header:=xlNo
For I = 5 To Lst1
shName = Cells(I, 2)
'判判分頁是否存在, 如不存在則新增一頁
If Not shExist(shName) Then
Set sh1 = Sheets.Add(After:=Sheets(Sheets.Count))
sh1.Name = shName
End If
[C4:E4].Copy Sheets(shName).[C4] '複製標題
[C3].FormulaR1C1 = "=COUNTIF(C[-1],""=""&R" & I & "C[-1])" '計算同名的工作表有幾個
Cells(I, 2).Resize([C3], 4).Copy Sheets(shName).[B5] '批次複製
I = I + [C3] - 1
Next
'恢復原狀, 按原序號排序, 並清除暫存區
[A5].Resize(Lst1 - 5, 5).Sort Key1:=[A5], Order1:=xlAscending, Header:=xlNo
[A:A].Clear: [C3].Clear '欄A 及 [C3] 均為暫存區
End Sub |
|
|
|
|
|
|
|
- 帖子
- 2848
- 主題
- 10
- 精華
- 0
- 積分
- 2903
- 點名
- 0
- 作業系統
- 〔略〕
- 軟體版本
- 〔略〕
- 閱讀權限
- 100
- 性別
- 男
- 來自
- 〔略〕
- 註冊時間
- 2013-5-13
- 最後登錄
- 2026-7-25
|
13#
發表於 2016-2-21 20:11
| 只看該作者
篩選法!!!
Sub Macro1()
Dim xArea As Range, i&, T$, TT$, Sht As Worksheet
Set xArea = Range([B4], Cells(Rows.Count, "B").End(xlUp)(1, 4))
For i = 2 To xArea.Rows.Count
T = xArea(i, 1): Set Sht = Nothing
If T = "" Or InStr(TT & "/", "/" & T & "/") Then GoTo 101
On Error Resume Next: Set Sht = Sheets(T): On Error GoTo 0
If Sht Is Nothing Then Set Sht = Sheets.Add(After:=Sheets(Sheets.Count))
Sht.Name = T: Sht.UsedRange.Clear
With xArea
.Parent.Select
.AutoFilter Field:=1, Criteria1:=T
.Copy Sht.[B4]
End With
TT = TT & "/" & T
101: Next i
ActiveSheet.AutoFilterMode = False
End Sub |
|
|
|
|
|
|
|
- 帖子
- 522
- 主題
- 36
- 精華
- 1
- 積分
- 603
- 點名
- 0
- 作業系統
- win xp sp3
- 軟體版本
- Office 2003
- 閱讀權限
- 50
- 性別
- 男
- 註冊時間
- 2012-12-13
- 最後登錄
- 2021-7-11
|
14#
發表於 2016-2-22 10:22
| 只看該作者
回復 13# 准提部林
准大你好!!
又學到一招, 直接
Set Sht = Nothing
If T = "" Or InStr(TT & "/", "/" & T & "/") Then GoTo 101
On Error Resume Next
Set Sht = Sheets(T)
On Error GoTo 0
If Sht Is Nothing Then
Set Sht = Sheets.Add(After:=Sheets(Sheets.Count))
End If
就可以不必先判斷sht是否存在,真高, 收下, 謝謝!!
但請問 InStr(TT & "/", "/" & T & "/") 的作用是什麼?謝謝!! |
|
|
|
|
|
|
|
- 帖子
- 552
- 主題
- 6
- 精華
- 0
- 積分
- 576
- 點名
- 0
- 作業系統
- win7
- 軟體版本
- office 2010
- 閱讀權限
- 50
- 性別
- 男
- 註冊時間
- 2015-2-8
- 最後登錄
- 2026-9-10
  
|
15#
發表於 2016-2-22 11:40
| 只看該作者
回復 14# yen956
我想InStr(TT & "/", "/" & T & "/")的意思為
當第一次讀取過的工作表名稱會寫入到變數TT的字串中,因為已經做過篩選了,所以當再次讀取到曾記錄過的名稱時跳過
而"/"則是要區分各工作表名的區隔,不會重覆,讓InStr容易判斷,而不會產生錯誤的判斷 |
|
|
|
|
|
|
|
- 帖子
- 2848
- 主題
- 10
- 精華
- 0
- 積分
- 2903
- 點名
- 0
- 作業系統
- 〔略〕
- 軟體版本
- 〔略〕
- 閱讀權限
- 100
- 性別
- 男
- 來自
- 〔略〕
- 註冊時間
- 2013-5-13
- 最後登錄
- 2026-7-25
|
16#
發表於 2016-2-22 12:00
| 只看該作者
本帖最後由 准提部林 於 2016-2-22 12:06 編輯
回復 15# lpk187
完全正確, 謝謝大出力解釋!
InStr(TT & "/", "/" & T & "/") 用"/'分隔,可以清楚分別 A AA AAA 或 A1 A11 A111,而不會誤判!!
而且理論上,工作表名稱不會有"/"字元,若用其它符號,就要考慮工作表表名稱是否含有這個符號,
例如:用"-"分隔,就可能對 1-1 1-11 1-111 相似工作表誤判!! |
|
|
|
|
|
|
|
- 帖子
- 522
- 主題
- 36
- 精華
- 1
- 積分
- 603
- 點名
- 0
- 作業系統
- win xp sp3
- 軟體版本
- Office 2003
- 閱讀權限
- 50
- 性別
- 男
- 註冊時間
- 2012-12-13
- 最後登錄
- 2021-7-11
|
17#
發表於 2016-2-22 12:30
| 只看該作者
回復 16# 准提部林
回復 lpk187:
回復 准大:
謝謝兩位詳細的說明, 謝謝!! |
|
|
|
|
|
|
|
- 帖子
- 522
- 主題
- 36
- 精華
- 1
- 積分
- 603
- 點名
- 0
- 作業系統
- win xp sp3
- 軟體版本
- Office 2003
- 閱讀權限
- 50
- 性別
- 男
- 註冊時間
- 2012-12-13
- 最後登錄
- 2021-7-11
|
18#
發表於 2016-2-22 15:48
| 只看該作者
'彙出到分頁4(純自我學習 VBA 用, 別無它意):
'更新版, 更新重點如下:
'1. 既然 欄A及[C3] 均為暫存區, 則應整合到同一欄中, 故[C3]應改到[A3]
'2. 兩列*****間的 清除分頁 應移 "主程式" 式內, 可避免誤刪重要資料
'3. 改用准大的概念, 不另判別分頁是否存在, 即刪除 Function shExist, 可省掉不少迴圈
'
'更正結果如下:
'請貼到 "彙總表"
Sub 彙出到分頁4()
Dim sh1 As Worksheet
Dim Lst1 As Integer, shName As String
Dim i As Integer, J As Integer
Lst1 = [B65536].End(xlUp).Row
'加入原序號, 方便恢復原狀(暫放欄A,可改放別欄)
[A5] = 1: Range("A5:A" & Lst1).DataSeries
'按工作表名稱排序
[A5].Resize(Lst1 - 5, 5).Sort Key1:=[B5], Order1:=xlAscending, Header:=xlNo
'主程式
For i = 5 To Lst1
shName = Cells(i, 2)
Set sh1 = Nothing
On Error Resume Next
Set sh1 = Sheets(shName)
On Error GoTo 0
'若 sh1 仍為 Nothing → 名為 shName 的工作表並不存在 → 增加新工作表
If sh1 Is Nothing Then
Set sh1 = Sheets.Add(After:=Sheets(Sheets.Count))
sh1.Name = shName
End If
sh1.Cells.Clear '清除分頁
[B4:E4].Copy sh1.[B4] '複製標題
[A3].FormulaR1C1 = "=COUNTIF(C[1],""=""&R" & i & "C[1])" '計算同名的工作表有幾個
Cells(i, 2).Resize([A3], 4).Copy sh1.[B5] '批次複製同名的工作表
i = i + [A3] - 1 '跳到下個不同名工作表, 故不用篩選
Next
'恢復原狀 → 按原序號排, 並清除暫存區
[A5].Resize(Lst1 - 5, 5).Sort Key1:=[A5], Order1:=xlAscending, Header:=xlNo
[A:A].Clear '清除暫存區 欄A
End Sub |
|
|
|
|
|
|
|
- 帖子
- 2035
- 主題
- 24
- 精華
- 0
- 積分
- 2031
- 點名
- 0
- 作業系統
- Win7
- 軟體版本
- Office2010
- 閱讀權限
- 100
- 性別
- 男
- 註冊時間
- 2012-3-22
- 最後登錄
- 2024-2-1
|
20#
發表於 2016-2-23 09:21
| 只看該作者
本帖最後由 c_c_lai 於 2016-2-23 09:22 編輯
回復 19# Hsieh - sh.[B4].Resize(UBound(ay) + 1, 4) = Application.Transpose(Application.Transpose(ay))
複製代碼 執行到此行,即產生 "型態不符 (#13)" |
|
|
|
|
|
|
|