当前位置:首页 > 办公设计 > Office教程 > 写几段代码,将总表按任意列拆分为多个工作簿

写几段代码,将总表按任意列拆分为多个工作簿

1年前 (2025-05-24)Office教程1610

大家好,我是星光。
今天和大家分享的VBA小代码是:一键将总表按任意列拆分为多个工作簿

什么意思呢?举个小栗子。
如下图所示,是一张总表,现在需要按任意列,比如班级列吧,将它拆分为多个工作簿。

动画演示如下:

VBA代码如下:

Sub SplitShByArr()
Dim shtAct As Worksheet, sht As Worksheet, wb As Workbook
Dim rngData As Range, rngGistC As Range, rngTemp As Range
Dim d As Object, aData, aKeys, vnt
Dim intTitCount, strKey As String, strName As String
Dim strADS As String, rngTit As Range
Dim i As Long, j As Long, intFirstR As Long, intLastR As Long
Dim k As Long, x As Long, intActR As Long
Dim intFirstC As Long, intGistC As Long
Dim strPath As String
On Error Resume Next '忽略错误继续运行程序
'
strPath = getStrPath() '用户选择文件保存路径
If strPath = "" Then Exit Sub
'
'获取用户输入的标题行数▼
intTitCount = getTitCount()
If intTitCount = False Then Exit Sub
'
'获取拆分依据列▼
Set rngGistC = GetRngGistC()
If Err.Number Then GoTo errDescript
'
Call disAppSet '取消屏幕刷新等系统设置
'
Set shtAct = ActiveSheet '当前工作表
If shtAct.FilterMode = True Then shtAct.Cells.AutoFilter '取消筛选状态
Set rngData = shtAct.UsedRange '实际区域
aData = rngData.Value '总表数据存入数组aData
intFirstC = rngData.Column '实际区域开始列
intGistC = rngGistC.Column - intFirstC + 1 '依据列在aData中的序列
intFirstR = rngData.Row '实际区域开始行
intActR = intTitCount - intFirstR + 2 '扣除标题的数组开始行
intLastR = GetintLastR(shtAct) '实际区域结束行
With shtAct '标题区域
Set rngTit = .Range(.Cells(1, 1), _
.Cells(intTitCount, _
UBound(aData, 2) + intFirstC - 1))
End With
'
'参数数组,修正异常数据▼
Set d = CreateObject("scripting.dictionary") '后期字典
ReDim aRef(1 To intLastR) '数组aRef,修正拆分列特殊数据
For i = intActR To UBound(aData)
If i > intLastR Then Exit For '如果大于有效数据最大行则退出循环
vnt = aData(i, intGistC)
If IsError(vnt) Then
aRef(i) = "错误值"
ElseIf vnt = "" Then
aRef(i) = "空白单元格"
ElseIf IsDate(vnt) Then '避免日期斜杠格式无法创建工作簿/表
aRef(i) = Format(vnt, "yyyy-m-d")
Else
aRef(i) = vnt
End If
strKey = aRef(i)
d(strKey) = d(strKey) + 1 '记录不同拆分关键字的数量
Next
'
'通过前8行数据来判断该列是否为特殊的文本数值
For j = 1 To UBound(aData, 2) '遍历列
For i = intActR To UBound(aData) '遍历前8行
If i > 8 Then Exit For
vnt = aData(i, j)
If IsNumeric(vnt) Then '是否数值
If VarType(aData(i, j)) = 8 Then '是否文本
strADS = strADS & "," & Cells(1, j + intFirstC - 1).Address
Exit For
End If
End If
Next
Next
strADS = Mid(strADS, 2) '需要设置文本格式的单元格地址
'
aKeys = d.keys '字典Keys,拆分关键字数组
For i = 0 To UBound(aKeys) '遍历关键字
strName = aKeys(i) '关键字
ReDim aRes(1 To d(strName), 1 To UBound(aData, 2)) '结果数组
k = 0 '计数器归0
'
'筛选符合条件的记录存入结果数组
For x = 1 To UBound(aRef)
If aRef(x) = strName Then '如果关键字符合
k = k + 1 '累加符合条件的行
For j = 1 To UBound(aData, 2) '遍历列
aRes(k, j) = aData(x, j) '数据存入结果数组
Next
End If
Next
'
'建立新工作簿,存放结果数组
Set wb = Workbooks.Add
With wb.Worksheets(1)
.Name = strName '命名
If Err.Number Then '如果名称有特殊字符,则退出程序
.Delete
wb.Close False
GoTo errDescript
End If
If Len(strADS) Then
.Range(strADS).EntireColumn.NumberFormat = "@" '特殊列设置为文本格式
End If
With .Cells(intTitCount + 1, intFirstC).Resize(k, UBound(aRes, 2))
.Value = aRes '结果数组数据写入工作表
End With
.UsedRange.Borders.LineStyle = 1 '设置边框线
rngTit.Copy
.Range("a1").PasteSpecial xlPasteColumnWidths '粘贴列宽
.Range("a1").PasteSpecial xlPasteAll '粘贴标题
End With
wb.SaveAs strPath & strName
wb.Close False
Next
errDescript:
shtAct.Select
Call reAppSet '恢复屏幕刷新等系统设置
Set d = Nothing '释放字典内存
If Err.Number Then
MsgBox Err.Description
Else
MsgBox "拆分完成。"
End If
End Sub

