ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] [讨论] 集合类的建立(类似WorkSheets和WorkSheet)

[复制链接]

TA的精华主题

TA的得分主题

发表于 2015-3-26 10:47 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:数组集合和字典
本帖最后由 lee1892 于 2015-3-26 13:55 编辑

VB中有大量的集合类,如Excel VBA中的WorkSheets和WorkSheet这样的,前者是后者的集合。

在实际使用中,我们会注意到这样的用法:
WorkSheets("Sheet1")
其等效于
WorkSheets.Item("Sheet1")

实际上利用的是VB中的默认属性,在VBA中这个属性是不显示的,但可以通过如下办法手动添加:
1、导出类模块文件
2、用文本编辑器编辑导出的文件,在所需要设置的默认属性段内加一行:
  1. Attribute Value.VB_UserMemId = 0
复制代码
3、移除VBA中的该文件,导入编辑过的类模块文件

以本贴附件为例,在文本编辑器中打开会是这样的
  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. End
  5. Attribute VB_Name = "CupCakes"
  6. Attribute VB_GlobalNameSpace = False
  7. Attribute VB_Creatable = False
  8. Attribute VB_PredeclaredId = False
  9. Attribute VB_Exposed = False
  10. Option Explicit

  11. Private colCakes As Collection

  12. Private Sub Class_Initialize()
  13.     Set colCakes = New Collection
  14. End Sub
  15. Private Sub Class_Terminate()
  16.     Dim oCake As CupCake
  17.     For Each oCake In colCakes
  18.         Set oCake = Nothing
  19.         colCakes.Remove 1
  20.     Next
  21.     Set colCakes = Nothing
  22. End Sub

  23. Property Get Item(Index) As CupCake
  24.     Attribute Value.VB_UserMemId = 0
  25.     Set Item = colCakes(Index)
  26. End Property

  27. Property Get Count() As Integer
  28.     Count = colCakes.Count
  29. End Property

  30. Public Function Add(Optional ByVal Name As String) As CupCake
  31.     If Len(Name) = 0 Then
  32.         Name = "CupCake " & colCakes.Count + 1
  33.     End If
  34.     Set Add = New CupCake
  35.     Add.Name = Name
  36.     colCakes.Add Add, Name
  37. End Function
复制代码
这样一来,就可以把 Item 属性作为默认属性,从而在实际使用中可以省略掉,比如附件中的测试过程:
  1. Sub Test()
  2.     Dim oCakes As New CupCakes, oCake As CupCake
  3.     Dim i%
  4.     With oCakes
  5.         Debug.Print oCakes.Count

  6.         Set oCake = .Add("MyCake")
  7.         With oCake
  8.             .Size = ckMiddle
  9.             .CakeType = ckChocolate
  10.         End With

  11.         With .Add("HisCake")
  12.             .Size = ckBig
  13.             .CakeType = ckStrawberry
  14.         End With
  15.     End With

  16.     With oCakes("MyCake")
  17.         Debug.Print .Name; .Size; .CakeType
  18.         Debug.Print
  19.     End With
  20.     With oCakes.Item("MyCake")
  21.         Debug.Print .Name; .Size; .CakeType
  22.         Debug.Print
  23.     End With

  24.     For i = 1 To oCakes.Count
  25.         With oCakes(i)
  26.             Debug.Print .Name; .Size; .CakeType
  27.         End With
  28.     Next

  29.     oCakes.Remove "MyCake"
  30.     Debug.Print oCakes.Count
  31.     ' 下述For Each不能使用
  32.     'For Each oCake In oCakes
  33.     '    Debug.Print oCake.Name
  34.     'Next
  35.     Set oCakes = Nothing
  36. End Sub
复制代码
但这个办法存在一个问题,就是这样的集合类是不支持 For Each 循环的。

欢迎讨论~

=============
附件加了3楼的办法
要支持 For Each 的话,需要如上述导出到文件,再用文本编辑器编辑,再导入。添加下述代码
  1. Public Function NewEnum() As IUnknown
  2.    Attribute NewEnum.VB_UserMemId = -4
  3.    Set NewEnum = colCakes.[_NewEnum]
  4. End Function
复制代码
此处的 colCakes 是用来存放类CupCake的内部集合对象,_NewEnum是集合对象的一个隐藏的方法需要用 [ ] 标识,前面一句设该方法的 UserMemId 为-4 是在VB中隐藏该方法,但在VBA中实际上并没有隐藏,但在VBA中必须设置才能正常使用。

150326-集合类的简单演示-by Lee1892.rar

12.94 KB, 下载次数: 285

评分

5

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-3-26 11:19 | 显示全部楼层
谢谢您。这正是我想要的。太棒了!
可以解释下 Attribute Value.VB_UserMemId = 0。这句的意思吗

TA的精华主题

TA的得分主题

发表于 2015-3-26 13:12 | 显示全部楼层
加入这些就可以for each了:

Public Function NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
   Set NewEnum = colCakes.[_NewEnum]
End Function

参考资料:
https:/ /msdn.microsoft.com/en-us/library/aa262338(v=vs.60).aspx

评分

3

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-3-28 17:11 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
谢分享,收藏备用。记得曾经做了个数三角形的文件,中间用到了,也受楼主指点,谢谢!

TA的精华主题

TA的得分主题

发表于 2015-3-28 21:14 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2015-4-2 15:02 | 显示全部楼层
每次回帖、谢谢!辛苦了。

TA的精华主题

TA的得分主题

发表于 2015-8-6 10:24 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
楼主精神可嘉,值得肯定

TA的精华主题

TA的得分主题

发表于 2016-7-10 11:17 | 显示全部楼层
每次回帖、谢谢!辛苦了。

TA的精华主题

TA的得分主题

发表于 2019-8-1 08:46 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
先打卡,以后慢慢研究,

TA的精华主题

TA的得分主题

发表于 2019-8-11 21:17 | 显示全部楼层
看不懂。先打卡,以后慢慢研究,
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

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

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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