ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

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

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-11-22 11:18 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
查找替换篇
Public Function 查找(ByVal 内容arr, [ByVal 所有结果 As Boolean = False], [ByVal 查找方向 As 查找 = 全部查找], [ByVal 行 As Long = 1], [ByVal 列 As Long = 1])
类似ExcelVBA里的Fnd方法,返回值为二维假数组,数组存行列坐标,
例如:arr(1,1)找到的第一个内容的行索引 arr(2,1)找到的第一个内容的列索引
          arr(1,2)找到的第二个内容的行索引 arr(2,2)找到的第二个内容的列索引
          arr(1,3)找到的第三个内容的行索引 arr(2,3)找到的第三个内容的列索引
第1参数:可以是数字或字符串也可以是(数字,字符串)数组
              还可以使用like方法的通配符 例如:"*da*"查找包含"da"的内容
              还可以是比较符号 例如:">100"查找大于100 、"<10"查找小于10、">=100"查找大于等于100、"<>"查找不等于空
              还可以查找不符合条件的(vba解释就是 not like) 写法例如:"<>*da*"查找不包含"da"的内容
              如果传递不是数组 例如 ">1",则返回参数的格式是一个假二维数组,格式像这样 array(array()) 一个数组套一个坐标数组
              如果传递了数组 例如 array(">1","*da*"),则返回参数的格式是一个假二维数组,
               格式像这样 array(array(),array())一个数组套两个坐标数组
               假数组取值应该这样:
               arr(1)(1,1)找到的第一个元素进行查找的第一个内容的行索引 arr(1)(2,1)找到的第一个元素进行查找的第一个内容的列索引
第2参数:true返回所有结果,false只返回第一个结果
              设置成false可以利用查找判断数据里是否含有指定内容 例如 If IsArray(da.查找("", False)) Then MsgBox "有空值"
第3参数:枚举值,用来设置查找的方向
Public Enum 查找
    全部查找 = 1
    向下查找 = 2
    向上查找 = 3
    向右查找 = 4
    向左查找 = 5
End Enum

第4,5参数:分别是行列索引,用来设置查找的起始位置,如果第3参数=全部查找,则第4,5参数无效
Public Function 查找替换(ByVal 坐标arr, ByVal 内容arr) As DataAutomation
配合查找方法,将查找到的值进行替换
第1参数:查找方法返回的坐标arr
第2参数:用来替换的值,
            注意:查找方法的第一参数是数组,返回的坐标arr是一个假二维数组
                     这时第2参数的内容arr也要是一个数组,例如:
                         坐标格式=array(array(),array())  内容arr要与之对应的=array(替换内容1,替换内容2)
Public Function 查找坐标取值(ByVal 坐标arr)
配合查找方法,将查找到的值取出
第1参数:查找方法返回的坐标arr
返回值是与坐标arr相同格式的数据
Public Function 坐标取值(ByVal 坐标arr)
与查找坐标取值不同的是,坐标arr是只能是一个坐标数组,不能是假数组
此方法用来人为构造数组,批量提取指定位置的值更加方便
Public Function 坐标替换(ByVal 坐标arr As Variant, ByVal 内容arr As Variant) As DataAutomation
与查找坐标取值不同的是,坐标arr是只能是一个坐标数组,不能是假数组
此方法用来人为构造数组,进行批量覆盖指定位置的值更加方便

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-11-22 11:27 | 显示全部楼层
Public Function 填充上下(ByVal arr, [ByVal 下填充 As Boolean = True], [ByVal st = ""]) As DataAutomation
Public Function 填充上下清除(ByVal arr, [ByVal 下填充 As Boolean = True], [ByVal st = ""]) As DataAutomation
Public Function 填充左右(ByVal arr, [ByVal 右填充 As Boolean = True], [ByVal st = ""]) As DataAutomation
Public Function 填充左右清除(ByVal arr, [ByVal 右填充 As Boolean = True], [ByVal st = ""]) As DataAutomation
四个方法是为了处理合并单元格数据,将合并单元格数据填充,或将清除填充变回合并前模样
第1参数:行或者列索引或索引数组(上下方法为列索引,左右方法为行索引)
第2参数:填充方向
第3参数:默认找到空值被填充,如果想改变为其他值,设置此参数
image.png
image.png
image.png

