ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

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

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-10 13:14 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖已被收录到知识树中,索引项:类和类模块
本帖最后由 hyefeifei 于 2013-11-10 13:39 编辑
lee1892 发表于 2013-11-10 09:39
你别打岔,你说的是表单的自定义函数,完全是另外一回事。

用函数返回代码片断执行成功与否是标准做法 ...

什么叫打岔?
你何时才能明白:
一、在工作表中引用自定义函数,不能改变单元格属性
二、在sub出现的任何地方,都可用function代替。
这两者没有任何矛盾。你举的是function在工作表中引用功能不完善的例子,你能举出一个sub必不可少的例子吗?

另外,我的原文是: “虽然function 和sub都可用做方法,但使用的时候,尽量用function ”说的是“方法”,希望你不要为了争论争论。
至于是否用字典建集合类的问题,我已经讲过三种方法的各自利弊,后面还要说到用collection构建集合类,喜欢用哪种,大家自便好了



点评

呵呵,冤枉人家了……人家是帮你说话,在批评jsxjd叫jsxjd别打岔呢。  发表于 2013-11-10 16:08

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-10 15:13 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 hyefeifei 于 2013-11-10 23:28 编辑

接着来,因为用数组构造集合类的局限性,我经常用的是collection,在论坛看了哪位朋友转贴的《字典与集合(Dictionary与Collection)》(这篇文章在主贴的附件里已经放在其中的一个工作表里了)才感觉到用字典的好处,大家弄明白了三种方式后,可以自己比较选择用哪种。

下面咱们用字典构造一个集合类,首先,咱们保留用数组建的那个类模块,新建一个类模块构造集合。把新建的类模块起名为:rngFormatDS
然后,需要在类模块的顶部声明一个字典

Private csDic AsObject

然后在类模块的初始化事件中,把字典对象实例化。

Private SubClass_Initialize()

    Set csDic =CreateObject("Scripting.Dictionary")

End Sub
这里用了后期绑定,改为前期绑定,我想大家都会处理。
下面为类添加Add方法:

Public Sub Add(rng AsRange)

    Dim rF As rngFormat
    Set rF = New rngFormat
    Set rF.Cell = rng
    rF.WhatType
    Set csDic(rF.Cell.Address) = rF
End Sub

这里,我们用单元格地址(rF.Cell.Address)做为索引关键字,在实际应用中,我们可以根据情况,选适合的关键字。

下面添加count属性

Public Property GetCount() As Long

    Count = csDic.Count
End Property
下面添加item属性

Public Property GetItems(i As Variant) As rngFormat

    Dim arr
    arr = csDic.Items
    If IsNumeric(i) Then
        Set Items = arr(i - 1)
    Else
        Set Items = csDic(i)
    End If
End Property
这段代码简单讲一下,因为字典是用关键字索引的,而我们构造的集合类,希望不仅用关键字索引,而且还能用自然序数(0123……)索引,所以,我们要先声明一个数组,把字典的item放到数组里,再用自然序数索引数组。
这个属性的参数i是一可变类型,当其为数字时,则item=arr(i-1)
当其不为数字时,item用字典的key索引 item=csDic(i)
但这里有一个问题,就是当字典的关键字也是数字时,就会出现错误,在我们这里,因为是用单元格地址做为字典关键字的,不可能是数字,所以避免了错误,大家使用时,要注意这一点。
现在返回标准模块:在顶部加一个声明
Public rngDAs rngFormatDS
运行:
Sub 测试字典()
    Dim rng As Range, i As Long
    Set rngD = New rngFormatDS           '实例化类,形成对象
    For Each rng In Range("a1:a41")
        rngD.Add rng
    Next
   For i = 1 To rngD.Count
        Cells(i, "b") =rngD.Items(i).DataType
        rngD.Items(i).rColor
   Next
End Sub
即可看到程序正常运行。
下面在引入事件之前,先对rngFormat增加一个属性,大家可以看到,自把DataType属性声明为枚举类型后,我们得到的是01234的数字,很不直观,我们还是希望得到字符串表示的属性。我们当然不能变回去,重新把DataType声明为字符串的,而是增加一个字符串属性值。
增加一这个属性很容易,打开类模块加入如下代码即可:
PublicProperty Get strDataType() As String
    Select Case mDatatype
    Case 文本: strDataType = "文本"
    Case 数字: strDataType = "数字"
    Case 日期: strDataType = "日期"
    Case 空值: strDataType = "空值"
    Case 公式: strDataType = "公式"
    End Select
