Event 语句
定义用户自定义的事件。
语法
[Public] Event procedurename [(arglist)]
Event 语句包含下面部分:
部分 描述
Public 可选的。指定该 Event 在整个工程中都是可见的。缺省情况下 Events 类型是 Public。应注意,事件只能在所声明的模块中产生。
procedurename 必需的。事件的名称;遵循标准的变量命名约定。
arglist 参数的语法及语法的各个部分如下:
[ByVal | ByRef] varname[( )] [As type]
部分 描述
ByVal 可选的。表示该参数是按值传递的。
ByRef 可选的。表示该参数是按地址传递的。ByRef 是 Visual Basic 的缺省设置。
varname 必需的。代表要传递给过程的参数变量的名称;遵循标准的变量命名约定。
type 可选的。指传递给过程的参数的数据类型;可以是 Byte、布尔、Integer、Long、Currency、Single、Double、Decimal(目前尚不支持)、Date、String(只支持变长)、Object、Variant、用户定义类型或对象类型。
说明
事件被声明之后,就可以使用 RaiseEvent 语句来产生该事件。如果在标准模块中出现 Event 声明,就会产生语法错误。不能声明带返回值的事件。在下面的代码段中,给出了声明事件和产生事件的典型事件:
'在类模块的模块级中声明一个事件
Event LogonCompleted (UserName as String)
Sub
RaiseEvent LogonCompleted("AntoineJan")
End Sub
注意 可以象声明过程的参数一样来声明事件的参数,但有以下不同:事件不能有带命名参数、Optional 参数、或者 ParamArray 参数。事件没有返回值。
=======================================================================================
运用属性过程
Visual Basic 提供下表所列的三种属性过程。
过程 目的
Property Get 返回属性的值
Property Let 设置属性的值
Property Set 设置对象属性的值(即,该属性含有对象引用)。
从上表可见,每一个属性过程都有自己特殊的功能。典型的属性由一对属性过程组成:Property Get 检索属性的值,Property Let 或 Property Set 给属性赋值。
这些作用在有些情况下可能重叠。有两类赋值的属性过程的原因,是因为将对象引用赋给对象变量时,Visual Basic 有特殊的语法:
Dim wdg As Widget
Set wdg = New Widget
规则很简单:如果有 Set 语句,则 Visual Basic 调用 Property Set,如果没有则调用 Property Let。
提示 返回到经典的 Basics 语法,为了正确使用 Property Let 和 Property Set 保持清洁整齐,应键入 Let x = 4(直到今天 Visual Basic 还支持的语法)而不是 x = 4,。Visual Basic总是根据赋值类型决定调用属性过程— 对于 Let x = 4 调用 Property Let,对于 Set c1 = New Class1(对象属性)则调用 Property Set。
详细信息 “编程基础”中“对象使用”解释 Set 语句对对象变量的使用。
读写属性
下列编码显示了典型的读写属性:
'属性值的私有存储区。
Private mintNumberOfTeeth As Integer
Public Property Get NumberOfTeeth() As Integer
NumberOfTeeth = mintNumberOfTeeth
End Property
Public Property Let NumberOfTeeth(ByVal NewValue _
As Integer)
'(省略验证属性值代码。)
mintNumberOfTeeth = NewValue
End Property
存储了属性值的私有变量名,由作用域前缀 (m),类型前缀 (int) 和名称 (NumberOfTeeth) 组成,其中,作用域前缀 (m) 指明变量是模块级的。使用属性相同的名称可指明该变量和属性是相关的。
毫无疑问,已经注意到,这里和以前的示例一样,含有读写属性的属性过程名必须是相同的。
注意 属性过程缺省为公共的,因此,如果省略 Public 关键词,则属性过程仍是公共的。如果想要使属性为私有(只有对象内部才可访问),必须用 Private 关键词声明。即使不是必须,最好还是使用 Public 关键词,因为这可使意图清楚。
运行和播放属性过程
单步运行一些属性过程代码是有益处的。使用“工程”菜单,打开一个新的 Standard Exe 工程,并增添一个类模块。如上所示,从 NumberOfTeeth 属性复制代码到 Class1。
切换到 Form1,将下列代码添加到 Load 事件中:
Private Sub Form_Load()
Dim c1 As Class1
Set c1 = New Class1
'赋给新的属性值。
c1.NumberOfTeeth = 42
'显示属性值。
MsgBox c1.NumberOfTeeth
End Sub
按 F8 键,单步运行代码。注意,当属性被赋值时,运行跳到 Property Let,当检索属性值时,运行跳到 Property Get。将会发现,对属性过程其它组合,重复做这种练习是很有用的。
属性过程对的参数必须匹配
至今所见的属性过程示例都很简单,对多数属性而言属性过程也将是这样。但是,属性过程可有多个参数— 甚至可选参数。多个参数中最有用的是数组,下面将讨论。
当使用多个参数时,属性过程对的参数必须匹配。下表给出了在属性过程声明中参数的要求。
过程 声明语法
Property Get Property Get propertyname(1,..., n) As type
Property Let Property Let propertyname(1,..., n, n+1)
Property Set Property Set propertyname(1,..., n, n+1)
在 Property 过程中,从第一个参数到倒数第二个参数 (1,..., n),必须具有与过程相同的名称和数据类型。就象其它过程类型一样,列表中必需参数应排在第一个可选参数之前。
可能注意到,Property Get 过程的声明比相关的 Property Let 或 Property Set少一个参数。Property Get 过程的数据类型的声明必须与 Property Let 或 Property Set 最后一个参数 (n+1) 的数据类型一样。
例如,一个类似二维数组的属性的 Property Let 声明:
Public Property Let Things(ByVal X As Integer, _
ByVal Y As Integer, ByVal Thing As Variant)
'(省略给数组元素赋值的代码。)
End Property
Property Get 的参数声明必须与 Property Let 过程的参数名称和数据类型相同:
Public Property Get Things(ByVal X As Integer, _
ByVal Y As Integer) As Variant
'(省略从数组取值的代码。)
End Property
在 Property Set 声明中的最后参数的数据类型,要么是对象类型,要么是Variant 类型。
参数匹配
图 9.8 给出了这些参数匹配规则的理由。并显示了 Visual Basic 如何将赋值语句部分与 Property Let 参数相匹配。
图 9.8 Property Let 过程的调用
带多参数的属性过程最常用于创建属性数组。
只读属性
要创建只读属性,只须简单地省略 Property Let 或(对于对象属性)Property Set。
对象属性
若要创建一个读写对象属性,应使用 Property Get 和 Property Set 如:
Private mwdgWidget As Widget
Public Property Get Widget() As Widget
'Set 语句被用来返回一个对象引用。
Set Widget = mwdgWidget
End Property
Public Property Set Widget(ByVal NewWidget As Widget)
Set mwdgWidget = NewWidget
End Property
Variants 属性
Variants 数据类型的读写属性是最复杂的。如下所示,使用三种属性过程类型:
Private mvntAnything As Variant
Public Property Get Anything() As Variant
'Set 语句只用于包含了对象引用的任何属性。
If IsObject(mvntAnything) Then
Set Anything = mvntAnything
Else
Anything = mvntAnything
End If
End Property
Public Property Let Anything(ByVal NewValue As Variant)
'(省略验证代码。)
mvntAnything = NewWidget
End Property
Public Property Set Anything(ByVal NewValue As Variant)
'(省略验证代码。)
Set mvntAnything = NewWidget
End Property
在正确环境中,Property Set 和 Property Let 总是很正常的使用。但是,使用 Property Get 必须考虑以下二种情况:
strSomeString = objvar1.Anything
Set objvar2 = objvar1.Anything
在第一种情况中,Anything 属性包含了字符串,它赋给了 String 变量。在第二个情况中,Anything 属性包含了对象引用,它被赋给对象变量。
通过使用 IsObject 函数,在返回值之前测试私有 Variants 变量,可对 Property Get 进行编程来处理这两种情况。
自然,当属性包含对象引用时,如果第一条编码被调用,将会出现错误,但这不是 Property Get 问题,而是使用 Variants 属性的问题。
仅写一次属性
属性过程有几种可能的组合。所有的组合都是有效的,但有些相对来说不太常用,比如只写属性(只有 Property Let,而无 Property Get)。有些则取决于另外的因素,而不是所组合的属性过程类型。
例如,如本章后“对象模型”所描述的那样,当通过创建一个对象模型在程序中组织对象时,可能想让该对象能引用包含它的对象。使用 Parent 属性可这样做。
当对象创建时,应设置 Parent 属性,但此后,可能想防止其被有意或无意地改变。以下示例显示了 Account 对象如何使用 Parent 属性。该属性指向含有帐号的 Department 对象。
'Parent 属性要用私有数据存储
Private mdeptParent As Department
Property Get Parent() As Department
'使用 Set 语句引用对象。
Set Parent = mdeptParent
End Property
'属性值只能被设置一次。
Public Property Set Parent(ByVal NewParent _
As Department)
If deptParent Is Nothing Then
'赋初值。
Set mdeptParent = NewParent
Else
Err.Raise Number:=vbObjectError + 32144, _
Description:="Parent property is read-only"
End If
End Property
当访问 Account 对象的父对象时,例如通过代码 strX = acctNew.Parent.Name 获取部门名称,Property Get 被用于返回对父对象的引用。
该示例中,编入 Property Set 是为了使 Parent 属性只能被设置一次。例如,当 Department 对象创建一个新的帐号时,可以执行代码 Set acctNew.Parent = Me 设置属性。此后,该属性为只读的。
详细信息 因为在 Visual Basic 中窗体是类,故可向窗体添加用户属性。请参阅本章前面“定制窗体类”的内容。
======================================================================
Property Get 语句
声明 Property 过程的名称,参数以及构成其主体的代码,该过程获取一个属性的值。
语法
[Public | Private | Friend] [Static] Property Get name [(arglist)] [As type]
[statements]
[name = expression]
[Exit Property]
[statements]
[name = expression]
End Property
Property Get 语句的语法包含下面部分:
部分 描述
Public 可选的。表示所有模块的所有其它过程都可访问 Property Get 过程。如果在包含 Option Private 的模块中使用,则该过程在该工程外是不可使用的。
Private 可选的。表示只有包含其声明的模块的其它过程可以访问该 Property Get 过程。
Friend 可选的。只能在类模块中使用。表示该 Property Get 过程在整个工程中都是可见的,但对对象实例的控制者是不可见的。
Static 可选的。表示在调用之间保留该 Property Get 过程的局部变量的值。Static 属性对在该 Property Get 过程外声明变量不会产生影响,即使过程中也使用了这些变量。
name 必需的。Property Get 过程的名称;遵循标准的变量命名约定,但不能与同一模块中的 Property Let 或 Property Set 过程同名。
arglist 可选的。代表在调用时要传递给 Property Get 过程的参数的变量列表。多个变量则用逗号隔开。Property Get 过程中的每个参数的名称和数据类型必须与相应 Property Let 过程(如果存在)中的参数一致。
type 可选的。该 Property Get 过程的返回值的数据类型;可以是 Byte、Boolean、Integer、Long、Currency、Single、Double、Decimal(目前尚不支持)、Date、String(除定长)、Object、Variant或任何用户定义类型。任何类型的数组都不能作为返回值,但包含数组的 Variant 可以作为返回值。
Property Get 过程的返回值类型必须与相应的 Property Let 过程(如果有)的最后一个(有时是仅有的)参数的数据类型相同,该 Property Let 过程将其右边表达式的值赋给属性。
statements 可选的。Property Get 过程体中所执行的任何语句组。
expression 可选的。Property Get 语句所定义的过程返回的属性值。
其中的 arglist 参数的语法及语法的各个部分如下:
[Optional] [ByVal | ByRef] [ParamArray] varname[( )] [As type] [= defaultvalue]
部分 描述
Optional 可选的。表示参数不是必需的。如果使用了该选项,则 arglist 中的后续参数都是可选的,而且必须都使用 Optional 关键字声明。
ByVal 可选的。表示该参数按值传递。
ByRef 可选的。表示该参数按地址传递。ByRef 是 Visual Basic 的缺省选项。
ParamArray 可选的。只用于 arglist 的最后一个参数,指明最后这个参数是一个 Variant 元素的 Optional 数组。使用 ParamArray 关键字可以提供任意数目的参数。ParamArray 关键字不能与 ByVal、ByRef 或 Optional 一起使用。
varname 必需的。代表参数的变量名称;遵循标准的变量命名约定。
type 可选的。传递给该过程的参数的数据类型;可以是 Byte、Boolean、Integer、Long、Currency、Single、Double、Decimal(目前尚不支持)、Date、String(只支持变长)、Object 或 Variant。如果参数不是 Optional,则也可以是用户自定义的类型,或对象类型。
defaultvalue 可选的。任何常数或常量表达式。只在 Optional 参数时是合法的。如果类型为 Object,则显式的缺省值只能是 Nothing。
说明
如果没有使用 Public,Private 或 Friend 显式指定,则 Property 过程缺省为公用。如果没有使用 Static,则在调用之后不会保留局部变量的值。Friend 关键字只能在类模块中使用。Friend 过程可以被工程中的任何模块的过程访问。Friend 过程不会在其父类的类型库中出现,且 Friend 过程不能被后期绑定。
所有的可执行代码都必须属于某个过程。不能在别的 Property、Sub 或 Function 过程中定义 Property Get 过程。
Exit Property 语句使执行立即从一个 Property Get 过程中退出。程序接着从调用该 Property Get 过程的语句下一条语句开始执行。在 Property Get 过程中的任何位置都可以有 Exit Property 语句。
Property Get 过程与 Sub 和 Property Let 过程的相似之处是:Property Get 过程是一个可以获取参数,执行一系列语句,以及改变其参数的值的独立过程,而与 Sub 和 Property Let 过程不同的是:当要返回属性的值时,可以在表达式的右边使用 Property Get 过程,这与使用 Function 或属性名的方式一样。
================================================================
Property Let 语句
声明 Property Let 过程的名称,参数以及构成其主体的代码,该过程给一个属性赋值。
语法
[Public | Private | Friend] [Static] Property Let name ([arglist,] value)
[statements]
[Exit Property]
[statements]
End Property
Property Let 语句的语法包含下面部分:
部分 描述
Public 可选的。表示所有模块的所有其它过程都可访问该 Property Let 过程。如果在包含 Option Private 的模块中使用,则这个过程在该工程外是不可使用的。
Private 可选的。表示只有在包含其声明的模块的其它过程中可以访问该 Property Let 过程。
Friend 可选的。只能在类模块中使用。表示该 Property Let 过程在整个工程中都是可见的,但对于对象实例的控制者是不可见的。
Static 可选的。表示在调用之间将保留 Property Let 过程的局部变量的值。Static 属性对在该 Property Let 过程外声明的变量不会产生影响,即使过程中也使用了这些变量。
name 必需的。Property Let 过程的名称;遵循标准的变量命名约定,但不能与同一模块中的 Property Get 或 Property Set 过程同名。
arglist 可选的。代表在调用时要传递给 Property Let 过程的参数的变量列表。多个变量则用逗号隔开。Property Let 过程中的每个参数的名称和数据类型必须与 Property Get 过程中的相应参数一致。
value 必需的。指用于给属性赋值的变量。当调用该过程时,这个参数出现在调用表达式的右边。value 的数据类型必须和相应的 Property Get 过程的返回值类型一致。
statements 可选的。Property Let 过程中执行的任何语句组。
其中的 arglist 参数的语法和语法的各个部分如下:
[Optional] [ByVal | ByRef] [ParamArray] varname[( )] [As type] [= defaultvalue]
部分 描述
Optional 可选的。表示参数不是必需的。如果使用了该选项,则 arglist 中的后续参数都必须是可选的,而且必须都使用 Optional 关键字声明。注意,一个 Property Let 表达式的右边是不可能为 Optional 的。
ByVal 可选的。表示该参数按值传递。
ByRef 可选的。表示该参数按地址传递。ByRef 是 Visual Basic 的缺省选项。
ParamArray 可选的。只用于 arglist 的最后一个参数,指明最后这个参数是一个 Variant 元素的 Optional 数组。使用 ParamArray 关键字可以提供任意数目的参数。ParamArray 关键字不能与 ByVal、ByRef 或 Optional 一起使用。
varname 必需的。代表参数变量的名称;遵循标准的变量命名约定。
type 可选的。传递给该过程的参数的数据类型;可以是 Byte、Boolean、Integer、Long、Currency、Single、Double、Decimal(目前尚不支持)、Date、String(只支持变长)、Object 或 Variant。如果参数不是 Optional,则也可以是用户定义类型,或对象类型。
defaultvalue 可选的。任何常数或常数表达式。只在 Optional 参数时是合法的。如果类型为 Object,则显式的缺省值只能是 Nothing。
注意 每个 Property Let 语句必须为其所定义的过程定义至少一个参数。当这个 Property Let 语句所定义的过程被调用时,该参数(如果有多个参数则指最后一个)就包含了将赋给属性的实际值。该参数就是前述语法中的 value。
说明
如果没有使用 Public、Private 或 Friend 显式指定,则 Property 过程缺省为公用。如果没有使用 Static,则不会在调用之后保留局部变量的值。Friend 关键字只能在类模块中使用。不过 Friend 过程可以被工程中的任何模块的过程访问。Friend 过程不会在其父类的类型库中出现,且 Friend 过程不能被后期绑定。
所有的可执行代码都必须属于某个过程。不能在别的 Property、Sub 或 Function 过程中定义 Property Let 过程。
Exit Property 语句使执行立即从一个 Property Let 过程中退出。程序接着从调用该 Property Let 过程的语句下一条语句开始执行。在 Property Let 过程的任何位置都可以有 Exit Property 语句。
Property Let 过程与 Function 和 Property Get 过程的相似之处是:Property Let 过程是一个可以获取参数,执行一系列语句,以及改变其参数值的独立过程。而与 Function 和 Property Get 过程不同的是:这两个过程都有返回值,而 Property Let 过程只能用于属性表达式或 Let 语句的左边。
====================================================================
Property Set 语句
声明 Property 过程的名称,参数以及构成其主体的代码,该过程设置一个对象引用。
语法
[Public | Private | Friend] [Static] Property Set name ([arglist,] reference)
[statements]
[Exit Property]
[statements]
End Property
Property Set 语句的语法包含下面部分:
部分 描述
Optional 可选的。表示调用者可以提供或不提供该参数。
Public 可选的。表示所有模块的所有其它过程都可访问这个 Property Set 过程。如果在包含 Option Private 的模块中使用,则这个过程在该工程外是不可使用的。
Private 可选的。表示只有包含其声明的模块的其它过程可以访问该 Property Set 过程。
Friend 可选的。只能在类模块中使用。表示该 Property Set 过程在整个工程中都是可见的,但对对象实例的控制者是不可见的。
Static 可选的。表示在调用之间保留 Property Set 过程的局部变量的值。Static 属性对在该 Property Set 外声明的变量不会产生影响,即使过程中也使用了这些变量。
name 必需的。Property Set 过程的名称;遵循标准的变量命名约定,但不能与同一模块中的 Property Get 或 Property Let 过程同名。
arglist 可选的。代表在调用时要传递给 Property Set 过程的参数的变量列表。对于多个变量则用逗号隔开。
reference 必需的。对象引用赋值的右边所使用的包含对象引用的变量。
statements 可选的。Property 过程体中所执行的任何语句组。
其中的 arglist 参数的语法以及语法各个部分如下:
[Optional] [ByVal | ByRef] [ParamArray] varname[( )] [As type] [= defaultvalue]
部分 描述
Optional 可选的。表示参数不是必需的。如果使用了该选项,则 arglist 中的后续参数都必须是可选的,而且必须都使用 Optional 关键字声明。注意:Property Set 表达式的右边不可能是 Optional。
ByVal 可选的。表示该参数按值传递。
ByRef 可选的。表示该参数按地址传递。ByRef 是 Visual Basic 的缺省选项。
ParamArray 可选的。只用于 arglist 的最后一个参数,指明最后这个参数是一个 Variant 元素的 Optional 数组。使用 ParamArray 关键字可以提供任意数目的参数。ParamArray 关键字不能与 ByVal、ByRef 或 Optional 一起使用。
varname 必需的。代表参数的变量的名称;遵循标准的变量命名约定。
type 可选的。传递给该过程的参数的数据类型;可以是 Byte、Boolean、Integer、Long、Currency、Single、Double、Decimal(目前尚不支持)、Date、String(只支持变长)、Object 或 Variant。如果参数不是 Optional,则也可以是用户定义类型,或对象类型。
defaultvalue 可选的。任何常数或常数表达式。只在 Optional 参数时是合法的。如果类型为 Object,则显式的缺省值只能是 Nothing。
注意 每个 Property Set 语句必须为其所定义的过程定义至少一个参数。当 Property Set 语句所定义的过程被调用时,这个参数(如果有多个参数则指最后一个)就包含了将赋给属性的实际的对象引用。这个参数就是前述语法中的 reference。它不能是 Optional。
说明
如果没有使用 Public、Private 或 Friend 显式指定,则 Property 过程按缺省情况是公用的。如果没有使用 Static,则在调用之后不会保留局部变量的值。Friend 关键字只能在类模块中使用。不过 Friend 过程可以被工程中的任何模块的过程访问。Friend 过程不会在其父类的类型库中出现,且 Friend 过程不能被后期绑定。
所有的可执行代码都必须属于某个过程。不能在别的 Property、Sub 或 Function 过程中定义 Property Set 过程。
Exit Property 语句使执行立即从一个 Property Set 过程中退出。程序接着从调用该 Property Set 过程的语句下一条语句执行。在 Property Set 过程的任何位置都可以有 Exit Property 语句。
Property Set 过程与 Function 和 Property Get 过程的相似之处是:它们都是一个可以获取参数,执行一系列语句,以及改变其参数的值的独立过程。而与 Function 和 Property Get 过程不同的是:这两个过程都有返回值,而 Property Set 过程只能用于对象引用赋值(Set 语句)的左边。