TA的精华主题

TA的得分主题

发表于 2021-11-22 11:41 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
好东西,谢谢分享!

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-11-22 11:48 | 显示全部楼层
本帖最后由 905738810 于 2021-11-22 11:57 编辑

第二种回调函数(因为用了CallWindowProc函数,我起名叫《CWP回调》)
为了方便后续方法讲解先将回调函用法
以da.循环 方法进行讲解
Public Function 循环(ByVal 次数 As Long, ByVal AddressOf地址, [ByVal key As String = "循环"]) As DataAutomation
第1参数:指定循环的次数,也可以理解为调用回调函数的次数
第2参数:回调函数地址,写法是 AddressOf 函数名 (AddressOf 关键字不能丢)
第3参数:给回调函数传递的方法标识符,如果一个回调函数有两个方法进行调用,可以利用标识符来判断具体方法
CWP回调函数模板
'Private Function 循环1(da As DataAutomation, 计数 As Long, 层数 As Long, key As String) As Boolean
'End Function
'Private Function 自定义分组1(da As DataAutomation, 计数 As Long, 层数 As Long, key As String) As Boolean
'End Function
'Private Function 子组自定义分组1(da As DataAutomation, 计数 As Long, 层数 As Long, key As String) As Boolean
'End Function
'Private Function 遍历组1(da As DataAutomation, 计数 As Long, 层数 As Long, key As String) As Boolean
'End Function
'Private Function 自定义筛选1(da As DataAutomation, 计数 As Long, 层数 As Long, key As String) As Boolean
'End Function
目前这5种方法的回调函数都是用了CWP回调,CWP回调的好处在于调用速度极快,所以我在频繁需要回调的方法上都用了CWP回调,并且回调函数采用了传址方法,可以回写变量。
但是他也有缺点就是要加AddressOf 关键字,回调函数只能写在模块中,格式不能乱写否则崩溃
注意:CWP回调的回调格式一定要按照模板来写,da类的顶部写也有模板可以直接复制
         模板的函数名,变量名是可以更改的,类型和关键字不能修改
以循环方法示例:
image.png
循环回调第1参数:调用的da实例
循环回调第2参数:调用次数
循环回调第3参数:总次数
循环回调第4参数:标识符
如果将回调函数返回值设置true可以提前终止循环


TA的精华主题

TA的得分主题

发表于 2021-11-22 12:00 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
4600行+的代码,写一个类,佩服!
强大!

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-11-22 12:32 | 显示全部楼层
opel-wong 发表于 2021-11-22 12:00
4600行+的代码,写一个类,佩服!
强大!

我写了100+个方法了,目前把我想到的全部写了出来,基本可以很灵活的处理多种数据,后续遇到处理不了的数据,慢慢还会增加方法的
其实我想分成多个类写的,但是为了VBA使用者移植方便,强行写到了一起,好在VBA的类不会因为方法多而影响new的效率

TA的精华主题

TA的得分主题

发表于 2021-11-22 12:46 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
太牛了,佩服,好东西,收藏了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-11-22 13:56 | 显示全部楼层
本帖最后由 905738810 于 2021-11-23 19:57 编辑

Public Function 筛选(ByVal index As Long, ByVal 条件arr, [条件共存 As Boolean = True]) As DataAutomation对数据进行整行筛选
第1参数:进行判断条件的列索引
第2参数:条件或条件数组,条件可以是数字,字符串,支持like通配符,可以是比较运算符
               详细内容可以参考前面的查找方法
               条件数组的互相运算方式是or运算,如果想and可以多次调用方法例如:da.筛选().筛选()
