VBA 根据表格指定列拆分多sheet

news2025/2/22 19:44:42

一. 需求

⏹ 根据部分列,拆分数据到多个sheet页

在这里插入图片描述


二. 代码

⏹ 重点代码摘要

  • CreateObject("scripting.dictionary"):创建一个字典对象,相当于Java中的Map
  • Dim aRef() As String:定义一个存储字符串类型的数组
  • ReDim aRef(1 To UBound(aData)):在声明数组时不指定大小,而在后续需要时再使用ReDim语句来动态调整数组的大小。
  • .Parent.UsedRange:根据用户所选范围选中包含该范围的父级工作表,然后通过UsedRange属性来获取该工作表中已经使用的单元格范围。
  • 2维数组aData的数据格式
    ' aData
    [
       ["年份", "日期", "部门"],
       ["2008年", "1月", "客服"],
       ["2009年", "2月", "财务"]
       ......
    ]
    
    lngColCount = UBound(aData, 2):获取2维数组中,第2维数组的长度 。

⏹ VBA代码

Sub SplitShts()

    Dim d As Object, sht As Worksheet
    Dim aData, aResult, aTemp, aKeys, i&, j&, k&, x&
    Dim rngData As Range, rngGist As Range
    Dim lngTitleCount&, lngGistCol&, lngColCount&
    Dim rngFormat As Range, strYesOrNo As String
    ' 定义一个存放字符串类型数据的数组
    Dim aRef() As String
    Dim strKey As String, strTemp As String
    ' 忽略错误,程序继续运行
    On Error Resume Next 
    
    ' 创建了一个字典对象(相当于java中的Map)
    Set d = CreateObject("scripting.dictionary")
    
    ' 用户选择的拆分依据列
    Set rngGist = Application.InputBox("请框选拆分依据列!只能选择单列单元格区域!", Title:="提示", Type:=8)
    ' 拆分依据列的列标
    lngGistCol = rngGist.Column
    ' 用户设置总表的标题行数
    lngTitleCount = Val(Application.InputBox("请输入总表标题行的行数?", Default:=1))
    
    If lngTitleCount < 0 Then 
        MsgBox "标题行数不能为负数,程序退出。": Exit Sub
    End If
    
    ' 让用户选择是否在分表保留总表的格式
    strYesOrNo = MsgBox("是否需要在分表保留总表格式?", vbYesNo)
    
    ' 总表的数据区域
    Set rngData = rngGist.Parent.UsedRange
    ' 总表的单元格区域用于粘贴总表格式 
    Set rngFormat = rngGist.Parent.Cells
   
    ' 2维数组aData的数据格式
    ' [
    '   ["年份", "日期", "部门"],
    '   ["2008年", "1月", "客服"],
    '   ["2009年", "2月", "财务"]
    '   ......
    ' ]
    aData = rngData.Value
    ' 计算依据列在数组中的位置
    lngGistCol = lngGistCol - rngData.Column + 1
    ' 数据源的列数(2维数组中,第2维数组的长度)
    lngColCount = UBound(aData, 2)
    
    ' 关闭代码执行时屏幕刷新
    Application.ScreenUpdating = False
    ' 不允许显示警告对话框
    Application.DisplayAlerts = False
    
    ' 在VBA中,可以在声明数组时不指定大小,而在后续需要时再使用ReDim语句来动态调整数组的大小。
    ReDim aRef(1 To UBound(aData))
    
    For i = 1 To UBound(aData) 
    
        ' 处理依据列的异常值,空白/错误值/整行空白等
        If IsError(aData(i, lngGistCol)) Then
            aRef(i) = "错误值"
        ElseIf aData(i, lngGistCol) = "" Then
        
            ' 判断是否整行数据为空
            strTemp = "" 
            For j = 1 To lngColCount
                strTemp = strTemp & aData(i, j)
            Next
            
            ' 如果整行为空
            If strTemp = "" Then 
                aRef(i) = "整行空白"
            Else
                aRef(i) = "空白单元格"
            End If
        Else
            strKey = aData(i, lngGistCol)
            aRef(i) = strKey
        End If
    Next
    
    For i = lngTitleCount + 1 To UBound(aData)
    
        ' 从数组中获取部门名称
        strKey = aRef(i)
        
        ' 若满足条件,则跳出本次循环
        If strKey = "整行空白" Then
            Exit For
        End If
        
        ' 字典中存在关键字时则跳过本次循环
        If d.exists(strKey) Then
            Exit For
        End If
        
        d(strKey) = ""
        
        ' 声明一个结果数组
        ReDim aResult(1 To UBound(aData), 1 To lngColCount) 
        
        k = 0
        
        ' 遍历数据源
        For x = lngTitleCount + 1 To UBound(aData) 
            strTemp = aRef(x)
            ' 如果记录符合条件,则装入结果数组
            If strTemp = strKey Then 
                k = k + 1
                For j = 1 To lngColCount
                    aResult(k, j) = aData(x, j)
                Next
            End If
        Next
        
        ' 删除旧表
        For Each sht In ActiveWorkbook.Worksheets 
            If sht.Name = strKey Then sht.Delete
        Next
        
        ' 新建一个工作表
        With Worksheets.Add(, Sheets(Sheets.Count))
        
            .Name = strKey
            ' 设置单元格为文本格式
            .Range("a1").Resize(UBound(aData), lngColCount).NumberFormat = "@"
            
            ' 标题行
            If lngTitleCount > 0 Then 
                .Range("a1").Resize(lngTitleCount, lngColCount) = aData
            End If
            
            ' 写入数据
            .Range("a1").Offset(lngTitleCount, 0).Resize(k, lngColCount) = aResult
            
            ' 如果用户选择保留总表格式
            If strYesOrNo = vbYes Then 
                rngFormat.Copy
                ' 复制粘贴总表的格式
                .Range("a1").PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
                ' 删除多余的格式单元格 
                .Range("a1").Offset(lngTitleCount + k, 0).Resize(UBound(aData) - k - lngTitleCount, 1).EntireRow.Delete
            End If
            
            .Range("a1").Select
        End With
    Next
    
    ' 回到总表
    rngData.Parent.Activate 
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
    
    ' 释放
    Set d = Nothing
    Set rngData = Nothing
    Set rngGist = Nothing
    Set rngFormat = Nothing
    Erase aData: Erase aResult
    
    MsgBox "数据拆分完成!"
    
