本帖最后由 hyefeifei 于 2013-11-10 07:24 编辑
说点题外的:如果看到现在,不知道是否有人会问,弄了这么多代码,要实现的功能确很简单,有这个必要吗?
第一:诚然,类模块能实现的,不用类模块原则上也能实现,但是,原则上能实现的,你不一定能实现,除非你天赋异禀,对复杂的逻辑有着超强的解析力。但就算如此,你也要费大量脑细胞,何苦呢?类模块可以抽象复杂的过程,化繁为简,变难为易,不用岂不可惜。
第二:开发稍大一点的项目,管理,扩展就变得非常重要,如果不用类模块,你会感到这项工作就算不是一件不可完成的任务,也是一件头昏脑胀的任务。
第三:它可以模拟二元树,队列,堆栈之类的数据结构,封装API,捕获事件,引发事件,种种方便之处,不一而足。(这些以后慢慢都会讲到)
第四:类模块初看似难,其实简单,一旦掌握,就会越用越顺,越顺越爱用,学习成本并不是你想像的那么高,真正是低成本,高收益的知识。
个人认为,学习VBA,两个知识最重要,第一是ADO,次之的就是类。这个贴子只是期望引发大家对类的兴趣,惜乎现在看来,关注这个贴子的人并不多,不过,继续这个贴子,就当是一个自己提高的过程好了。
闲言少续,进入正题
Choose函数下面,我们引进枚举变量,并引入事件。
在这之前,先讲讲choose这个函数
Y=Choose(index,a1,a2,a3,……,an)
Index是一个介于1至n之间的数值,Y就等于a(index)
举个例子choose(3,”yy”,”xx”,”qq”,”dd”)就返回qq。
枚举变量引入
现在我们把文本,公式,空值,数值这几个属性值定义成一个枚举变量。
在类rngFormat 顶端输入:
Public Enum cType
文本
公式
日期
数值
空值
End Enum
记住,这时,文本,公式,日期,数值,空值,就变了数值0,1,2,3,4
修改rngFormat代码如下:
原Private mDatatype As String
改为:Private mDatatype As cType
原Public Function WhatType()
If IsEmpty(m_oCell) Then
mDatatype = "空值"
ElseIf m_oCell.HasFormula Then
mDatatype = "公式"
ElseIf IsNumeric(m_oCell) Then
mDatatype = "数字"
ElseIf IsDate(m_oCell) Then
mDatatype = "日期"
Else
mDatatype = "文本"
End If
WhatType = mDatatype
End Function
这段程序,把其中的空值,公式,数字,日期,文本,用其相应的数值代替变为:
If IsEmpty(m_oCell) Then
mDatatype = 4
ElseIf m_oCell.HasFormula Then
mDatatype = 1
ElseIf IsNumeric(m_oCell) Then
mDatatype = 3
ElseIf IsDate(m_oCell) Then
mDatatype = 2
Else
mDatatype = 0
End If
WhatType = mDatatype
现在可以运行一下标准模块中的test程序测试一下,就会看到b1:b41原来的文本,现在已经被01234这几个数替代。
增加一个方法现在为rngFormat增加一个方法,这个方法给其cell属性接受的单元格增加背景色。方法如下:
Public FunctionrColor() m_oCell.Interior.ColorIndex =Choose(Me.DataType + 1, 8, 37, 40, 24, 15) End Function
在类模块中引用自身,要用Me.这和在窗体中是一样的,不要忘了,datatype属性是01234,而索引值是1-N的值,所以要加1。
8, 37, 40, 24, 15 是5个颜色值,分别对应文本,公式,日期,数值,空值五个类型的背景色,例如,你想把公式的背景色变成红色,就把37改成3好了。
现在,我们在标准模块中,增加一句:rngC.Items(i).rColor,test变为:
Sub test()
Dim rng As Range, i As Long
Set rngC = New rngFormats '实例化类,形成对象
For Each rng In Range("a1:a41")
rngC.Add rng
Next
For i = 1 To rngC.Count
Cells(i, "b") =rngC.Items(i).DataType rngC.Items(i).rColor
Next
End Sub
此时,再运行test,发现单元格依各自的类型变色了。
讲到这里,忽然想到了一个问题,就是用数组构造集合类的时候,其Add方法,
有这么一句:redim preserve arr(1 tok+1) 提醒一下,这种声明最好不用,因为数组在运算大量数据时速度快是使用它的一个理由,但是当程序运行到:
redim preserve arr(1to k+1) 这一句时,vba会先建立一个空的数组arr(1 to k+1),然后把原先的arr(1 to k) 的数据复制过来,这一过程,会降低效率,所以,在实际应用中,最好是预先判断好数组最大的下标,声明一个固定数组,然后用一个长整形变量,来记录数组中有效下标。如果非用preserve关键字,也要设一个条件 ,批量增加下标。关于数组,坛子里有详细介绍的贴子,就不多说了。(在主贴的附件里,用数组构造类,用的就是固定数组)
到此为止的附件:
类_3.rar
(26.51 KB, 下载次数: 138)
原打算讲事件来着,不过现在想来,还是先介绍一下用字典构造集合类,然后再在字典集合类中引入事件,不要把所有的知识点,都在数组里讲了,且由于数组不支持关键字索引(当然可以通过曲折手段实现,但那样没效率也没意义),好多功能实现起来麻烦。暂停……
|