'用户选择文件夹路径
Function getStrPath() As String
Dim strPath As String
With Application.FileDialog(msoFileDialogFolderPicker)
If .Show Then
strPath = .SelectedItems(1)
Else '如用户为选中文件夹则退出
Exit Function
End If
End With
If Right(strPath, 1) <> "\" Then strPath = strPath & "\"
getStrPath = strPath
End Function

'获取用户输入的标题行数
Function getTitCount()
Dim intTitCount
intTitCount = InputBox("请输入标题行的行数", _
Title:="公众号Excel星球", _
Default:=1)
If StrPtr(intTitCount) = False Then
getTitCount = False
Exit Function
End If
If IsNumeric(intTitCount) = False Then
MsgBox "标题行的行数只能输入数字。"
getTitCount = False
Exit Function
End If
If intTitCount < 0 Then MsgBox "标题行数不能为负数。" getTitCount = False Exit Function End If getTitCount = intTitCount End Function '用户选择拆分依据列 Function GetRngGistC() As Range Dim rngGistC As Range Set rngGistC = Application.InputBox("请选择拆分依据列。", _ Title:="公众号Excel星球", _ Default:=Selection.Address, _ Type:=8) If rngGistC Is Nothing Then Exit Function End If If rngGistC.Columns.Count > 1 Then
MsgBox "拆分依据列只能是单列。"
Exit Function
End If
Set GetRngGistC = rngGistC
End Function

'取消屏幕刷新,公式重算等
Sub disAppSet()
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.DisplayAlerts = False
End With
End Sub

'恢复屏幕刷新等
Sub reAppSet()
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.DisplayAlerts = True
End With
End Sub

'最大数据有效行
Function GetintLastR(ByVal sht As Worksheet)
GetintLastR = sht.Cells.Find("*", _
LookIn:=xlFormulas, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious).Row
End Function

代码详细解释见注释,概要说明如下▼

第13至第14行代码,调用getStrPath函数过程,打开文件浏览对话框,允许用户选择任意文件夹作为数据源;如果用户未选取文件夹,则退出程序。

第17至第18行代码,调用getTitCount过程,允许用户输入指定行数的标题行。

第21至第22行代码,调用GetRngGistC过程,允许用户选择拆分依据列。

第24行代码,调用disAppSet过程,取消屏幕刷新等系统设置。

第26至第34行代码将总表数据存入数组aData,并获取获取总表实际存在数据的区域、首列、拆分依据列在实际区域中的第几列、首行和尾行等重要数据。这是由于首行首列未必是第一行第一列,比如本例所示的数据,也就导致拆分依据列的列标未必是实际处理数据的列标。