End Sub

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1641729.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux学习之IP协议

前言&#xff1a; 在学习IP协议i前&#xff0c;我们其实知道网络协议栈是一层层的&#xff0c;上层封装好之后就传给下层&#xff0c;对于我们治安学习到的TCP协议&#xff0c;在对数据进行封装之后&#xff0c;并不是直接就将数据进行传输&#xff0c;而是交给下一层网络层进…

【讲解如何OpenCV入门】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

GDPU unity游戏开发 碰撞器与触发器

砰砰叫&#xff0c;谁动了她的奶酪让你的小鹿乱撞了。基于此&#xff0c;亦即碰撞与触发的过程。 碰撞器与触发器的区别 通俗点讲&#xff0c;碰撞器检测碰撞&#xff0c;触发器检测触发&#xff0c;讲了跟没讲似的。碰撞器是用来检测碰撞事件的&#xff0c;在unity中&#xff…

发表博客之:transformer 架构 推理时候运算流程详细讲解,小白都可以看得懂,AI推理工程师必备技能!

文章目录 [发表博客之&#xff1a;transformer 架构 推理时候 详细讲解&#xff0c;小白都可以看得懂&#xff0c;AI推理工程师必备技能&#xff01;](https://cyj666.blog.csdn.net/article/details/138439826)总结一下 发表博客之&#xff1a;transformer 架构 推理时候 详细…

[每日AI·0501]GitHub 版 Devin,Transformer的强力挑战者 Mamba,Sora 制作细节与踩坑,OpenAI 记忆功能

AI 资讯 国资委&#xff1a;加快人工智能等新技术与制造全过程、全要素深度融合GitHub版 Devin 上线&#xff0c;会打字就能开发应用&#xff0c;微软 CEO&#xff1a;重新定义 IDE在12个视频理解任务中&#xff0c;Mamba 先打败了 TransformerSora 会颠覆电影制作吗&#xff…

Python | Leetcode Python题解之第66题加一

题目&#xff1a; 题解&#xff1a; class Solution:def plusOne(self, digits: List[int]) -> List[int]:n len(digits)for i in range(n - 1, -1, -1):if digits[i] ! 9:digits[i] 1for j in range(i 1, n):digits[j] 0return digits# digits 中所有的元素均为 9retu…

Java——认识异常

目录 一.异常的概念与体系结构 1.异常的概念 1.1算术异常 1.2数组越界异常 1.3空指针异常 2.异常的体系结构 3.异常的分类 3.1编译时异常 3.2运行时异常 二.异常的处理 1.防御式编程 1.1LBYL 1.2EAFP&#xff08;核心&#xff09; 2.异常的抛出 3.异常的捕获 3…

1081 检查密码(测试点2简析)

solution 潜在的非法字符里可能包含空格&#xff0c;所以不能直接用cin接收string&#xff08;测试点2&#xff09; #include<iostream> #include<string> using namespace std; int judge(string s){if(s.size() < 6) return 1;int num 0, c 0;for(int i …

C++基础——输入输出(文件)

一、标准输入输出流 C 的输入输出是程序与用户或外部设备&#xff08;如文件、网络等&#xff09;之间交换信息的过程。 C 提供了丰富的标准库来支持这种交互&#xff0c;主要通过流的概念来实现。 流&#xff1a;抽象概念&#xff0c;表示一连串的数据&#xff08;字节或字…

Python爬虫--爬取糗事百科段子

爬取糗事百科段子&#xff1a; 段子在 <div class"content"> 里面的 <span> 标签里面 不过这里有个坑&#xff0c;div 标签跟 span 标签 之间有很多空行 普通 .*? 是匹配不了的&#xff0c;需要使用模式修饰符 S S 的意思 让 .(点) 匹配&#xff0c…

政安晨:【Keras机器学习示例演绎】(三十一)—— 梯度集中,提高训练效果

目录 简介 设置 准备数据 使用数据增强 定义模型 实现梯度集中化 训练工具 不使用 GC 训练模型 使用 GC 训练模型 性能比较 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对…

基于php+mysql+html简单图书管理系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、Php、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

C#语言入门

一、基础知识 1. 程序语言是什么 用于人和计算机进行交流&#xff0c;通过程序语言让计算机能够响应我们发出的指令 2. 开发环境 IDE&#xff0c;集成开发环境。它就是一类用于程序开发的软件&#xff0c;这一类软件一般包括了代码编辑、编译器、调试器、图形用户界面等等工…

springboot 整合 knife4j-openapi3

适用于&#xff1a;项目已使用shiro安全认证框架&#xff0c;整合knife4j-openapi3 1.引入依赖 <!-- knife4j-openapi3 --> <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-spring-boot-starter</artifa…

【C语言】——结构体

【C语言】——结构体 一、结构体类型的声明1.1、结构体的声明1.2、结构体变量的创建和初始化1.3、结构体的特殊声明1.4、结构体的自引用1.5、结构体的重命名 二、 结构体的内存对齐2.1、对齐规则2.2、结构体对齐实践2.3、为什么存在内存对齐2.4、修改默认对齐数 三、结构体传参…

数据库(MySQL)—— 多表查询

数据库&#xff08;MySQL&#xff09;—— 多表查询 多表关系一对多多对多一对一多表查询概述数据准备查询形式笛卡尔积 分类连接查询内连接外连接左外连接右外连接 自连接联合查询 今天我们来进入MySQL中一个非常重要的部分&#xff1a;多表查询&#xff1a; 多表关系 多表关…

【HM】DevEco Studio如何使用代码编程AI助手

大家可能都有用过或了解过github copilot插件&#xff0c;确实为我们编码智能、提升开发效率有很大的帮助。推荐两款国产的ai编程插件&#xff0c;分别是华为的CodeArts Snap和阿里的通义灵码。 DevEco 中如何安装通义灵码&#xff1f; 一、下载通义灵码离线安装包 打开官网…

数组邻接表+堆优化版dijkstra+蓝桥杯2022年第十三届决赛真题-出差

文章目录 邻接表数组实现堆优化版dijkstra蓝桥杯2022年第十三届决赛真题-出差 邻接表数组实现 idx是每条边的地址e保存终点的节点值w保存每条边的权值ne[idx]保存边表&#xff0c;idx的下一个顶点的地址h[a]保存顶点表&#xff0c;a是起点&#xff0c;h[a]是终点的地址 int e…

docker-compose单机容器集群编排工具

前言&#xff1a; docker-compose用来单机上编排容器&#xff08;定义和运行多个容器&#xff0c;使容器能互通&#xff09; Eg&#xff1a;前端和后端部署在一台机器上&#xff0c;现在直接通过编写docker-compose文件对多个服务&#xff08;可定义依赖&#xff0c;按顺序启…

conda环境安装的pyproj包报错

conda环境安装的pyproj包报错 文章目录 conda环境安装的pyproj包报错问题解决参考 问题 在conda创建的Python3.9虚拟环境中安装pyproj包3.6在运行时出现以下报错 UserWarning: pyproj unable to set database path. _pyproj_global_context_initialize()解决 先激活并进入创…