ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 类-字典-数组-集合-接口-窗体

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2014-7-27 10:02 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:类和类模块
怎么不继续写了啊  我个人觉得类模块其实是为了简化算法而存在的
从高层次来抽象问题
可以在后续任务中免去大量的重复代码和重复判断
vba因为超轻量级的开发工具属性 使用的人大部分在一个模块甚至一个过程里即已解决问题
所以类出场的必要性确实很低 但是当代码量增大 需要做多层业务逻辑时 它肯定是利器了
只是vbe编辑器太过简陋 用vba构建类略显繁琐  大大增加了编码难度

楼主再接再厉啊 希望能写多一点 大家可以系统的学习一下 最好能应用到示例中

TA的精华主题

TA的得分主题

发表于 2014-11-12 10:56 | 显示全部楼层
没有啊没有啊没有啊没有啊没有啊没有啊没有啊没有啊没有啊没有啊没有啊没有啊没有啊没有啊

TA的精华主题

TA的得分主题

发表于 2014-11-12 10:57 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
不存在啊不存在啊不存在啊不存在啊不存在啊不存在啊不存在啊不存在啊

TA的精华主题

TA的得分主题

发表于 2014-11-12 10:58 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2014-12-14 14:32 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-3-19 15:24 | 显示全部楼层
大家好,一年没过来了,这段时间人生变故,真是今我已非昨我了,想继续把这篇太监贴续完,或另开一贴写点sql方面的东西,不知大家是不是有兴趣

TA的精华主题

TA的得分主题

发表于 2015-3-19 15:58 | 显示全部楼层
hyefeifei 发表于 2015-3-19 15:24
大家好,一年没过来了,这段时间人生变故,真是今我已非昨我了,想继续把这篇太监贴续完,或另开一贴写点sq ...

不错,真是相当的不错。希望能续完,并开一个SQL 的专题。
虽然不是100%同意楼主的观点,但是还是相当支持的。关于类的作用,我想毋庸置疑,在诸多面向对象语言中早已证明了其威力,楼主的系列文章也开阔了初学者的思路,认识到类模块并不是那么面目可憎,高高在上,不可接近。

但是仅就VBA 语言的类模块与VBE 开发平台而言,还是值得探讨的。VBA 的类模块编写繁琐,应用麻烦,不支持继承和多态等特性,不支持重载,甚至写一个最简单的构造方法传参,居然是用事件模拟来构造的,不能用纯构造类的角度来解决。刚刚接触时怀着高大上的心态,可是稍稍了解一下其他专业语言比如C# ,vb 的类模块的局限性就不可谓不大了。

至于sub 与Function 的争论,俺是支持楼主和香川诸位的观点的,Sub 和Function 的本质区别就是一个没有返回值,一个能返回值而已。本质上是一样的,只是微软为了限制工作表函数而限制了function修改单元格格式等等属性的功能,从语言的层面上是一样的。sub 本质就是 c 里面的 void 类型的函数嘛。 学vba 学语言眼光不能局限于excel 这个角落。

个人观点,如果能将本帖续完当然最好,或者有精力开一贴专门探讨一下ADO 的应用,我想大家是热烈期待的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-3-26 22:12 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
一年多没来坛子了,仔细看了一下之前一篇没完成的帖子,有多处文字错误,不知是不是可以修改。

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-3-26 22:29 | 显示全部楼层
捕获事件实例:
      现在,请打开附件“类_4.xlsm”,如果要在Sheet1的A1:A41单元格中,实现双击某一单元格,则与此单元格类型相同的单元格被着色,右击某一单元格,则与此单元格类型相同的单元格去色,该如何处理呢?
我们知道worksheet有BeforeDoubleClick事件,我们现在要做的是捕获Sheet1的BeforeDoubleClick事件,根据前面所讲的,在rngFormatDS类模块的顶部声明变量:Private WithEvents wks as Worksheet,然后就可以把表sheet1传递给wks,如何传递?当然是通过属性了,下面,把如下代码加入rngFormatDS模块。
  1. Public Property Set Sheet(msh As Worksheet)
  2.     Set wks = msh
  3. End Property
  4. Public Property Get Sheet()
  5.     Set Sheet=wks
  6. End Property
复制代码
       然后,我们就可以在左上角的下拉列表中选择wks,在右边的下拉列表中选择BeforeDoubleClick或BeforeRightClick了。

       不过,在这之前,与rColor方法相对应,我们给rngFormat类加一个“去色”的方法,在类中加入如下代码:
  1. Public Function unColor()
  2.     m_oCell.Interior.ColorIndex = xlNone
  3. End Function
复制代码
      现在,回到rngFormatDS类,我们可以给wks 的BeforeDoubleClick事件添加代码了,代码很简单,先把字典(csDic)中的rngFormat实例放到数组(arArray)中,再循环数组,当循环到的rngFormat的whattype属性与通过双击单元格地址索引到的rngFormat属性相同时,执行着色(rColor)方法。代码如下:

Private Sub wks_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Dim arArray As Variant
    Dim lIndex As Long
    arArray = csDic.Items   'arArray 即包含所有rngFormat对象的数组
    If Application.Intersect(Range("data"), Target) Is Nothing Then Exit Sub    '为方便把A1:A41命名为Data,如右击此外的单元格则退出程序
    For lIndex = LBound(arArray) To UBound(arArray)
        If arArray(lIndex).WhatType = csDic(Target.Cells(1).Address).WhatType Then      '这里用Target.cells(1).address取代Target.address,可防止出错。
            arArray(lIndex).rColor
            Cancel = True
        End If
    Next lIndex
End Sub

    然后,我们给右键单击事件添加代码,只须修改arArray(lIndex).rColorarArray(lIndex).unColor即可,代码就不在这里写了,参见 类_5.rar (35.98 KB, 下载次数: 85)


引发事件实例:
      前面,集合类rngFormatDS通过捕捉worksheet的双击和右击事件,实现了双击着色,右击去色的功能。
我们也可以让集合类rngFormatDS象worksheet等对象一样,有自己的事件,然后其他的类可以捕获这些事件,这怎么实现呢?
      1 因为我们要在类rngFormatDS中增加一个它自己的事件,然后类rngFormat去引用这个事件,这样类rngFormatDS 和 rngFormat就形成了父子关系,在这种情况下,需要把他们都要用到的公共变量放到父类中去。所以,我们到rngFormat中去,把枚举变量cType剪切掉,然后粘贴到rngFormatDS的顶部。
      2 在rngFormatDS中声明一个事件:
      Event ChangeColor(rngType As cType, bOn As Boolean)
      3 何时引发这个事件呢?当然是在双击或右击鼠标时引发,所以我们修改wks_BeforeDoubleClickwks_BeforeRightClick和事件代码如下:

Private Sub wks_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Dim arArray As Variant
    Dim lIndex As Long
    arArray = csDic.Items
    If Application.Intersect(Range("data"), Target) Is Nothing Then Exit Sub                '
    RaiseEvent ChangeColor(csDic(Target.Cells(1).Address).WhatType, True)    '第一个参数指明哪种类型的实例需要变动颜色,第二个参数指明该变动是着色还是去色。
    Cancel = True
End Sub
Private Sub wks_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
    Dim arArray As Variant
    Dim lIndex As Long
    arArray = csDic.Items
    If Application.Intersect(Range("data"), Target) Is Nothing Then Exit Sub
RaiseEvent ChangeColor(csDic(Target.Cells(1).Address).WhatType, False)   
Cancel = True
End Sub

           4 此时,我们需要到rngFormat类中去捕获changecolor事件,象捕获Excel自身对象的事件一样,在顶部做如下声明:
  1. Private WithEvents rDS As rngFormatDS
复制代码
         5我们需要建一个属性,把父类传递给参数rDS,这里我们建一个叫Parent的属性,代码如下:
  1. Public Property Set Parent(objParent As rngFormatDS)
  2.     Set rDS = objParent
  3. End Property
复制代码
         6此时,我们就可以在左上角下拉列表中选rDS,在类此给rDS_ChangeColor事件添加代码了:
  1. Private Sub rDS_ChangeColor(rngType As cType, bOn As Boolean)
  2.     If mDatatype = rngType Then
  3.         If bOn Then
  4.             rColor
  5.         Else
  6.             unColor
  7.         End If
  8.     End If
  9. End Sub
复制代码
         代码很容易理解,当本实例的类型等于ChangeColor事件的第一个参数传递过来的类型时,判断ChangeColor事件第二个参数是否为真,是的话着色,不是的话去色。
         7还剩最后一步,到rngFormatDS类中去,在其Add方法中加如下代码:
  1. Set rF.Parent = Me
复制代码
      这样,子类与父类的关系就建立了,add方法的完整代码如下:
  1. Public Sub Add(rng As Range)
  2.     Dim rF As rngFormat
  3.     Set rF = New rngFormat
  4.     Set rF.Cell = rng
  5.     Set rF.Parent = Me
  6.     rF.WhatType
  7.     Set csDic(rF.Cell.Address) = rF
  8. End Sub
复制代码
     看到这里的朋友可下载 类_6.rar (37.35 KB, 下载次数: 80) ,进行测试。

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-3-26 22:43 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 hyefeifei 于 2015-3-26 22:45 编辑

       前面讲了用数组和字典实现集合类的方法,原打算讲一下利用collection实现集合类的方法,其实很简单,但是有两个知识点:一是设置类的默认属性,二是for each循环问题,正愁如何说清楚,发现lee1892的一个贴子已经讲清了,我再啰嗦已无必要,贴子链接:http://club.excelhome.net/thread-1194207-1-3.html
不过,建议大家用到集合类时,考虑到速度问题,处理的数据量大的话,不要用collection。待续…………
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-6-16 07:02 , Processed in 0.035158 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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