EndProperty
另外,我们可以看到,a1:a41中有一些单元格是错误值,我们希望把错误值单独弄成一个类型,这怎么办?很简单,在rngFormat类模块中,
1.修改enumcType 声明,在最后加上 “错误”,不带引号
2.在whattype方法中,加入iserror判断
3.在getstrDataType中,加入:Case 错误:strDataType = "错误"
4.在rColor方法中,加入一个颜色值3(红色)
改过的代码在附件中,就不列全了。
现在来说一下事件
首先要明白捕获事件与引发事件之分
捕获事件大家知道,图表,工作表,工作簿等都有各自的事件,当我们在类模块中,用
WithEvents关键字声明 图表、 工作表、 工作簿这些对象时,就可以捕获这些对象的事件。
举例如下:
在类模块顶部输入如下代码:
PrivateWithEvents wks as Worksheet
你也可以用Public关键字声明这个模块级变量,如果用Public声明,就到此为止了,但我不主张使用Public声明,所以还得在类模块中加下一个可读写属性,代码如下:
Public Property Set Sheet(msh As Worksheet)
    Set wks = msh
End Property
Public Property Get Sheet()
    Set Sheet=wks
End Property
此时,就可以在模块左上方下拉列表框里,选择wks,而在右上方下拉列表框里,就可以看到所有相关的事件了。
引发事件引发事件就是我们可以建立类模块自有的事件,然后,在其他的类模块中,捕获我们自建的事件。要做到这点,第一步是声明一个自定义的事件
举例如下:
Event Aaa(xx,xx)
Aaa是事件的名字,括号里是事件的参数,也可以没有参数
第二步,使用raiseevent引发事件
这个Aaa事件何时发生呢?
当然是根据我们的需要,在需要它发生的时候发生,比如说,我们需要它在一个YYY方法的最后发生,就可以这样做:
Sub YYY
……
……
RaiseEvent Aaa(xx,xx)
End sub
当然也可以这个类所捕获的事件中引发它,随着我们给rngFormatDS类,及Rngformat类加入事件,大家就会越来越清楚了。
待续…… 类_4.rar (31.03 KB, 下载次数: 167)

TA的精华主题

TA的得分主题

发表于 2013-11-10 18:53 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
谢谢分享!

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-10 22:40 | 显示全部楼层
本帖最后由 hyefeifei 于 2013-11-10 22:53 编辑
lee1892 发表于 2013-11-10 09:45
如果要构造集合类,建议你用Collection,作为非VB原生的字典并不是必须的。

实际上,在非必要的情况下 ...

实在抱歉,误会 了,这里说声对不起啊,以后看贴子要仔细了。多谢香川老师的提醒。

TA的精华主题

TA的得分主题

发表于 2013-11-10 22:55 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2013-11-19 13:27 | 显示全部楼层
hyefeifei 发表于 2013-10-18 21:29
前文提到的四本书下载:
链接:http://pan.baidu.com/share/link?shareid=2538296038&uk=2921381087 密码: ...

谢谢hyefeifei ,这四本书有实体书卖吗?我买了excelhome《Excel 2007函数与公式实战技巧精粹》,觉得很好,不知《Excel VBA实战技巧精粹》适合初学者用吗?

TA的精华主题

TA的得分主题

发表于 2013-11-19 22:56 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

感谢楼主分享

TA的精华主题

TA的得分主题

发表于 2013-11-19 23:34 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2013-12-8 23:09 | 显示全部楼层
细腻!精彩!
总有踏破铁鞋的快感!!!!

谢谢hyefeifei 老师!!!!!!!

TA的精华主题

TA的得分主题

发表于 2013-12-9 09:00 | 显示全部楼层
本帖最后由 yiyiyicz 于 2013-12-9 09:01 编辑

楼主很专业,
“类模块能实现的,不用类模块原则上也能实现”,这话没错
不知楼主有没有办法,用类实现多层继承和多根继承(用VBA)
十分期待!!!!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-23 21:45 , Processed in 0.047187 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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