结束条件语句序列] Loop While条件式 循环流程如图8.21所示。
5.Do-Loop Until语句 Do 循环体 [条件语句序列 Exit Do
结束条件语句序列] Loop Until条件式 循环流程如图8.22所示。
这样,就有4种Do循环结构。使用时,分析方法基本相同。即根据条件式结果的真假,对循环与否做出正确判断。 6.While-Wend语句
While-Wend循环与Do While-Loop结构类似,但不能在While-Wend循环中使用Exit Do语句。White-Wend语句格式为: While条件式 循环体 Wend
While-Wend结构主要是为了兼容QBasic和QuickBASIC而提供的。由于VBA中已有Do While-Loop循环结构,所以尽量不要使用While-Wend循环。
8.5 过程调用和参数传递
本章开始已经介绍了VBA的子过程和函数过程两种类型模块过程及相应的创建方法。下面结合实例介绍过程的调用和过程的参数传递。
8.5.1 过程调用
1.子过程的定义和调用
可以用Sub语句声明一个新的子过程、接受的参数和子过程代码。其定义格式如下 [Public|Private] [Static] Sub 子过程名([<形参>]) [<子过程语句>] [Exit Sub]
[<子过程语句>] End Sub
使用Public关键字可以使这个过程适用于所有模块中的所有其他过程;用Private关键字可 以使该子过程只适用于同一模块中的其他过程。 子过程的调用形式有两种:
Call 子过程名([<实参>]) 或 子过程名[<实参>] Access中,打开窗体的命令是DoCmd OpenForm
例8.1 下面编写一个打开指定窗体的子过程OpenForm()。代码如下: Sub OpenForms (strFormName As String)
'打开窗体过程,参数strFormName为需要打开的窗体名称 If strFormName=\
MsgBox \打开窗体名称不能为空!\警告\
Exit Sub '若窗体名称为空,显示“警告”消息,结束过程运行 End If
DoCmd OpenForm strFormName '打开指定窗体 End Sub
如果此时要调用该子过程打开名为“学生管理”的窗体,只需在主调过程合适位置增添调用语句: Call OpenForms(\学生管理\或 OpenForms\学生管理\2.函数过程的定义和调用
可以使用Function语句定义一个新函数过程、接受的参数、返回的变量类型及运行该函数过程的代码。其定义格式如下:
[Public|Private] [Static] Function 函数过程名([<形参>])[As数据类型] [<函数过程语句>]
[函数过程名=<表达式>] [Exit Function] [<函数过程语句>]
[函数过程名=<表达式>] End Function
使用Public关键字,则所有模块的所有其他过程都可以调用它。用Private关键字可以使这个函数只适用于同一模块中的其他过程。当把一个函数过程说明为模块对象中的私有函数过程时,就不能从查询、宏或另一个模块中的函数过程调用这个函数过程。
包含Static关键字时,只要含有这个过程的模块是打开的,则所有在这个过程中无论是显示还是隐含
说明的变量值都将被保留。
可以在函数过程名末尾使用一个类型声明字符或使用As子句来声明被这个函数过程返回的变量数据类型。否则VBA将自动赋给该函数过程一个最合适的数据类型。 函数过程的调用形式只有一种:函数过程名([<实参>])。
由于函数过程会返回一个数据,实际上,函数过程的上述调用形式主要有两种用法:一是将函数过程返回值作为赋值成分赋予某个变量,其格式为: 变量=函数过程名([<实参>])
二是将函数过程返回值作为某个过程的实参成分使用。
例8.9 编写一个求解圆面积的函数过程Area()。代码如下: Public Funciion Area(R As Single) As Single
'新建函数Area,返回一个单精度型值;接受单精度型参数R If R<=0 Then
MsgBox \圆的半径必须是正数值!\警告\
Area=0 '若圆半径<=0.0设置函数过程返回0值 Exit Function '结束过程运行 End If
Area=3.14*R*R '求半径为R的面的面积Area End Function
如果此时需要调用该函数过程计算半径为5的圆的面积,只要调用函数“Area(5)”即可。
需要特别指出的是,函数过程可以被查询、宏等调用使用,因此在进行一些计算控件的设计中特别有用。
8.5.2 参数传递
由上面过程定义式看到,过程定义时可以设置一个或多个形参(形式参数简称),多个形参之间用逗号分隔。其中.每个形参的完整定义格式为:
[Optional] [ByVal|ByRef] [ParamArray] varname[()] [As type] [=defaultvalue] 各项含义如下:
varname 必需的,形参名称。遵循标准的变量命名约定。 type 可选项,传递给该过程的参数的数据类型。
Optional 可选项,表示参数不是必需。如果使用了ParamArray,则任何参数都不能使用Optional。 ByVal 可选项,表示该参数按值传递。
ByRef 可选项,表示该参数按地址传递。ByRef是YBA的缺省选项n
ParaArray 可选项,只用于形参的最后一个参数,指明最后这个参数是一个Variant元素的Optional数组。使用ParamArray关键字可以提供任意数目的参数。但ParamArray关键字不能与ByVal、ByRef、或Optional一起使用。
Defaultvalue 可选项,任何常数或常数表达式。只对Optional参数合法。如果类型为Object,则显式的缺省值只能是Nothing。
含参数的过程被调用时,主调过程中的调用式必须提供相应的实参(实际参数简称),并通过实参向形参传递的方式完成过程操作。
关于实参向形参的数据传递,还需了解以下内容: (1)实参可以是常量、变量或表达式。
(2)实参数目和类型应该与形参数目和类型相匹配。除非形参定义含Optional和ParamArray选项,参数、类型可能不一致。
(3)传值调用(ByVal选项)的“单向”作用形式与传址调用(ByRef选项)的“双向”作用形式。
过程定义时,如果形式参数被说明为传值(ByVal项),则过程调用只是相应位置实参的值“单向”传送给形参处理,而被调用过程内部对形参的任何操作引起的形参值的变化均不会反馈、影响实参的值。由于这个过程,数据的传递只有单向性,故称为“传值调用”的“单向”作用形式。反之,如果形式参数被
说明为传址(ByRef项),则过程调用是将相应位置实参的地址传送给形参处理,而被调用过程内部对形参的任何操作的形参值的变化又会反向影响实参的值。在这个过程中,数据的传递具有双向性,故称为“传址调用”的“双向”作用形式。
需要指出的是,实参提供可以是常量、变量或表达式3种方法之一。常量与表达式在传递时,形参即便是传址(ByRef项)说明,实际传递的也只是常量或表达式的值,这种情况下,过程参数“传址调用”的“双向”作用形式就不起作用。但实参是变量、形参是传址(ByRef项)说明时,可以将实参变量的地址传递给形参,这时,过程参数“传址调用”的“双向”作用形式就会产生影响。 赋变量J的初始值为5
例8.20 举例说明有参过程应用,其中主调过程test_Click(),被调过程GetData(): '主调过程
Private Sub test_Click() Dim J As Integer
J=5 '赋值变量J的初始值为5
Call GetData(J) '调用过程,传递实参J(实际上是J的地值)
MsgBox J '测试观察实参J的值的变化(消息框显示J值) End Sub '被调过程
Private Sub GetData(ByRef f As Integer) '形参f被说明为ByRef传址形式的整型量 f=f+2 '表达式改变形参的值 End Sub
当运行test_Click()过程,并调用GetData()后,执行MsgBox J语句,会显示实参变量J的值已经变化为7,即被调过程GetData()中形参f变化到最后的值7(=5+2)。表明变皿的过程参数“传址调用”的“双向”作用有效。
如果将主调过程teat_Click()中的调用过程语句Call GetData(J)换成常量Call GetData(5)或表达式Call GetData(J+1),运行、测试发现,执行MsgBox J语句后,显示实参变量J的值依旧是5。表明常量和表达式的过程参数“传址调用”的“双向“作用无效。
总之,在有参过程的定义和调用中,形参的形式及实参的组织有很多的变化。如果充分了解不同的使用方式,就可以极大地提高模块化编程能力。 8.6 VBA程序运行错误处理
无论怎样为程序代码作彻底地测试与排错,程序错误仍可能出现。VBA中提供On Error GoTo语句来控制当有错误发生时程序的处理。
On Error GoTo 指令的一般语法如下: On Error GoTo 标号 On Error Resume Next On Error GoTo 0
“On Error GoTo 标号”语句在遇到错误发生时程序转移到标号所指位置代码执行。一般标号之后都是安排错误处理程序,见以下错误处理过程ErrorProc调用位置:
On Error GoTo ErrHandler '发生错误,跳转至ErrHandler位置执行 ?
ErrHandler: Call ErrorProc ?
在此例中,On Error GoTo指令会使程序流程转移到ErrHandler标号位置。一般来说,错误处理的程序代码会在程序的最后。
“On Error Resume Next”语句在遇到错误发生时不会考虑错误,并继续执行下一条语句。
“On Error GoTo 0”语句用于关闭错误处理。
如果没有用On Error GoTo语句捕捉错误,或者用On Error GoTo 0关闭了错误处理,则在错误发生后会出现一个对话框,显示出相应的出错信息。
VBA编程语言中,除使用“On Error?”语句结构来处理错误外,还提供了一个对象(Err)、一个函数(Error$())和一个语句(Error)来帮助了解错误信息。其中,Err对象的number属性返回错误代码;而Error$()函数则可以根据错误代码返回错误名称;Error语句的作用是模拟产生错误,以检查错误处理语句的正确性。
例8.21 错误处理应用。
Private Sub test_Click() '定义一事件过程
On Error GoTo ErrHandle '监控错误,安排错误处理至标号ErrHandle位置 Error11 '模拟产生代码为11的错误 Msgbox \ '没有错误,显示\!\信息 Exit Sub '正常结束过程 ErrHandle: '标号ErrHandle
MsgBox Err.Number '显示错误代码(显示为11)
MsgBox Error$(Err.Number) '显示错误名称(显示为“除数为零”) End Sub
Err对象还提供其他一些属性(如source、description等)和方法(raise、clear)来处理错误发生。
实际编程当中,需要对可能发生的错误进行了解和判断,充分利用上述错误处理机制可快还、准确地找到错误原因并加以处理,从而编写出“健壮”的程序代码来。
8.7 VBA程序的调试:设置断点、单步跟踪、设置监视窗
Acces的VBE编程环境提供了完整的一套调试工具和调试方法。熟练掌握好这些调试工具和调试方法的使用,可以快速、准确地找到问题所在,不断修改,加以完善。 一、“断点”概念
所谓“断点”就是在过程的某个特定语句上设置一个位置点以中断程序的执行。“断点”的设置和使用贯穿在程序调试运行的整个过程。 “断点”设置和取消有4种方法:
(1)选择语句行,单击“调试”工具栏中的“切换断点”可以设置和取消“断点”。 (2)选择语句行,单击“调试”菜单中的“切换断点”项可以设置和取消“断点”。 (3)选择语句行,按下键盘“F9”键可以设置和取消“断点”。 (4)选择语句行,鼠标光标移至行首点击可以设置和取消“断点”。
在VBE环境里,设置好的“断点”行是以“酱色”亮红显示,如图8.25所示。