- 积分
- 4144
好友
记录
日志
相册
回帖0
主题
分享
精华
威望 旺
钢镚 分
推荐 人
|
018.将总表按任意列拆分成多个工作簿
. r) v0 W7 m5 v* M8 G/ [
0 ?: R$ Y2 f7 r ?2 @& B1 T9 }0 L: t. q
Sub SplitShts()# R# M7 h" E- ]8 d& [
Dim d As Object, sht As Worksheet7 n/ I( s J6 t4 j1 S) U
Dim aData, aResult, aTemp, aKeys, i&, j&, k&, x&
5 N. [$ P7 W0 ]) `' d4 p% H Dim rngData As Range, rngGist As Range, ws As Workbook
3 i& M z( R, d1 ?$ [: _& i Dim lngTitleCount&, lngGistCol&, lngColCount&
5 [0 y* K0 r$ r- H: [9 c Dim rngFormat As Range, aRef, strYesOrNo As String
. Z* n5 ?2 ]4 A- H Dim strKey As String, strTemp As String, strPath As String
, y0 p6 M5 I* b. p: X6 A% f On Error Resume Next '忽略错误,程序继续运行; l# }8 J k3 d
Set d = CreateObject("scripting.dictionary")) S' M7 b+ j! C7 c, ]5 Y
With Application.FileDialog(msoFileDialogFolderPicker)2 q) Q& u2 ]' D$ _& ~' M) o
'用户选择保存工作簿的路径
* b( y; F$ J1 X5 @" B( j4 w$ B If .Show Then strPath = .SelectedItems(1) Else Exit Sub# F Q! g3 O/ A+ M
End With: Z$ S4 Y7 q8 Z$ U9 h
If Right(strPath, 1) <> "\" Then strPath = strPath & "\": h& q. L& T, U6 W1 V: k
Set rngGist = Application.InputBox("请框选拆分依据列!只能选择单列单元格区域!", Title:="提示", Type:=8)& q8 x* g3 i7 Q( q' [, Y
'用户选择的拆分依据列" t9 g Z8 E! J' H* f
If rngGist Is Nothing Then Exit Sub
& ~* k1 W/ R2 l X lngGistCol = rngGist.Column '拆分依据列的列标
3 e. {+ d. g( S- |1 g9 I9 K8 E lngTitleCount = Val(Application.InputBox("请输入总表标题行的行数?", Default:=1))
& Z, N7 O: h) d+ g% P '用户设置总表的标题行数( Q/ S$ c5 a" G! f/ t+ ^; ^
If lngTitleCount < 0 Then MsgBox "标题行数不能为负数,程序退出。": Exit Sub
& E* D R6 ]! ~ strYesOrNo = MsgBox("是否需要在分表保留总表格式?", vbYesNo)8 u2 f- C: r& N d
Set rngData = rngGist.Parent.UsedRange
+ m7 L T8 O: O0 t [' p. f* n/ I '总表的数据区域7 [+ C; X4 Y0 A6 z$ _: ~: J
Set rngFormat = rngGist.Parent.Cells
- G. `. }. W3 [, c2 Q5 ^5 h '总表的单元格区域用于粘贴总表格式2 `: x1 z; @! i( s# b6 Y
aData = rngData.Value '数据源装入数组
1 B7 O9 }: L/ u& |) Y3 @9 T5 F) J+ K lngGistCol = lngGistCol - rngData.Column + 17 g, z4 P3 S+ q8 C
'计算依据列在数组中的位置
8 M# i2 e- y7 x, e* W/ x) e lngColCount = UBound(aData, 2)
, Z# b9 a% m- y- |" n. Y '数据源的列数" X9 k H- Z# P' k% `
Application.ScreenUpdating = False
6 j! C% o# m5 L( ~ Application.DisplayAlerts = False+ A8 M9 r; y7 V& B7 \
ReDim aRef(1 To UBound(aData))" t: b$ N% t# T+ ?, I3 E( ~5 `
For i = 1 To UBound(aData) '处理依据列的异常值,空白/错误值/整行空白等
" G- v! u8 W* F2 U# R, M2 g( C4 ~ If IsError(aData(i, lngGistCol)) Then
$ e, o ], M' ~" { aRef(i) = "错误值"
' L0 C3 H- ?/ P8 {7 j ElseIf aData(i, lngGistCol) = "" Then+ A' R9 ^; \. b% O/ `
strTemp = "" '判断是否整行数据为空
9 v/ v9 H/ Q2 x- S" ]3 u5 l, P For j = 1 To lngColCount% |5 J" v$ p; y9 Z O' y4 V; e) J/ t
strTemp = strTemp & aData(i, j)0 E L$ Z' U/ o8 z
Next/ I$ e3 a4 @) T) _" B6 Z2 _
If strTemp = "" Then '如果整行为空6 V- ~: U; S- u
aRef(i) = "整行空白"
+ E- q5 b6 e% I8 P Else
- X. l, `+ a. r aRef(i) = "空白单元格"
8 k% J5 Z8 M$ d' F% x End If& l H* h) }' c& `
Else
& S$ |: z0 n* N) B/ I: o* Z' p strKey = aData(i, lngGistCol)
+ Q" h5 t) |( L$ {. c9 _1 y7 Z, J aRef(i) = strKey0 [, F6 k/ C% |* e
End If
( K$ U' H, t( v9 L& k) X6 V Next3 N+ O( K+ U" x9 M0 \: _4 Z
For i = lngTitleCount + 1 To UBound(aData)! G# J2 e7 o6 E( ^% r. a( Q
strKey = aRef(i)+ p# C( p# \$ d0 v6 r
If strKey <> "整行空白" Then4 H# H7 } q% p% \- ]& C
If Not d.exists(strKey) Then1 F. h( M( W- M- T6 H
'字典中不存在关键字时则遍历建表/ V' v% \* m& C! X. _1 X; z
d(strKey) = "") P4 s B; a5 @3 y4 J2 I& x7 `
ReDim aResult(1 To UBound(aData), 1 To lngColCount) '声明一个结果数组
: J: ^# {( l9 F- n; A/ k k = 0
$ } o( ^. U9 D, C9 i5 T For x = lngTitleCount + 1 To UBound(aData) '遍历数据源
% X: ~$ x& e9 S8 V v strTemp = aRef(x)
9 {9 }! ^6 ]( a% P) V If strTemp = strKey Then '如果记录符合条件,则装入结果数组
. X0 n; w+ j/ J v Z k = k + 1
& S U' g! b/ Z0 x8 R Y- A7 {, | For j = 1 To lngColCount
& x, G; [+ R, m+ k& n+ \+ O aResult(k, j) = aData(x, j)5 [/ F4 r/ W. T6 m* x- @
Next
; ]# C5 I- s0 X End If
; y- t6 d0 x- o; j6 }# F, D. s Next
$ `0 M+ b: W. z' U& Q: L Set ws = Workbooks.Add0 G! q _! { [2 r% r) E/ R4 O) c
With ws.Sheets(1)
/ t$ A4 G. E' g* @9 |; @7 h% h '新建一个工作簿0 h: Q- w% w7 ] l
.Range("a1").Resize(UBound(aData), lngColCount).NumberFormat = "@"
2 R- \4 a, T% a8 e/ J) k '设置单元格为文本格式% J; L9 p5 ~: i8 x+ P& g/ s. F
If lngTitleCount > 0 Then .Range("a1").Resize(lngTitleCount, lngColCount) = aData% [7 }0 t) l" ^ l9 T4 ]$ D
'标题行
3 C* H. B9 w& E: T .Range("a1").Offset(lngTitleCount, 0).Resize(k, lngColCount) = aResult
3 d9 }% u6 _$ X' Z- M# R '写入数据0 _, }) f) b1 C8 \9 j
If strYesOrNo = vbYes Then '如果用户选择保留总表格式
: u0 f, @# p8 J' k rngFormat.Copy7 O/ f' y+ | i7 |; R
.Range("a1").PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
6 L3 l7 I- H, d; w '复制粘贴总表的格式
) Z/ z! i9 o, g' H .Range("a1").Offset(lngTitleCount + k, 0).Resize(UBound(aData) - k - lngTitleCount, 1).EntireRow.Delete5 P5 j$ M& `1 Q2 ~3 ^9 M% _- O
'删除多余的格式单元格* }, i9 L& P: y/ F9 c) |, ?
End If
0 M8 l) s7 l8 Y& @9 H" K .Range("a1").Select6 g4 Z. {: J* G6 F* \/ v5 ^8 J% u
End With: ?1 T5 z; U6 M2 z+ B9 u
ws.SaveAs strPath & strKey, xlWorkbookDefault3 ^% S$ V; @, j8 X1 |- L! H
ws.Close False
6 x& P- s8 S" ]) a: Y' h, m- U End If! t. W8 P7 f) B
End If1 W; ^7 _& r: V
Next* L/ N7 I% C4 B
Application.ScreenUpdating = True0 a$ l# _# k0 h
Application.DisplayAlerts = True
4 e h( o' U: A" `" f Z Set d = Nothing
9 B3 }6 [4 x- Y Set rngData = Nothing
. ~( B" [8 P, G, A: k Set rngGist = Nothing I& `7 d; z' U) [
Set rngFormat = Nothing
3 A+ W: c* n8 b% o Erase aData: Erase aResult* }, [2 {1 p, G2 Z3 @
MsgBox "数据拆分完成!", v" |7 U- N Y' [" c
End Sub |
|