第35至第39行代码计算标题区域,并赋值变量rngTit。

第41行至第58行代码遍历拆分依据列,处理异常值,比如空格、错误值和可能以”/”为格式的日期值。

第61至第72行代码通过前8行数据判断相关列是否为文本格式,避免文本型数值,比如身份证,在拆分后变形。代码将文本型数值所在的单元格地址赋值变量strADS。

第75至第113行代码按关键字拆分总表数据。其中第82至第89行代码遍历数据源将符合条件的数据存入数组aRes。第92至110行代码新建工作簿,并将结果数组的数据写入该工作簿的首个工作表,并设置标题行。

第118至第122行代码使用MsgBox函数以消息框的形式显示数据拆分结果信息。

……

示例下载,百度网盘▼
https://pan.baidu.com/s/1L2n62GIfURP09QXlIuzOwQ
提取码: tejq

扫描二维码推送至手机访问。

欢迎转载或分享本篇文章。

本文链接:https://www.jcba123.com/article/1625

分享给朋友:

“写几段代码,将总表按任意列拆分为多个工作簿” 的相关文章

5个典型应用,学会Excel高级筛选

5个典型应用,学会Excel高级筛选

1、筛选指定条件的记录 如下图所示,要从数据表中筛选出“产品归类”字段中是“信用贷”的所有记录。 首先在空白单元格中写入要筛选的字段名称和要筛选的条件。 注意字段名称要和数据表中的字段名称完全一样,否则就筛选不出来了。 单击数据区域任意单元格,在【数据】选项卡下单击【高级】按...

Microsoft Excel 教程,如何在 Excel 图表中添加趋势线?

Microsoft Excel 教程,如何在 Excel 图表中添加趋势线?

欢迎观看 Microsoft Excel 教程,小编带大家学习 Microsoft Excel 的使用技巧,了解如何在 Excel 图表中添加趋势线。 向图表添加趋势线,选择图表,选择「图表设计」选项卡,然后单击「添加图表元素」。 选择「趋势线」-「线性」。注意: E...

PPT文字字体拆分效果

PPT文字字体拆分效果

第一步:在PPT软件中,插入一个文本框,并输入您需要的文字。 第二步:点击菜单栏中的"插入"选项,然后选择"形状",插入一个矩形。 第三步:选中文字和矩形,按住Ctrl键(确保两者都被选中)。然后点击菜单栏中的"格式"选项,再点击"合并形状",最后点击"拆分"。此时,文字...

PPT如何分离文本框

PPT如何分离文本框

1.需要将右侧文本框当中的文字提取到左边。 2.在文本框中选中目标文字,单击左键,直接向左边拉动。 3.拉动后,看到文字就已经显示在左边的幻灯片当中。 4.单击工具栏【插入】下的【文本框】,单击在幻灯片左侧插入一个文本框。 5.选中目标文字,按...

做表不用Ctrl键,天天加班八点半

做表不用Ctrl键,天天加班八点半

用Ctrl键与其他键组合,能形成很多快捷键,比如大家最熟悉的Ctrl+C(复制)、Ctrl+V(粘贴)和Ctrl+Z(撤销)。 除此之外,常用的Ctrl系组合键还有Ctrl+A(全选)、Ctrl+S(保存)、Ctrl+F(查找)、Ctrl+H(替换)、Ctrl+X(剪切)、Ctrl+P(打印)、Ct...

数据有效性的几个典型应用,看看你是哪一级

数据有效性的几个典型应用,看看你是哪一级

今天和小伙伴们一起分享数据有效性的几个典型应用。 普通青年这样用 步骤简要说明: 选中区域,设置数据验证,允许条件选择序列,输入要在下拉菜单中显示的内容: 男,女 注意不同选项要使用半角的逗号隔开。   初级青年这样用 步骤简要说明: 选中数据区域,设置数据验证,在【输入信息】选项卡下...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。