在阅读本文之前,建议先阅读下面2篇文章:
1.一起学Excel专业开发22:使用类模块创建对象1
2.一起学Excel专业开发23:使用类模块创建对象2
自定义集合类存在的不足
在《一起学Excel专业开发23:使用类模块创建对象2》中,我们自定义的集合类存在两个方面的不足:
1.不能在For Each循环语句中直接处理集合中的成员,否则会导致出错,如下图1所示,只能通过索引和Item属性来处理。
图1
2.自定义的集合没有默认的属性,因此不能使用标准的集合语法如gclsCells(1)来简化Item属性,在访问集合中的成员时,必须显示地指定Item属性。
解决方法
方法1:使用Visual Basic 6
在VB6中,可以指定一个属性为某个类的默认属性。如果将Item属性指定为默认属性,则当需要访问集合中的某个成员时,就可以使用简写的方式,例如gclsCells(1)。
步骤1:在Excel VBE中,将CCells类模块导出,导出文件名为CCells.cls。
步骤2:在VB6中打开CCells.cls。
步骤3:将鼠标放置在Item属性过程中的任何地方,单击菜单“工具——过程属性”。
步骤4:在“过程属性”对话框中,单击“高级”按钮,选择“过程标识符”组合框中的“(缺省)项,如下图2所示。这样,将Item属性设置成了该类的默认属性。
图2
步骤5:添加代码以访问集合中的成员:
代码语言:javascript复制Public Function NewEnum() As IUnknown
Set NewEnum = mcolCells.[_NewEnum]
End Function
设置该过程的属性如下图3所示。
图3
这样,就可以使用For Each循环来直接处理自定义集合类中的成员了。
步骤6:保存修改。
步骤7:将CCells.cls导回到Excel VBE中。此时,在VB6中对该类模块所作的修改生效。
方法2:使用文本编辑器
如果没有安装VB6,可以通过文本编辑器如记事本来创建这些过程及其属性。
步骤1:在Excel VBE中,将CCells类模块导出,导出文件名为CCells.cls。
步骤2:在记事本中打开CCells.cls。
步骤3:将Item过程属性修改为:
代码语言:javascript复制Property Get Item(ByVal vID As Variant)As CCell
Attribute Item.VB_UserMemId = 0
Set Item = mcolCells(vID)
End Property
步骤4:添加NewEnum过程:
代码语言:javascript复制Public Function NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
Set NewEnum = mcolCells.[_NewEnum]
End Function
步骤5:保存并关闭记事本。
步骤6:将CCells.cls导回到Excel VBE中。
使用上述任一方法修改将CCells.cls类模块后,就可以使用gclsCells(1)的方式来获取集合中的成员,也可以使用For Each循环来直接处理自定义集合中的成员。此时,我们将CreateCellsCollection过程修改为:
代码语言:javascript复制Public Sub CreateCellsCollection()
Dim clsCell As CCell
Dim lIndex As Long
Dim lCount As Long
Dim rngCell As Range
'创建新的Cells集合
Set gclsCells = New CCells
'对当前工作表中已使用区域中的每个单元格创建Cell对象
For Each rngCell In Application.ActiveSheet.UsedRange
gclsCells.Add rngCell
Next rngCell
'统计集合中公式单元格的数量
For Each clsCell In gclsCells
If clsCell.CellType = anlCellTypeFormula Then
lCount = lCount 1
End If
Next clsCell
MsgBox "公式单元格数量:" & CStr(lCount)
End Sub
就不会出现本文开头的图1所示的错误了。