第3参数:如果第2参数是数组并且,条件有共同区间
                 例如:array("*d*","*da*") 此条件都满足包含"da"内容的区间
                           数据为("a","dav","da","dd")
             如果参数=true 则会把相同区间内容复制一份 ,结果为:数据("dav","da","dd","dav","da")
             如果参数=false则只会保留一个结果 ,结果为:数据("dav","da","dd")

Public Function 筛选自定义(ByVal AddressOf地址, [ByVal key As String = "筛选自定义"]) As DataAutomation

按CWP回调函数来筛选
回调函数返回true则保留数据,返回false则删除数据 2021-11-23更新这句话
第1参数:回调函数地址,写法是 AddressOf 函数名 (AddressOf 关键字不能丢)
第2参数:给回调函数传递的方法标识符,如果一个回调函数有两个方法进行调用,可以利用标识符来判断具体方法
回调函数模板:
'Private Function 自定义筛选1(da As DataAutomation, 计数 As Long, 层数 As Long, key As String) As Boolean
'End Function

回调第1参数:调用的da实例
回调第2参数:调用次数
回调第3参数:调用次数(与回调第2参数一模一样)
回调第4参数:标识符

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-11-22 14:59 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
讲解属性的概念
       由于da类使用了回调机制,可以将数据分功能分块,使代码结构更清晰,
但是有一个弊端就是无法实现两函数间的互相通信,或者说主函数与回调函数的变量无法共用
所以我研究出了属性这个概念。
     因为回调函数的参数是有da实例的,在da实例中添加属性,就可以将主函数与回调函数通过
读写属性方法来实现通信。
Public Function 属性添加(ByVal key As String, ByVal 内容) As DataAutomation
底层就是字典实现的
第1参数:标识符(理解成字典的key)
第2参数:要写入属性的内容(理解成字典的item)
Public Function 属性(ByVal key As String)
通过标识符取出属性
第1参数:标识符

下面演示:两个da实例互相调用
image.png
此示例只用了已经讲过的方法,来实现高级筛选功能
这个示例效率肯定不高,代码也过于长了(应该比纯VBA少吧)
实际上这种查找功能,在后面查找篇章中会有更好的处理方法
主要是给大家体会da类的用法思路,以及属性的作用
属性的扩展方法
这些方法底层都是属性实现的
Public Function 备份还原数据(ByVal key As String) As DataAutomation
da类是对da数据操作的,比如筛选方法,执行后da数据就改变了,如果想复用筛选前的数据,可以将数据先备份
第1参数:标识符(理解成字典的key)
Public Function 备份数据(ByVal key As String) As DataAutomation
对备份的数据进行还原,还原后现有da数据会被替换掉
第1参数:标识符(理解成字典的key)
关于备份示例参照此贴开篇的演示动图
Public Function xin(Optional ByVal key As String = "") As DataAutomation
创建一个新的da实例,此函数已经在前面讲解过了
在高级筛选功能演示中,其实直接使用da.xin("da2")方法来创建一个新的实例,创建后直接可以da.属性("da2")调用了,这样更方便

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-11-22 15:03 | 显示全部楼层
本帖最后由 905738810 于 2021-11-23 14:10 编辑

组的概念,组可以是da类的灵魂了
对组操作大概分三部
一、分组(对da实例按条件拆分成N个da子实例)
      分组有一下几种方法
             1.按查找内容分组
             2.按行上下不同分组
             3. 按类别分组
             4.按列数量分组
             5.按数量分组
             6.按条件分组
             7.对组再分组
                 对组再分组分一下几种模式:
                     1.对叶子节点分组
                     2.对第N层组在分组

二、遍历组(利用回调函数逐个取出da子实例,对da子实例进行修改)
      遍历组分一下几种模式:
            1.全部遍历
            2.遍历叶子节点组
            3.遍历第N层组
三、合并组(通过遍历组对da子实例进行修改后,还原到da实例中)
      合并组分一下几种模式:
            1.合并全部节点的组
            2.合并叶子节点组
            3.合并第N层组


您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-19 02:21 , Processed in 0.050326 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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