Sub Question() myVar = MsgBox(Prompt:="I enjoy my job.", _ Title:="Answer Box", Buttons:="4") MsgBox myVar End Sub
11.3.1.3 选项语句的语法 语法:Option Compare {Binary | Text | Database} 在 Option Compare 语句的语法中,大括号和垂直线指示三项中的强制性选择(在Visual Basic 的语句中不用键入大括号)。例如,下列的语句指出在模块中,字符串的比较是根据文本的排序顺序而不区分大小写。 Option Compare Text
11.3.1.4 Dim 语句的语法 语法: Dim varname[ ( [subscripts] ) ] [As type] [, varname[([subscripts])] [As type]] . . . 在 Dim 语句的语法中,Dim 是必备的关键字。而唯一必备的元素是 varname(变量名)。例如,下列的语句创建三个变量:myVar、 nextVar 和 thirdVar。它们会自动被声明成 Variant 变量。 Dim myVar, nextVar, thirdVar 下面的示例声明了一个String 型的变量。它包含了数据类型,如此可以节省内存并且可帮助从代码中找出错误。 Dim myAnswer As String 若在一个语句中声明好几个变量,则必须包含每一个变量的数据类型。变量在声明时若少了数据类型,则会自动地声明为Variant 。 Dim x As Integer, y As Integer, z As Integer 在下列的语句中,x 与 y 都被指定成 Variant 数据类型,只有 z 被指定成 String 数据类型。 Dim x, y As Integer,Z As String 如果声明一个数组变量,则必须包含圆括号,但下标则是可选的。下列的语句中定义了一个动态数组 myArray。 Dim myArray()
程序非常大并且使用很多变量。 程序的执行速度必须尽可能得快。 将数据直接写到随机存储文件中。 除了 Variant 之外,支持的数据类型包括 Byte、Boolean、 Integer、Long、Single、Double、Currency、Decimal、Date、Object 以及 String。可使用 Dim 语句去声明一个指定类型的变量,例如: Dim X As Integer 上述语句声明变量 X 是一个整型,其范围介于-32,768~32,767 之间。如果试着去设置超出此范围的数值给 X ,则会有错误发生。如果试着去指定一个分数给 X,则此分数会自动四舍五入。例如: X = 32768 ' 产生错误。 X = 5.9 ' 设置 x = 6。
11.3.3 Visual Basic 的命名规则 当在 Visual Basic 的模块中为过程、常数、变量以及参数命名时,可以使用下列的规则: 第一个字符必须使用英文字母。 不能在名称中使用空格、句点(.)、惊叹号(!)、或 @、、 $,# 等字符。 名称的长度不可以超过 255 个字符。 通常,使用的名称不能与 Visual Basic 本身的 Function 过程、语句以及方法的名称相同。必须退出使用与程序语言的关键字相同的名称。若所使用的内在语言函数,语句或方法与所指定的名称相冲突,则必须显示地识别它。常规会将内建函数,语句或方法的名称之前加上关联的类型库的名称。例如,如果有一个名为 Left 的变量,则只能用 VBA.Left 来调用 Left 函数。 不能在范围的相同层次中使用重复的名称。例如,不能在同一过程中声明两个命名为 age 的变量。然而,可以在同一模块中声明一个命名为 age 的私有变量和命名为 age 的过程级别的变量。 注意: Visual Basic 不区分大小写,但它会在名称被声明的语句处保留大写。
11.3.4 声明变量、常数和数组
11.3.4.1 声明变量 通常会使用 Dim 语句来声明变量。一个声明语句可以放到过程中以创建属于过程的级别的变量。或在声明部分可将它放到模块顶部,以创建属于模块级别的变量。 下面的示例创建了变量 strName 并且指定为 String 数据类型。 Dim strName As String 如果该语句出现在过程中,则变量 strName 只可以在此过程中被使用。如果该语句出现在模块的声明部分,则变量 strName 可以被此模块中所有的过程所使用,但是不能被同一工程中不同的模块所含过程来使用。为了使变量可被工程中所有的过程所使用,则在变量前加上 Public 语句,如以下的示例: Public strName As String 变量可以声明成下列数据类型中的一种:Boolean、Byte、 Integer、Long、Currency、Single、Double、Date、String(变长字符串)、String * length (定长字符串)、Object 或 Variant。如果未指定数据类型,则 Variant 数据类型被赋予默认。也可以使用 Type 语句来创建用户自定义类型。 可以在一个语句中声明几个变量。而为了指定数据类型,必须将每一个变量的数据类型包含进来。在下面的语句中,变量 intX、 intY、与 intZ 被声明为 Integer 类型。 Dim intX As Integer, intY As Integer, intZ As Integer 在下面的语句中,变量 intX 与 intY 被声明为 Variant 类型;只有intZ 被声明为 Integer 类型。 Dim intX, intY, intZ As Integer 在声明语句中,不一定要提供变量的数据类型。若省略了数据类型,则会将变量设成 Variant 类型。 使用 Public 语句:可以使用 Public 语句去声明公共模块级别变量。 Public strName As String 公有变量可用于工程中的任何过程。如果公有变量是声明于标准模块或是类模块中,则它也可以被任何引用到此公有变量所属工程的工程中使用。 使用 Private 语句:可以使用 Private 语句去声明私有的模块级别变量。 Private MyName As String 私有变量只可使用于同一模块中的过程。 注意: 在模块级别中使用 Dim 语句与使用 Private 语句是相同的。不过使用 Private 语句可以更容易地读取和解释代码。 使用Static 语句:当使用 Static 语句取代 Dim 语句时,所声明的变量在调用时仍保留它原先的值。 使用Option Explicit 语句:在 Visual Basic 中可以简单地通过一个赋值语句来隐含声明变量。所有隐含声明变量都为 Variant 类型,而Variant 类型变量比大多数其他类型的变量需要更多的内存资源。如果显式地声明变量为指定的数据类型,则应用程序将更有效。显式声明所有变量减少了命名冲突以及拼写错误的发生率。 如果不想使Visual Basic 生成隐含声明,可以将Option Explicit 语句放置于模块中所有的过程之前。这一个语句要求对模块中所有的变量做显式地声明。如果模块包含Option Explicit 语句,则当 Visual Basic 遇到一个先前未定义的变量或拼写错误,它会发生编译时间的错误。 可以设置 Visual Basic 程序环境中的某个选项,使得自动在所有新的模块中包含 Option Explicit 语句。 注意: 需显式地声明固定大小的数组与动态数组。 为自动化声明一个对象变量:当使用一个应用程序去控制另外一个应用程序的对象时,应该设置一个对于其他应用程序的类型库的引用。若设置一个引用,则可以根据它们最常指定的类型来声明对象变量。例如,如果是在 Microsoft Word 中,当对 Microsoft Excel 类型库做一引用设置时,可以在 Microsoft Word 中声明 Worksheet 类型的变量来表示 Microsoft Excel 中的Worksheet 对象。 如果使用其他的应用程序去控制 Microsoft Access 对象,在多数情况下,可以根据它们最常指定的类型来声明对象变量。也可以使用关键字 New 去自动生成一个对象的新实例。然而,可能要指示它是 Microsoft Access 对象。例如,当在 Microsoft Visual Basic 里面声明一个对象变量去表示 Microsoft Access form 时,必须区别它是 Microsoft Access Form 对象或是 Visual Basic Form 对象。所以在声明变量的语句中必须要包含类型库的名称,如下面示例所示: Dim frmOrders As New Access.Form 某些应用程序并不能识别特别的 Microsoft Access 对象类型。既使已经在这些应用程序中设置了一个对 Microsoft Access 类型库的引用,必须声明所有 Microsoft Access 对象变量为 Object 类型。不能使用 New 关键字去创建这个对象的新实例。下面的示例显示了不能识别 Microsoft Access 对象类型的应用程序,如何去声明一个变量用来表示 Microsoft Access Application 对象。然后应用程序创建一个 Application 对象的实例。 Dim appAccess As Object Set appAccess = CreateObject("Access.Application")
11.3.4.2 声明常数 如果要声明一个常数,可以使用 Const 语句去声明,并且设置它的值;而在常数声明完之后,则不能加以更改或赋予新值。 在声明部分,可以在过程中或者在模块顶部声明常数。模块级别中的常数默认为私有的。若要声明一个公共模块级别常数,则可以在 Const 语句前加上 Public 这个关键字。也可以利用在 Const 语句前加上 Public 关键字来明确地声明一个私有的常数,使得我们可更容易地去读取并且解释代码。 下面的示例,声明了一个 Public 常数 conAge 为 Integer 类型,并且指定它的值 为34。 Public Const conAge As Integer = 34 常数可以声明成下列数据类型中的一种:Boolean、Byte、 Integer、Long、Currency、Single、Double、Date、String 或 Variant。因为已经知道常数的值,所以可以指定 Const 语句中的数据类型。关于数据类型的详细信息。 可以在一个语句中声明数个常数。为了指定数据类型,必须将每一个常数的数据类型包含进来。在下面的语句中,常数 conAge 和 conWage 被声明为 Integer 类型。 Const conAge As Integer = 34, conWage As Currency = 35000
11.3.5 过程及其调用 11.3.5.1 Function 过程 Function 过程是一系列由 Function 和 End Function 语句所包含起来的 Visual Basic 语句。Function 过程和 Sub 过程很类似,但函数可以返回一个值。Function 过程可经由调用者过程通过传递参数,例如常数、变量、或是表达式等来调用它。如果一个 Function 过程没有参数,它的 Function 语句必须包含一个空的圆括号。函数会在过程的一个或多个语句中指定一个值给函数名称来返回值。 在下面的示例中,Celsius 函数会根据华氏温度来计算摄氏温度。当 Main 过程调用此函数时,会有一包含参数值的变量传递给此函数。而计算的结果会返回到调用的过程,并且显示在一个消息框中。 Sub Main() temp = Application.InputBox(Prompt:= _ "Please enter the temperature in degrees F.", Type:=1) MsgBox "The temperature is " Celsius(temp) " degrees C." End Sub Function Celsius(fDegrees) Celsius = (fDegrees - 32) * 5 / 9 End Function
11.3.5.2 Sub 过程 Sub 过程是一系列由 Sub 和 End Sub 语句所包含起来的 Visual Basic 语句,它们会执行动作却不能返回一个值。Sub 过程可有参数,例如常数、变量、或是表达式等来调用它。如果一个 Sub 过程没有参数,则它的 Sub 语句必须包含一个空的圆括号。 下面 Sub 过程中,每一行都有注释来解释它的作用:
'声明过程命名为 GetInfo '该 Sub 过程没有参数 Sub GetInfo() '声明字符串变量命名为 answer Dim answer As String '指定 InputBox 函数的返回值给 answer answer = InputBox(Prompt:="What is your name?") '条件 If...Then...Else 语句 If answer = Empty Then '调用 MsgBox 函数 MsgBox Prompt:="You did not enter a name." Else 'MsgBox 函数与 answer 变量连接。 MsgBox Prompt:="Your name is " answer '结束 If...Then...Else 语句 End If '结束 Sub 过程 End Sub
11.3.5.3 属性过程 属性过程是一系列的 Visual Basic 语句,它允许程序员去创建并操作自定义的属性。属性过程可以用来为窗体,标准模块,以及类模块创建只读属性。可被用来在代码中代替 Public 变量,当设置属性值时上述动作应被执行。 与 Public 变量不同,在对象浏览器中属性过程会有一些帮助字符串指定给自定义的属性。 当创建一个属性过程时,它会变成此过程所包含的模块的一个属性。Visual Basic 提供下列三种类型的 Property 过程: Property Let 用来设置属性值的过程。 Property Get 用来返回属性值的过程。 Property Set 用来设置对对象引用的过程。 声明属性过程的语法如下所示: [Public | Private] [Static] Property {Get | Let | Set} propertyname_ [(arguments)] [As type] statements End Property 属性过程通常是成对使用的:Property Let 与 Property Get 一组,而 Property Set 与 Property Get 一组。单独声明一个 Property Get 过程就像声明只读属性。三个 Property 过程一起使用时,只有对 Variant 变量有用,因为只有 Variant 才能包含一个对象或其他数据类型的信息。Property Set 本意是使用在对象上;而 Property Let 则不是。 在 Property 过程声明中所需要的参数如下: Property Get Property Get propname(1, ..., n) As type Property Let Property Let propname(1, ..., n, n+1) Property Set Property Set propname(1, ..., n, n+1) 在具有相同名称属性过程中,从第一个到最后一个参数(1, ..., n)都必须共享相同的名称与数据类型。 Property Get 过程声明时所需的参数比相关的 Property Let 以及 Property Set 声明少一个。Property Get 过程的数据类型必须与相关的 Property Let 以及 Property Set 声明中的最后 (n+1)个参数的类型相同。例如,如果声明下列的 Property Let 过程,则 Property Get 声明所使用参数的名称与数据类型必须同 Property Let 过程中所用的一样。
Property Let Names(intX As Integer, intY As Integer, varZ As Variant) ' 执行语句. End Property Property Get Names(intX As Integer, intY As Integer) As Variant ' 执行语句. End Property 在 Property Set 声明中,最后一个参数的数据类型必须是对象类型或是 Variant。
11.3.5.4 调用 Sub 以及 Function 过程 从其他过程调用一个 Sub 过程时,必须键入过程名称以及任何需要的参数值。而 Call 语句并不需要,不过若使用它,则任何参数必须以括号括起来。 可以使用 Sub 过程去组织其他的过程,因此可以较容易地了解并调试它们。在下面的示例中,Sub 过程 Main 传递参数值 56 去调用 Sub 过程 MultiBeep。运行 MultiBeep 后,控件返回 Main,然后 Main 调用 Sub 过程 Message。Message 显示一个信息框;当按“确定”键时,控件会返回 Main,接着 Main 退出执行。
Sub Main() MultiBeep 56 Message End Sub Sub MultiBeep(numbeeps) For counter = 1 To numbeeps Beep Next counter End Sub Sub Message() MsgBox "Time to take a break!" End Sub 1.调用具有多个参数的 Sub 过程 下面的示例展示了调用具有多个参数的 Sub 过程的两种不同方法。当第二次调用 HouseCalc 时,因为使用 Call 语句所以需要利用括号将参数括起来。
Sub Main() HouseCalc 99800, 43100 Call HouseCalc(380950, 49500) End Sub Sub HouseCalc(price As Single, wage As Single) If 2.5 * wage = 0.8 * price Then MsgBox "You cannot afford this house." Else MsgBox "This house is affordable." End If End Sub 在调用 Function 过程时使用括号。 为了使用函数的返回值,必须指定函数给变量,并且用括号将参数封闭起来;如下示例所示: Answer3 = MsgBox("Are you happy with your salary?", 4, "Question 3") 如果不在意函数的返回值,可以用调用 Sub 过程的方式来调用函数。如下面示例所示,可以省略括号,列出参数并且不要将函数指定给变量: MsgBox "Task Completed!", 0, "Task Box" 注意在上述例子中若包含括号,则语句会导致一个语法错误。 2.传递命名参数 Sub 或 Function 过程中的语句可以利用命名参数来传递值给被调用的过程。参数有两种传递方式:按值来传递和按地址来传递。按值传递只是传递参数的一个副本,在函数内建立一个同参数类型及内容一样的变量,在过程体内部参数对参数所作的改变不会影响到实际参数;按地址传递则不然,它传递的是实际参数的地址,过程中所有对参数的改变都将影响到实际参数”。命名参数的组成是由参数名称紧接着冒号(:=)以及等号,然后指定一个值给参数。 下面的示例使用命名参数来调用不具返回值的 MsgBox 函数。 MsgBox Title:="Task Box", Prompt:="Task Completed!" 下面的示例使用命名参数调用 MsgBox 函数。将返回值指定给变量 answer3。 answer3 = MsgBox(Title:="Question 3", _ Prompt:="Are you happy with your salary?", Buttons:=4)
11.3.5.5 调用属性过程 表11-2 列出了调用属性过程的语法。
当调用一个 Property Let 或 Property Set 过程时,总是会有一个参数出现在等号(=)的右边。 当用多个参数声明一个 Property Let 或 Property Set 过程时, Visual Basic 传递调用的右边参数,给 Property Let 或 PropertySet 声明中的最后一个参数。例如,图11-18 显示了 Property 过程调用中的参数与 Property Let 声明中的参数的关系: