Excel精英培训网

 找回密码
 注册
数据透视表40+个常用小技巧,让你一次学会!
楼主: qee用

[分享] VBA类:隐者的秘密

  [复制链接]
 楼主| 发表于 2006-11-16 09:51 | 显示全部楼层

1.第一步:使用Event语句声明事件

看一下类模块中现在的代码:

Option Explicit

Public Event Change(ByRef Cancel As Boolean)

Private s$

Public Property Get Value() As String

  Value = s

End Property

Public Property Let Value(ByVal c As String)

  s = c

End Property

Private Sub Class_Initialize()

  s = "abc"  初始值

End Sub

和前面的代码比较,多出了一句:

Public Event Change(ByRef Cancel As Boolean)

这就是Event语句,只此一句,我们已经为我们的类声明(我想使用“注册”一词是不是更妥切)了一个事件Change。在看Event语句产生的效果前,先来看它的特性:

1)为了声明事件,Event总是Public的,这好理解吧。

2)事件可以不带参数,如Public Event Change(),也可以带参数,如我们上面给出的,但参数不能是命名参数,可选参数或数组参数。这里我只解释一下命名参数的含义。我们知道,事件可以因特定的用户事件而触发,也可以在代码中象方法一样指定执行,如下面的CommandButton1_Click

Private Sub CommandButton2_Click()

  CommandButton1_Click

End Sub

但在调用对象的方法时我们通常喜欢这样的方式:

Selection.Sort Key1:=Range("A2"), Order1:=xlAscending

这里Key1Order1就是命名参数,命名参数的好处是我们不必记住它们的次序,调用时直接以名称和冒号后加等于号指定它的值,但对事件的调用却不允许这样。

3)事件没有返回值。

现在我们看一下,Event为我们做了什么。

建立一窗体UserForm1,添加一个TextBox控件(名称为TextBox1),两个CommandButton控件(名称为CommandButton1CommandButton2),CommandButton1Caption设置为“赋值”,CommandButton2Caption设置为“读值”,窗体的代码如下:

Option Explicit

Dim WithEvents mc As MyClass

Private Sub CommandButton1_Click()

  mc.Value = TextBox1 '赋值

End Sub

Private Sub CommandButton2_Click()

  MsgBox "mc当前的值为" & mc.Value '读值

End Sub

Private Sub UserForm_Initialize()

  Set mc = New MyClass

End Sub

上面这段代码实现的是,当点击CommandButton1时便会将TextBox1的值赋给mcValue,当点击CommandButton2时便会显示mc当前的Value值。

来运行一下这个窗体,先点击CommandButton2,此时显示“abc”,是mc的初始值,然后在TextBox1输入“123”,点击CommandButton1,再点击CommandButton2,显示“123”,说明赋值成功了。

呵呵,忘了,我们要做什么了!现在,请从UserForm1代码窗口的“通用”框中选择mc,哇!我们声明的事件在右边“声明”框中已经出现了!

我们定义这个事件是希望当mc的值改变时响应的,现在就迫不及待地给它写一句代码吧:

Private Sub mc_Change(ByRef Cancel As Boolean)

  If MsgBox("要改变mc的值吗?", vbYesNo) = vbNo Then Cancel = True

End Sub

上面这句代码你不会陌生吧,希望当用户选择了在改变时给用户一个确认的机会。

但是,现在点击CommandButton1,却不会给你选择的机会,我们还有一步没有做。

 

[此贴子已经被作者于2007-3-27 23:28:08编辑过]
excel精英培训的微信平台,每天都会发送excel学习教程和资料。扫一扫明天就可以收到新教程
回复

使用道具 举报

 楼主| 发表于 2006-11-16 09:52 | 显示全部楼层

2.第二步:使用RaiseEvent语句引发事件

声明了事件后,我们要做的,便是找到所有与事件发生关联的地方,使用RaiseEvent语句引发事件,这里引发的含义相当于Call,就是调用用户在事件中写的代码。在本例中,只有一个地方,就是Property Let Value过程中:

  Dim chyn As Boolean

  RaiseEvent Change(chyn)

  If chyn Then Exit Property

通过传递回的chyn,决定是否执行后面的赋值语句。下面就是添加了RaiseEvents语句后的类模块的代码:

Option Explicit

Public Event Change(ByRef Cancel As Boolean)

Private s$

Public Property Get Value() As String

  Value = s

End Property

Public Property Let Value(ByVal c As String)

  Dim chyn As Boolean

  RaiseEvent Change(chyn)

  If chyn Then Exit Property

  s = c

End Property

Private Sub Class_Initialize()

  s = "abc"

End Sub

现在你可以去运行你的窗体了,我们要的效果应该是达到了吧。为了便于你调试,下面给出窗体的全部代码:

Option Explicit

Dim WithEvents mc As MyClass

Private Sub CommandButton1_Click()

  mc.Value = TextBox1 '赋值

End Sub

Private Sub CommandButton2_Click()

  MsgBox "mc当前的值为" & mc.Value '读值

End Sub

Private Sub UserForm_Initialize()

  Set mc = New MyClass

End Sub

Private Sub mc_Change(ByRef Cancel As Boolean)

  If MsgBox("要改变mc的值吗?", vbYesNo) = vbNo Then Cancel = True

End Sub

当然,我们可以把上面mc_Change的代码要做的直接在Property Let Value过程的代码中,从而不使用事件。这就是在本回的开头说的。

事件的构建已经完成,说了这么多,其实你只要记住两步的标题就可以了。到这里,关于VBA类最基本最重要的部分已经给朋友们介绍完了。余下的,留着您在未来的探索路上慢慢体会吧,也请您不要忘了和大家分享您的喜悦。

隐者已向你展示了她所有的秘密,铅华去尽,只有美丽!

 

[此贴子已经被作者于2007-3-27 23:30:51编辑过]
回复

使用道具 举报

 楼主| 发表于 2006-11-16 09:52 | 显示全部楼层

七、一个完整的类实例
现在,提供一道简单的测试,帮大家回顾一下前面的知识。建议您做一下,因为VBA是实践性的。
题目要求:

(一)构建两个类:
1.Student类
具有2个属性:
(1)Name:可读写。
(2)Id:可读写,但只能写一次。格式为字母S加两位整数,如S01,S02…等。
2.Students类
具有1个属性,3个方法,2个事件:
(1)Count属性:只读,返回Student成员数量。
(2)Item方法:使用下标如Stus.Item(i)的方式调用,返回相应的Student成员,i可以是Student成员的自然顺序,也可以是Student成员的Id。
(3)Add方法:增加Student成员。当增加成员时,按顺序递增生成成员的Id,每个Id号只用一次,不因删除成员受影响。
(4)Remove方法:删除Student成员。
(5)BeforeAdd事件:在增加成员前作出响应,允许用户取消增加成员。
(6)AfterRemove事件:在删除成员后响应。

(二)构建一个用户窗体测试前面的类:

1.窗体上包含四个CommandButton,分别完成如下功能:

(1)增加成员

使用InputBox输入Student成员的Name,完成增加。

(2)删除成员
使用InputBox输入Student成员的Id或自然序号,完成删除。
(3)显示学员总数。
使用MsgBox显示Student成员总数。
(4)查询学员
使用InputBox输入Student成员的Id或自然序号,然后使用MsgBox显示相应Student成员的Name。

2.一个ListView,即时显示现有的所有Student成员。
3.事件处理
(1)BeforeAdd事件,查找现有成员的Name是否有和要增加的成员的Name相同的,如有,则给出提示,让用户选择是否增加。

(2)AfterRemove事件,刷新ListView显示

(三)未尽之处自由发挥,假定用户操作规范,可不考虑错误处理。

参考答案:

 

[此贴子已经被作者于2007-8-16 14:44:03编辑过]
回复

使用道具 举报

 楼主| 发表于 2006-11-16 09:53 | 显示全部楼层

八、未完的结尾

VBA类虽然留给了我们一些遗憾,比如不能构建隐藏成员、默认成员,也不能创建列举属性,但并不影响它作为VBA的一项非常有用技术。本文期望的,是把您带入这个大门,不知做到了没有,对它的进一步探讨,以后有机会再和朋友们一起学习吧。

[em12]

回复

使用道具 举报

发表于 2007-3-28 08:41 | 显示全部楼层

精华好贴!对版主的水平非常钦佩。

谢谢版主的指导,要抽时间好好学学,也不枉费版主的努力。

回复

使用道具 举报

发表于 2006-11-16 13:01 | 显示全部楼层

好,谢谢楼主分享!

回复

使用道具 举报

发表于 2006-11-21 09:48 | 显示全部楼层

虽看不大懂!!但是好东东!,谢了!
回复

使用道具 举报

发表于 2006-11-21 11:41 | 显示全部楼层

哈哈,顶

回复

使用道具 举报

发表于 2006-11-25 17:55 | 显示全部楼层

高手哦
回复

使用道具 举报

发表于 2006-12-1 18:51 | 显示全部楼层

谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|Excel精英培训 ( 豫ICP备11015029号 )

GMT+8, 2024-4-27 01:20 , Processed in 0.377255 second(s), 7 queries , Gzip On, Yac On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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