Excel VBA 编程基础 -- 类与对象(四)前面我们介绍了类与对象的基本概念,讨论了对象的属性以及创建和销毁时所触发的事件,今天我们以一个实际的例子来具体应用前面讨论的内容。例1. 学生成绩表这里有一张学生成绩表,包括姓名(Name)、国籍(Country)、性别(Gender)、出生日期(BirthDate)、数学成绩(Math)、中文成绩(Chinese)、英文成绩(English)。如图:图1 学生成绩表现在我们要把每一行表示为一个对象。首先,让我们来定义一个类 CStudent,如图2:图2 CStudent插入一个类模块,将模块名字修改为 CStudent,表示学生类。图中显示了这个类的内部数据成员,包括 m_Id,m_Name 等等。然后定义了两个事件处理处理程序:Class_Initialize 和 Class_Terminate。初始化事件处理程序 Class_Initialize 用来给只读属性 Id 生成唯一编号并赋给内部成员变量 m_Id。终止化事件处理程序无事可做,因为 CStudent 没有可释放的外部资源,所以 Class_Terminate 也可以不出现。另外,还定义了一个字符串常量 ERR_SOURCE,用来发生错误时向外界报告错误源头。下面的代码就是各个属性的 Get/Let 过程了。我们来看对性别(Gender)属性的处理逻辑,如图3 所示:图3 Gender 属性的处理逻辑我们看到,Get 函数很简单,直接将 m_Gender 成员变量的值作为 Get 函数的返回值即可。但对于 Let 过程的处理就稍微复杂了点。我们说过,属性的 Get/Let 就相当于内部成员变量的“防火墙”,尤其对于 Let 过程中外界传递过来的参数要进行合法性检查。在上图 Let Gender 过程中,我们要对传递进来作为性别参数的 value 进行检查。首先,我们约定世界上只有“男”、“女”两种性别(性别问题是一个很复杂的问题,这里只做最简约定)。为此,我们声明两个变量 isMale 和 isFemale,分别表示检查的结果是男性还是女性。然后使用 StrComp 函数将 value 分别与 Male 和 Female 比较,注意 StrComp 使用了 vbTextCompare 的比较方式,表示比较不区分大小写。如果比较结果既不是男性(Not isMale)也不是女性(Not isFemale),则通过 Err.Raise 报告错误。其中,ERR_SOURCE 常量在 CStudent 中定义,其他常量在 MyConstants 模块中定义,如下图所示:图4 常量定义模块 MyConstants如果检查结果是男性或者女性,则将参数值赋给内部成员变量 m_Gender。下面是对属性 BirthDate(出生日期)的处理:图5 BirthDate 属性的处理Get 函数也很简单,直接赋值即可。对 Let 过程则和对 Gender 的处理一样,也要对参数进行检查。首先,我们约定学生年龄要在 [ 6, 100 ] 这个区间内。然后根据学生的出生日期求出年龄,并判断是否落在这个区间内。如果学生年龄落在这个区间之外,则报告错误,否则,把参数 value 的值赋给内部成员变量 m_BirthDate。我们已经讨论了两个属性的处理逻辑,其他属性的处理逻辑与此类似,此处不赘。下面来看如何利用 CStudent 类来读取开头所示的学生成绩表。图6 使用 CStudent 来读取学生成绩表由图可见,有了 CStudent 这个类,读取数据集的代码就变得非常简单清晰,这正是使用类与对象要达到的目的。在测试程序中,我们声明了一个 CStuddent 类型的数组,要读取的学生成绩表就放在这个数组中。在代码部分,我们首先使用 Excel 的函数 CountA 来获知数据表的行数,并据此定义数组大小。接下来用一个 For ... Next 循环读取数据表,用一个函数 BuildStudentObject 来读取每一行。最后,再用一个 For ... Next 循环,调用 CStudent 中的方法 WhoAmI 报告每个学生的年龄、总成绩和平均成绩。下面来看 BuildStudentObject 函数。图7 BuildStudentObject 函数首先,声明一个 CStudent 类型的对象变量 cso,然后使用 New 操作符将类 CStudent 实例化,并将实例的地址赋给 cso。接下来,将各个单元格的值分别赋给 cso 的对应属性。注意:当赋值号两边的类型不一致时,VBA 会隐含将右边的表达式转换为左边所要求的类型,但我们这样显式写出转换函数,譬如 CDate,CDbl,会使得代码的意图更清晰,更易读。最后,因为函数是返回 CStudent 类型的对象,所以要使用 Set 语句将 cso 赋给函数名 BuildStudentObject 作为函数的返回值。相关阅读Excel VBA 编程基础 -- 类与对象(一)Excel VBA 编程基础 -- 类与对象(二)Excel VBA 编程基础 -- 类与对象(三)