ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 905738810

[原创] VBA DataAutomation数据处理类模块,一行代码搞定复杂数据

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-12-2 09:16 | 显示全部楼层

Public Function 开启自动处理(监视单元格区域 As Range, ByVal 函数名 As String) As DataAutomation
内置了工作表 Change事件,开启自动处理后只要监视区域被修改,则会调用回调函数
第1参数:要监视的单元格对象
第2参数:回调函数名(String类型)
使用该函数必须将da类声明到全局
演示:
动图看效果
GIF.gif
静图看代码
image.png
Public Function 关闭自动处理() As DataAutomation
可以关闭开启的自动处理

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-12-2 09:48 | 显示全部楼层
Function GZ(ByVal sr As String) As Variant
方法名演变过程:构造序号-->构造-->GZ
还是构造序号的辅助方法,为什么我给他起了这么简化的名字呢,因为他的强大
如此简单的声明背后都不会简单。
第1参数:构造表达式文本 (本人独创的构造达式)
表达式如下
(重复数量)(计算符+&*)(计算值)[ 值 , 数字下限 - 数字上限 ...]
并且支持表达式嵌套
1)首先表达式需要一个中括号[]
中括号里可以写任意值,或者是一个数字范围比如:1到10写成[1-10]
[]里可以用,英文逗号分隔符写入多个值或范围比如:"[1-4,10,10,10,11-14]"
image.png
2)然后中括号[]左边可以写上重复数量,比如 1,2,3 序列重复3次写成"3[1,2,3]"
image.png
3)再然后中括号重复数量后可以写上每次重复进行(加法+,乘法*,连接&)计算,
比如 1,2,3 序列重复3次每次递增1写成"3+1[1,2,3]"
image.png
4)减法和除法可以用+负数,*小数来解决,如递减"3+-1[1,2,3]"
image.png
5)构造公式可以嵌套嵌套再嵌套...
如"3+3[2[1-3]]"
先重复2次1到3,结果1,2,3,1,2,3
在对结果进行加1操作3次,结果如图:
image.png
6)不仅仅写数字,如"3[a,b,c]"
image.png
7)如果把[,]这些关键字写当成字符串,可以用转译符号/
image.png
到此所有方法全部讲完,完结了

TA的精华主题

TA的得分主题

发表于 2021-12-2 12:35 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-12-3 08:52 | 显示全部楼层
案例解析,我就以这个朋友的贴做案例
excel用VBA按自定义排序
image.png
如图将左边的四个表格标题是乱的,对表格排序,使四个表格的标题顺序对应
解题分析:
1)如果四个表数据整体排序列那么肯定不会的到结果,所以需要将四个表分开处理
这时就应该想到分组
2)分组有很多方法,自定义分组,查找分组,类别分组,条件分组,数量分组,上下不同分组
忘记的可以翻回去看看,自定义应该是最后才考虑的,因为需要回调增加代码量,
根据分析,只要找到标题行就可以可以确定分组位置了,所以我选择查找分组,
代码:da(Range([A1], [D65536].End(3))).按查找内容分组(Array("姓名", "性别", "部门", "次数"), 1)
          先写入数据,然后按查找内容分组,只要找到标题那些关键字,就进行分组,
3)分组后,组里每个单元就是单独的表格了,这样对单元进行排序,不会影响其他单元
4)根据标题排序,可以想到我前面说的辅助方法<根据标题返回序号>这个方法就可以返回标题对应的序号
再使用<转换列>方法就可以转换列的顺序,忘的可以回顾70楼看看根据标题返回序号
注意的是,对组的每个单元操作肯定是要遍历他,所以使用遍历组方法,先遍历,在遍历组的回调函数进行单元操作
代码: Call da(Range([A1], [D65536].End(3))).按查找内容分组(Array("姓名", "性别", "部门", "次数"), 1).遍历组(AddressOf 标题排序, 1)
回调函数:
Private Function 标题排序(da As DataAutomation, 计数 As Long, 层数 As Long, key As String) As Boolean
    '取出第一行标题数组
    arr = da.取整行(1).取出数组
    '用转换列对表格排序
    Call da.转换列(da.根据标题返回序号(arr, Array("姓名", "性别", "部门", "次数")))
End Function
5)操作后每个单元的顺序都一致了,这是就可以把单元数据拼接会来,用合并组方法,合并后写回单元格
Call da(Range([A1], [D65536].End(3))).按查找内容分组(Array("姓名", "性别", "部门", "次数"), 1).遍历组(AddressOf 标题排序, 1)
Call da.合并组(1).写入单元格([G1])

6)分析完成代码截图如下
image.png
有些方法为了让你们看的清晰的写了两行,实际可以精简成7行
image.png
如果Sub,Function,Dim这些语句忽略不计,可以看出真正实现功能的只需要写两行代码就完成了
演示文件: excel用VBA按自定义排序.rar (245.45 KB, 下载次数: 25)





