前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VBA拆分表格

VBA拆分表格

作者头像
xyj
发布2020-07-28 10:09:10
1.4K0
发布2020-07-28 10:09:10
举报
文章被收录于专栏:VBA 学习VBA 学习

1、需求:

根据某一列内容,将1个Sheet表格拆分为多个分表。

2、举例:

还是接着上一次的例子,分年龄段统计人数工作完成后,你又接到任务需要将总表根据年龄段拆分为多个分表。

因为例子里只有5个年龄段,所以你完全可以筛选复制5次就搞定了,不过,如果后面又有变化,比如需要根据职务或者其他情况来拆分,那你又得手动去处理了,让我们看看用VBA代码如何来完成这个工作,一旦情况变化,你只要重新运行一次程序就可以。

3、代码实现

这个功能的实现原理其实和筛选也差不多,我们需要获取作为拆分表格列的不重复项目,然后得到每一个不重复项目的单元格,再复制单元格就可以了。

要获取不重复的项目,字典自然是最好的选择,我们使用字典对象来记录每一个关键字对应的所有单元格,最后将字典记录下来的单元格复制到新表即可:

代码语言:javascript
复制
Enum RetCode
    ErrRT = -1
    SuccRT = 1
End Enum

Enum Pos
    RowStart = 2
    
    年龄段 = 6
    
    KeyCol = 年龄段
    Cols = 年龄段
End Enum

Type DataStruct
    Src() As Variant
    Rows As Long
    Cols As Long
    
    Result() As Variant
End Type

Sub vba_main()
    Dim d As DataStruct
    
    If RetCode.ErrRT = ReadSrc(d) Then Exit Sub
    If RetCode.ErrRT = GetResult(d) Then Exit Sub
End Sub

Private Function GetResult(d As DataStruct) As RetCode
    Dim dic As Object

    Set dic = VBA.CreateObject("Scripting.Dictionary")
    
    Dim i As Long
    Dim strkey As String
    For i = Pos.RowStart To d.Rows
        strkey = VBA.CStr(d.Src(i, Pos.KeyCol))
        If dic.Exists(strkey) Then
            '再次出现的关键字,合并
            Set dic(strkey) = Excel.Union(Cells(i, 1).Resize(1, Pos.Cols), dic(strkey))
        Else
            '第一次出现的关键字,记录标题及当前行单元格
            Set dic(strkey) = Excel.Union(Cells(1, 1).Resize(1, Pos.Cols), Cells(i, 1).Resize(1, Pos.Cols))
        End If
    Next
    
    Dim keys As Variant
    keys = dic.keys()
    Dim items As Variant
    items = dic.items()
    '新建表并复制单元格
    For i = 0 To UBound(keys)
        strkey = VBA.CStr(keys(i))
        '注:这里没有去考虑sheet的名称是否合规,sheet名称是不能包含" / \ 等字符的"
        Worksheets.Add().Name = strkey
        items(i).Copy Range("A1")
    Next
End Function

Private Function ReadSrc(d As DataStruct) As RetCode
    ReadSrc = ReadData(d.Src, d.Rows, Pos.Cols, Pos.KeyCol, Pos.RowStart)
End Function

Private Function ReadData(ByRef RetArr() As Variant, ByRef RetRow As Long, Cols As Long, KeyCol As Long, RowStart As Long) As RetCode
    ActiveSheet.AutoFilterMode = False
    RetRow = Cells(Cells.Rows.Count, KeyCol).End(xlUp).Row
    If RetRow < RowStart Then
        MsgBox "没有数据"
        ReadData = RetCode.ErrRT
        Exit Function
    End If
    RetArr = Cells(1, 1).Resize(RetRow, Cols).Value

    ReadData = RetCode.SuccRT
End Function

如果后面需求有变化,需要按别的列进行拆分,只要修改Pos枚举里的KeyCol即可。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 VBA 学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档