TA的精华主题

TA的得分主题

 楼主| 发表于 2021-12-3 09:41 | 显示全部楼层
案例:如图将左表变右表
image.png
思路分析:
1)首先他是对每个班级进行转换成一行,那么可以先对班级分组,分组方法肯定是<按类别分组>了
   分组肯定要遍历组的否则没意义了,先展示分组后效果
image.png
可以看出分组后每个班级到一个单元了
2)将每个班级转成一行可以用<行列改变>方法,演示如下
image.png
3)虽然转换成了一行不过,有班级进行干扰,可以先删除班级,在转换
image.png
4)效果已经出来了,这时再把班级加进去,
image.png
这段代码可以说一说了,我用了da.名字,这时什么?
           以前只是粗略的说了一下,da.名字,是da的标识符,如果做一个大工程这个属性你们就会替换到他的好处了
在这里da.名字是因为,使用了分组产生的da子实例,系统会自动给他安排一个名字,按类别分类就安排类别作为名字
按数量就会安排数量作为他的名字,大家可以一个一个去试一试不同分组产生的名字
          这里还用了<添加数据>方法,该方法只支持添加数组,所以我用array函数构造了一个数组
5)经过上面几步效果已经出来了,之后只需要将组的单元合并,就完成了
整理如下
image.png
6)构造标题,肯定要用构造序列函数 da.GZ
不会GZ函数表达式的请往回翻
表达式为:da.GZ("[班级,重复数量[姓名,成绩]]")
重复数量我们可以用合并后的da数据的列数来计算 (da.列数 - 1) / 2
所以表达式为:da.GZ("[班级," & (da.列数 - 1) / 2 & "[姓名,成绩]]")
image.png
7)之后只需要将标题数组arr写入单元格就可以了,可以用da方法套一下
da(da.GZ("[班级," & (da.列数 - 1) / 2 & "[姓名,成绩]]")).写入单元格 ([E1])
image.png
8)分析完成,可以看出三行有效代码就完成了复杂的转换,展示了da类的强大
附件: 班级转换.rar (259.09 KB, 下载次数: 17)
作业:还是此例子如何将右表转成左表?

TA的精华主题

TA的得分主题

发表于 2021-12-3 09:57 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-12-8 10:51 | 显示全部楼层
出一个新案例:
image.png
要求根据工作量报表以及工资单价表,计算出每个人的工资
工作量报表+工资单价表算出工资报表
说明:1)根据产品对应的工资单价*数量可以计算出总价
          2)每人每人进行演讲,演出的人数,姓名是不固定的
          3)一个组里的总工资均分到每个人


TA的精华主题

TA的得分主题

 楼主| 发表于 2021-12-8 11:27 | 显示全部楼层
思路:
1)将工作量报表中的产品匹配工资单价表中的单价可以用da字典方法,创建工资单价表的da实例并用da.字典设置行索引方法生成字典索引
取出工作量报表中的产品的数组,在da工资单价表实例中用da.字典取行方法取出新的da实例
image.png
上述代码为了直观声明了三个da实例才完成操作,在da中可以用da.xin()方法创建新的da实例,整理后代码
image.png
2)将匹配到的数据,写入工作量报表中 的da数据中,可以用覆盖区域方法
image.png
因为产品名已经不需要了将产品位置替换成了单价
同样简化成一行后
image.png
3)计算每一行的总工资
用添加计算列的方法,产生新的一列总价
image.png

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-12-8 11:46 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
继续上面案例思路
4)根据小组对总价进行求和
可以用da.数据透视方法,注意数据透视前应该将小组的合并单元格填充
image.png
5)处理小组姓名的分隔符号,由于分隔符都不规范,使用正则统一替换为,
并且还存在两个姓名之前有多个分隔符情况也要用正则替换掉,所以用两次da.正则替换方法
image.png
6)计算一组里没人的人均工资,总工资/人数,人数可以用分隔符+来确定数量
同样适用da.添加计算列方法,可以使用excel函数计算人数,例如
image.png
代码就是这样
image.png
计算完最后删除一些没用的列
日期[1列],产品[3列],数量[4列],总价[5列],这些已经不需要了
image.png



TA的精华主题

TA的得分主题

 楼主| 发表于 2021-12-8 12:04 | 显示全部楼层
继续案例思路:
7)处理后如上图片,现在将姓名展开
da.分列方法
image.png
8)根据姓名进行求和
image.png
9)将工资小数位舍入1位
image.png
10)完成统计,整理出最终代码
image.png
今天这案例讲解完毕,分析这么多主要为了说清思路,可以看出实际代码就是那么几行
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-9-27 19:05 , Processed in 0.073728 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表