《第九章__模块与VBA编程基础.ppt》由会员分享,可在线阅读,更多相关《第九章__模块与VBA编程基础.ppt(66页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第九章模块与VBA编程基础概述本章要涉及到编程。了解编程基础知识,掌握程序的三种结构在VBA中的实现,能够读懂程序并写(填)出程序片段1.模块基本概念2.创建模块3.VBA设计基础4.VBA流程控制5.过程调用和参数传递6.程序错误处理和调试9.1模块基本概念模块就是一些程序的集合,完成特定的功能。模块分类:1.类模块(与Access内置对象关联,如窗体、报表)2.标准模块9.2 创建模块模块以过程为单元组成,一个模块包含一个声明区域和若干个过程Sub、函数Function。过程创建一般格式public|privatestatic 过程名(形参表)语句Exit subEnd sub调用过程Ca
2、ll 过程名(参数表)Function函数public|privatestatic 函数名(形参表)语句End Function例题9.1编写一个求圆面积的函数Area()对于该例题中出现的语句只要大体了解即可。9.1【添加过程】对话框【例9.1】编写一个计算圆面积的函数过程Area()。Public Function Area(r as Single)as SingleIf r=0 ThenMsgBox 圆的半径必须大于零,vbCritical,警告Area=0 半径为零,设置函数返回值为0Exit Function 结束函数过程运行End IfArea=3.14*r*rEnd Functi
3、on函数过程的调用形式:函数过程名()函数过程不能使用CALL来调用执行,需要直接引用函数名并加括号来辨别,可以在查询、宏等中调用使用,函数过程的返回值可以直接赋给某个变量。例如,假如在某个窗体中要计算半径为8的圆面积,并用变量S保存圆面积值,可调用上面创建的Area()函数过程,调用命令格式为:s=Area(8)。9.3 VBA编程基础VBA是一种计算机语言。对象在Access中指表、查询、窗体、报表、页、宏、模块、DoCmd等认识VBE窗口例题9.2新建窗体,放置一个按钮,该按钮的单击事件响应某过程。对象组合框事件组合框属性窗口工程窗口代码窗口立即窗口标准工具栏代码编辑区VBA语句书写原则
4、一行一句,如果特别长可以用_(下划线)隔开如果节省空间,可以用:(冒号)将多条语句写在同行VBE可以自动识别语法错误,有颜色提示。注释,给程序员看,对机器无用(单引号后面就是注释内容)rem后面是注释内容数据类型Access中提供了若干数据类型,如下:1.整数Integer2.长整数Long3.单精度数Single4.双精度数Double5.货币Currency6.字符串String7.布尔型Boolean8.日期型Date9.变体类型Variant10.用户自定义类型数据库对象DatebaseConnectionFormReportControlQueryDefTableDefCommand
5、RecorderSet常量、变量、数组常量:不能改变的量。1.直接常量2.符号常量Const定义的常量3.内部常量,Access定义的常量4.系统常量,True、False、Null、Yes、No、On、Off变量变量,可以改变的量。变量命名包含字母、数字、下划线、汉字,且不以数字、下划线开头,不区分大小写,不能与系统关键字冲突。声明变量:在VBA中可以隐式声明显式声明,Dim变量作用域局部变量、模块变量、全局变量数据库对象变量的引用方法窗体名称!控件名称.属性名称注意叹号和点号的使用Function SafeSqr(num)Val_Temp=Abs(num)SafeSqr=Sqr(Val_T
6、em)End Function例如:intX1%=1243 定义intX1为一个整型变量DouX2#=45665.456 定义douX2为一个双精度变量StrX3$=Access 定义strX3为一个字符串变量声明变量的一般方法是用Dim.AsDataType结构,其中As指定变量数据类型。Dim语句使用格式为:Dim 变量名As 数据类型如果不使用“数据类型”可选项,默认定义的变量为Variant数据类型。可以使用Dim语句在一行中声明多个变量。例如:Dim strX As String 定义了1个字符型变量strXDim intX As Integer,strZ As String 定义了
7、1个整型变量intX和1个字符型变量strZDim x 定义了1个变体(Variant)类型变量xDim I,j,k As integer 只有k是integer型,I与j都是Variant型表9.4 3种变量的使用规则与作用域作用范围局部变量模块变量全局变量声明方式Dim、StaticDim、PrivatePublic声明位置在子过程中在窗体/模块的声明区域在标准模块的声明区域能否被本模块的其他过程存取不能能能能否被其他模块的过程存取不能不能能Access建立的数据库对象及其属性,均可被看成是VBA程序代码中的变量及其指定的值来加以引用,与普通变量不同的是要使用规定的引用格式。例如,窗体和报
8、表对象的引用格式为:Forms(或Reports)窗体(或报表)名称!控件名称.属性名称关键字Forms或Reports分别指示窗体或报表对象类;感叹号(!)为分隔符,用于分隔开父子对象;“属性名称”为可选项,若省略,则默认为控件的基本属性Value。注意:如果对象名称中含有空格或标点符号,引用时要用方括号把对象名称括起来。例如,要在代码中引用窗体(Myform1)中名为Txtxh的文本框控件,可使用以下语句:Forms!Myform1!Txtxh=3020503323“若在本窗体的模块中引用,可以使用Me代替Forms!Myform1。语句变为:Me!Txtxh=3020503323“For
9、ms!Myform1!Txtxh”在程序语句中的作用相当于变量,但它指示的是某个Access对象。当需要多次引用对象时,可以先声明一个Control(控件)数据类型的对象变量,然后使用Set关键字建立对象变量指向的控件对象。语句使用格式如下:Dim Txtxhbl As Control 定义对象变量,数据类型为Control(控件)数据类型Set Txtxhbl=Forms!Myform1!Txtxh 为对象变量指定窗体控件对象以后要引用控件对象,可转为引用对象变量。例如:Txtxhbl=3020503323等同于:Forms!Myform1!Txtxh=3020503323借助将变量定义为对
10、象变量类型并使用Set语句为对象变量指定对象的方法,可以定义表9.3中所列任何对象数据类型的对象变量,并将数据库对象指定为对象变量名。数组数组是相同类型变量的集合定义数组Dim 数组名(下界 to 上界)AS 类型默认下界为0零数组引用通过数组明(下标)方法引用二维数组Dim 数组名(a to b,m to n)AS 类型列举一些关于数组定义、引用的例子单独考数组很少,一般与循环部分结合!数组变量由变量名和数组下标组成,在VBA中不允许隐式说明数组,可用Dim语句来声明数组。数组声明方式为:Dim 数组名(下标下界to 下标上界)As 数据类型下标下界的缺省值为0,数组元素为:数组名(0)至数
11、组名(下标上界);如果设置下标下界非0,要使用to选项。在使用数组时,可以在模块的通用声明部分使用Option Base来指定数组的默认下标下界是0或l:Option Base 1 设置数组的默认下标下界为lOption Base 0 语句的默认形式数组有两种类型:固定大小的数组和动态数组。前者总保持同样的大小,而后者在程序中可根据需要动态地改变数组的大小。(1)固定大小的数组例如:Dim IntArray(l0)As Integer这条语句声明了一个有11个整型数组元素的数组,数组元素从IntArray(0)至IntArray(l0),每个数组元素为一个整型变量,这里指定数组元素下标上界来定
12、义数组。VBA中允许指定数组下标范围时使用To,如下例所示:Dim IntArray(-2 to 3)As Integer该语句定义一个有6个整型数组元素的数组,数组元素下标从-2到3。如果要定义多维数组,声明方式为:Dim 数组名(数组第1维下标上界,数组第2维下标上界)As 数据类型例如:Dim IntArray(3,5)As Integer语句定义了一个二维数组,第一维有4个元素,第二维有6个元素。类似的声明也可以用在二维以上的数组中。例如:Dim MultArray(3,1 to 5,0 to 5)As Long语句定义了一个三维数组,第一维有4个元素,第二维有5个元素,第三维有6个元
13、素,其中数组元素的总数为三个维数的乘积:456=120。(2)动态数组在VBA中,还允许用户定义动态数组。很多情况下,不能明确知道数组中应该有多少元素,可使用动态数组。动态数组中元素的个数是不定的,在程序运行中可以改变其大小。动态数组的定义方法是:先使用Dim来声明数组,但不指定数组元素的个数,而在以后使用时再用ReDim来指定数组元素个数,称为数组重定义。在对数组重定义时,可以使用ReDim后加保留字Preserve来保留以前的值,否则使用ReDim后,数组元素的值会被重新初始化为默认值。【例9.4】定义动态数组IntArray,设默认下界为1,并用循环赋值。Dim IntArray()As
14、 Integer 声明动态数组ReDim IntArray(5)数组重定义,分配5个元素For I=1 To 5 使用循环给数组元素赋值IntArray(I)=INext IRem数组重定义,调整数组的大小,并抹去其中元素的值。ReDim IntArray(10)重新设置为10个元素,IntArray(1)至IntArray(5)的值不保留For I=11 To 20 使用循环给数组元素重新赋值IntArray(I)=INext IRem数组重定义,调整数组的大小,使用保留字Preserve来保留以前的值。ReDim Preserve IntArray(15)重新设置为15个元素,IntArr
15、ay(1)至IntArray(10)的值保留For I=11 To 15 使用循环给未赋值数组元素赋值IntArray(I)=INext IRedim语句只能出现在过程中,可以改变数组的大小和上下界,但不能改变数组的维数。执行不带Preserve关键字的Redim语句时,数组中存储的数据会全部丢失。VBA将重新设置其中元素的值。对于Variant变量类型的数组,设为Empty;对于Numeric类型的数组,设为0;对于String类型的数组则设为空字符串;对象数组则设为Nothing。使用Preserve关键字,可以改变数组中最后一维的边界,但不能改变这一维中的数据。例如:Redim IntA
16、rray(10,10,10)Redim Preserve IntArray(10,10,15)也就是说,在使用Preserve关键字时,只能通过改变数组的上界来重新设置数组的大小,改变数组的下界将会导致一个错误。如果改变后的数组比原来小,那么多出来的数据将会丢失。(3)数组的使用数组声明后,数组中的每个元素都可以当作单个的变量来使用,其使用方法同相同类型的普通变量。数组元素的引用格式为:数组名(下标值)。其中:如果该数组为一维数组,则下标值为一个范围为数组下标下界,数组下标上界的整数;如果该数组为多维数组,则下标值为多个(不大于数组维数)用逗号分开的整数序列,每个整数(范围为数组该维下标下界,
17、数组该维下标上界)表示对应的下标值。例如,可以如下引用前面定义的数组,设默认下界为1。IntArray(2)引用一维数组IntArray的第2个元素。IntArray(2,2)引用二维数组IntArray的第2行第2个元素。【例9.5】若要存储一年中每天的支出,可以声明一个具有365个元素的数组变量,而不是365个变量,数组中的每一个元素都包含一个值。下列的语句声明数组CurArray具有365个元素,设默认下界为1。Dim CurArray(1 to 365)As Currency 声明一个具有365个元素的一维数组Dim intI As IntegerFor intI=1 to 365 C
18、urArray(intI)=10 每个数组元素都赋予一个初始值10Next运算符、表达式运算符1.算术运算符+-*/mod 2.字符串运算符+&,推荐使用&3.关系运算符=like is between.and4.逻辑运算符and or not5.对象运算符!.【例9.6】算术运算符应用示例。28 计算2的8次方2(1/2)或20.5 计算2的平方根 7/2 标准除法,结果为3.572 整数除法,结果为3 10 Mod 4 取模运算,结果为210 Mod 2 结果为010 Mod-4 结果为2-10 Mod-4 结果为-2-8.8 Mod 5 结果为-4 20 True 结果为21,逻辑量Tr
19、ue转化为数值-1 20+False+6 结果为26,逻辑量False转化为数值0【例9.7】“&”运算符应用示例。Strx=ABCStrx&是大写英文字母 出错Strx&是大写英文字母 结果为“ABC是大写英文字母”Access&数据库教程 结果为“Access数据库教程”abcd&1234 结果为“abcd1234”abcd&1234 结果为“abcd1234”4321&1234 结果为“43211234”4321&1234 结果为“43211234”2+3&=&(2+3)结果为“2+3=5”【例9.8】“+”运算符应用示例。4321+1234 结果为55554321+1234 结果为“4
20、3211234”abcd+1234 出错4321+1234&100 结果为“5555100”【例9.9】Is关系运算符应用示例。Dim s1,s2 As ControlSet s1=Me!text1Set s2=Me!text1strx=s1 Is s2 strx值为“True”【例9.10】关系运算符应用示例。Dim S 定义变量SS=(52)结果为TrueS=(2=5)结果为FalseS=(abcdabc)结果为TrueS=(王力刘力)结果为TrueS=(#2005/10/10#2004/10/12#)结果为True【例9.11】逻辑运算符应用示例。Dim S 定义变量SS=(52 And
21、 3=4)结果为FalseS=(52 Or 3=4)结果为TrueS=(abcdabc And 3=4)结果为FalseS=Not(3=4)结果为TrueS=(52 Xor 3=4)结果为TrueS=(52 Xor 4=3)结果为FalseS=(25 Eqv 3=4)结果为TrueS=(52 Eqv 3=4)结果为FalseS=(52 Imp 3=4)结果为FalseS=(52 Imp 4=3)结果为True表达式表达式就是由常量、变量、运算符构成的字符串,表达式具有特定的唯一值。表达式运算优先级参看表9.9 P222(1)表达式的组成表达式由字面值、常量、变量、运算符、函数、标识符、逻辑量和
22、括号等按一定的规则组成,表达式通过运算得出结果,运算结果的类型由操作数的数据和运算符共同决定。注意:在VBA中,逻辑量在表达式中进行算术运算时,True值被当成-1、False值被当成0处理。(2)表达式的书写规则只能使用圆括号且必须成对出现,可以使用多个圆括号,但必须配对。乘号不能省略。X乘以Y应写成X*Y,不能写成XY。表达式从左至右书写,无大小写区分。(3)算术运算表达式的结果类型在算术运算表达式中,参与运算的操作数可能具有不同的数据精度,VBA规定运算结果的数据类型采用精度高的数据类型。(4)运算优先级如果一个表达式中含有多种不同类型的运算符,运算进行的先后顺序由运算符的优先级决定。V
23、BA常用运算符的优先级划分如9.9所示。表9.9 运算符的优先级高优先级 高 低低算术运算符字符串运算符关系运算符逻辑运算符指数运算()&+=Not负数(-)And乘法和除法(*、/)Or整数除法()取模运算(Mod)加法和减法(+、-)关于运算符的优先级作如下说明:不同类型运算符的优先级为:算术运算符字符串运算符关系运算符逻辑运算符圆括号优先级最高。所有关系运算符的优先级相同。也就是说,按从左到右顺序处理。算术运算符和逻辑运算符必须按照表9.9所列优先顺序处理。函数1.数学函数绝对值函数 abs(数值表达式)向下取整 Int(数值表达式)取整Fix(数值表达式)四舍五入Round(数值表达式
24、)自然指数Exp(数值表达式)自然对数Log(数值表达式)开平方Sqr(数值表达式)正弦函数Sin(数值表达式)余弦函数Cos(数值表达式)正切函数Tan(数值表达式)随机函数Rnd(数值表达式)函数字符串函数字符串检索InStr(起始位置,串1,串2,Compare)在串1中寻找串2的起始位置。-串长函数len(字符串),返回串长,汉字算一个-字符串截取left(str,n)Right(str,n)mid(str,start,n)字符串函数生成空格space(n),产生n个空格大小写转换Ucase(str)转换成大写Lcase(str)转换成小写删除空格Ltrim(str)消除前面空格Rtr
25、im(str)消除后面空格Trim(str)消除前后空格注意:没有直接消除中间空格函数日期、时间函数Date()Time()Now()Year(日期)month(日期)Day(日期)Hour()minute()second()DateAdd(间隔类型,间隔值,基准日期时间)DateDiff(间隔类型,日期1,日期2)类型转换字符转成ASCII码ASC(字符串),只转换第一个ASCII转成字符 Chr(代码)数字转字符 Str(数值表达式)字符转数字Val(字符串)流程控制语句声明语句:命名或定义变量、常量、函数等赋值语句:将表达式值赋给变量变量名=表达式Goto语句 不推荐使用9.4.1 声明
26、语句声明语句通过声明语句可以命名和定义过程、变量、数组或常量。当声明一个过程、变量或数组时,也同时定义了它们的作用范围,此范围取决于声明位置(子过程、模块或全局)和使用什么关键字(Dim、Public、Static或Global等)来声明它。例如,有如下程序段:Sub Myproc()Dim SinS as Single,SinR as SingleConst P=3.14159End Sub上述语句声明定义了一个名为Myproc的子过程,Dim语句定义了2个名称分别为SinS和SinR的单精度数据变量,Const语句定义了1个名为P的符号常量。当这个子过程被调用或运行时,所有包含在Sub和E
27、nd Sub之间的语句都会被执行。9.4.2 赋值语句赋值语句赋值语句用于指定一个值或表达式给变量或常量。使用格式为:Let 变量名=值或表达式其中:Let为可选项,在使用赋值语句时,一般省略。例如:Dim SinS as Single,SinR as SingleSinS=1234.567Let SinR=12.3关于使用赋值语句的说明:(1)当数值表达式与变量精度不同时,系统强制转换成变量的精度。例如:Dim IntN as IntegerIntN=10.6 IntN为整型变量,10.6经四舍五入转换后赋值,IntN值为11(2)当表达式是数字字符串,变量为数值型,系统自动转换成数值类型再
28、赋值,若表达式含有非数字字符或空串时,赋值出错。例如:IntN%=123 IntN值为123IntN%=1a2 3 出错,类型不匹配(3)不能在一个赋值语句中,同时给多个变量赋值。例如:以下语句语法没有错误,但结果不正确。x%=y%=z%=10(4)实现累加作用的赋值语句。例如:n=n+1 取变量n中的值加1后再赋给n,与循环语句结合,可实现计数说明:还有一个赋值语句是Set语句,它用来指定一个对象给已声明为对象类型的变量,Set关键字不能省略。9.4.3 标号和标号和GoTo语句语句GoTo语句用于在程序执行过程中实现无条件转移。格式为:GoTo标号程序执行过程中,遇到GoTo语句,会无条件
29、地转到其后的“标号”位置,并从该位置继续执行程序。标号定义时,名字必须从代码行的第一列开始书写,名字后加冒号“:”。例如:Goto Label1 跳转到标号为“Label1”的位置执行Label1:定义的“Label1”标号位置说明:GoTo语句在早期的Basic语言中曾广泛应用。在VBA中,程序的执行流程可用结构化语句控制,除在错误处理的“On Error GoTo.”结构中使用外,应避免使用GoTo语句。9.4.4 执行语句执行语句顺序结构每条语句执行且执行一次。选择(分支)结构根据条件真假,有些语句可能不执行,但执行部分只运行一次。循环结构根据条件真假,有些语句可能执行多次,但也有可能一
30、次也不执行!分支结构单分支、双分支、多分支单分支if 条件 then 语句块双分支if 条件 then 语句块1else 语句块2end if多分支,即单双分支的嵌套注意:else总与最近的if配对使用!当嵌套层次太多时,可以考虑使用case语句(1)单分支结构语句格式为:If Then 或 If Then End If功能:当条件表达式为真时,执行Then后面的语句块或语句,否则不做任何操作。说明:语句块可以是一条或多条语句。在使用上边的单行简单格式时,Then后只能是一条语句,或者是多条语句用冒号分隔,但必须与If语句在一行上。例如:比较两个数值变量x和y的值,用x保存大的值,y保存小的值
31、。语句如下:If xy Thent=x t为中间变量,用于实现x与y值的交换x=y y=tEnd If或If xy Then t=x:x=y:y=t(2)双分支结构语句格式为:If Then Else 或If Then ElseEnd If功能:当条件表达式为真时,执行Then后面的语句1或语句块1,否则执行Else后面的语句2或语句块2。【例9.12】编写计算如下函数的程序语句。If x=0 Theny=Sqr(x)Elsey=Abs(x)End If或If x=0 Then y=Sqr(x)Else y=Abs(x)本例亦可用单分支结构语句实现,读者可写出程序语句。双分支结构语句只能根据条
32、件表达式的真或假来处理两个分支中的一个。当有多种条件时,要使用多分支结构语句。(3)多分支结构语句格式为:If Then ElseIf ThenElseEnd If功能:依次测试条件表达式1、条件表达式2、,当遇到条件表达式为真时,则执行该条件下的语句块。如均不为真,若有Else选项,则执行Else后的语句块,否则执行End If后面的语句。说明:不管条件分支有几个,程序执行了一个分支后,其余分支不再执行。当有多个条件表达式同时为真时,只执行第一个与之匹配的语句块。因此,应注意多分支结构中条件表达式的次序及相交性。另外注意ElseIf中不能有空格。【例9.13】用窗体实现如下操作:当输入某同学
33、期末考试科目的总平均成绩时,显示该生对应的五级制总评结果。在窗体中添加以下控件:创建2个标签控件,其标题分别设为:总平均成绩和总评结果。创建2个文本框控件,其名字分别设为:Zpcj和Zpjg。创建1个命令按钮,其标题为“评定”,在其Click事件过程中,加入如下代码语句:Private Sub command1_Click()If Me!Zpcj=90 ThenMe!Zpjg=优秀ElseIf Me!Zpcj=80 ThenMe!Zpjg=良好ElseIf Me!Zpcj=70 ThenMe!Zpjg=中等ElseIf Me!Zpcj=60 ThenMe!Zpjg=及格ElseMe!Zpjg=
34、不及格End IfEnd Sub运行结果:当在总平均成绩文本框中输入任何数值数据时,单击【评定】按钮,总评结果将显示在总评结果框中。(4)If语句的嵌套使用:指If或Else后面的语句块中又包含有If语句。语句格式为:If ThenIf Then End IfEnd If【例9.14】比较3个数值变量x、y和z的值,通过交换,使得xyz。程序语句如下:If xy Thent=x:x=y:y=t 如果xyIf yz Then t=y:y=z:z=t 如果yzIf xy Then t=x:x=y:y=t 此时的x,y值已不是原先的值End IfEnd IfEnd If注意:嵌套If语句应注意书写格
35、式,为提高程序的可读性,多采用锯齿型。注意If与End If的配对。多个If嵌套,End If与它最近的If配对。2.多分支Select Case语句Select Case语句格式为:Select Case 变量或表达式Case 表达式1Case 表达式2Case ElseEnd Select功能:Select语句首先计算Select Case后的值,然后依次计算每个Case子句中表达式的值,如果的值满足某个Case值,则执行相应的语句块,如果当前Case值不满足,则进行下一个Case语句的判断。当所有Case语句都不满足时,执行Case Else子句。如果条件表达式满足多个Case语句,则只
36、有第一个Case语句被执行。说明:“变量或表达式”可以是数值型或字符串表达式。Case表达式与“变量或表达式”的类型必须相同。Case表达式可以是下列几种格式:单一数值或一行并列的数值,之间用逗号分开。用关键字To分隔开的两个数值或表达式之间的范围,前一个值必须比后一个值要小。字符串的比较是从它们的第一个字符的ASCII码值开始比较的,直到分出大小为止。用Is关系运算符表达式。例如:Case 1 to 20Case is20Case 1 To 5,7,8,10,is20Case A To Z【例9.15】例9.13中判定学生总评成绩的代码可改写如下:Select Case Val(me!Zpc
37、j)Case is=90me!Zpjg=优秀Case 80,81,82 to 89me!Zpjg=良好Case 70 to 79me!Zpjg=中等Case 60 to 69me!Zpjg=及格Case Elseme!Zpjg=不及格End Select又例如:Dim strx as string*1Select Case strxCase A to Z,a to zstry=英文字母Case!,?,.,;stry=标点符号Case Is68stry=字符的ASCII码值小于68Case Elsestry=其他字符End Select 3.循环语句(1)Do WhileLoop循环语句语法格式
38、为:Do While 条件表达式 Exit Do Loop 功能:Do While循环语句:当条件表达式结果为真时,执行循环体,直到条件表达式结果为假或执行到Exit Do语句而退出循环体。(2)Do UntilLoop循环语句语法格式为:Do Until 条件表达式 Exit Do Loop Do Until循环语句:当条件表达式结果为假时,执行循环体,直到条件表达式结果为真或执行到Exit Do语句而退出循环体。(3)DoLoop While循环语句语法格式为:Do Exit Do Loop While 条件表达式 说明:关键字While用于指明当条件为真(True)时,执行循环体中的语句
39、。(4)DoLoop Until循环语句语法格式为:Do Exit Do Loop Until 条件表达式说明:关键字Until用于指明当条件为真(True)前执行循环体中的语句。对于(1)和(2)循环语句先判断后执行,循环体有可能一次也不执行;而对于(3)和(4)循环语句为先执行后判断,循环体至少执行一次。在DoLoop循环体中,可以在任何位置放置任意个数的Exit Do语句,随时跳出DoLoop循环。如果Exit Do使用在嵌套的DoLoop语句中,则Exit Do会将控制权转移到Exit Do所在位置的外层循环。当省略While或Until条件子句时,循环体结构变成如下格式:Do Exi
40、t Do Loop循环结构仅由Do.Loop关键字组成,表示无条件循环,若在循环体中不加Exit Do语句,循环结构为“死循环”。【例9.16】把26个小写英文字母赋给数组strx。Dim strx(1 to 26)As StringI=1Do While I=26strx(I)=Chr(I+96)I=I+1Loop5)ForNext循环语句主要用于循环次数已知的循环操作。语句格式为:For 循环变量=初值 To 终值 step 步长值Exit For Next 循环变量功能:循环变量先被赋初值。判断循环变量是否在终值内,如果是,执行循环体,然后循环变量加步长值继续;如果否,结束循环,执行Ne
41、xt后的语句。说明:循环变量必须为数值型。step步长值:可选参数。如果没有指定,则step的步长值默认为1。注意:步长值可以是任意的正数或负数。一般为正数,初值应小于等于终值;若为负数,初值应大于等于终值;步长值不能为0,否则造成“死循环”。【例9.17】把26个大写英文字母赋给数组strx。Dim strx(1 to 26)As StringI=1For I=1 To 26 strx(I)=Chr(I+64)Next I说明:循环体结束后,循环变量的值为循环终值+步长值,上例循环结束后I值为27。【例9.18】分析下列程序的循环结构:For K=5 To 10 Step 2K=K*2Nex
42、t K按照公式计算,循环次数为:(10-5+1)/2=3次,但这是错误的。实际上,该循环的循环次数为只有1次(循环变量先后取值5和12,循环执行1次之后,循环变量值为12,超过终值10,循环结束)。【例9.19】在立即窗口中显示有(*)组成的5*5的正方形。Sub Procedure5()输出5*5的正方形 Const MAX=5 定义常量 Dim Str As String Str=For n=1 to Max Str=Str+*Next nFor n=1 to Max Debug.print Str Next nEnd Sub(6)WhileWend循环语句WhileWend循环与Do W
43、hileLoop结构类似,但不能在WhileWend循环中使用Exit Do语句。WhileWend循环语句格式为:While条件表达式Wend9.5过程调用函数调用函数名称(参数表)例题9.20计算圆面积,使用函数调用方法过程调用Call 过程名称(参数表)参数传递ByVal传值方式,单向ByRef传址方式,双向举例子说明!【例9.20】在窗体对象中,使用函数过程实现任意半径的圆面积计算,当输入圆半径值时,计算并显示圆面积。在窗体中添加以下控件:创建两个标签控件,其标题分别设为:半径和圆面积。创建两个文本框控件,其名字分别设为:SinR和SinS创建一个命令按钮,其标题设为“计算”,在其Cl
44、ick事件过程中,加入如下代码语句:Private Sub command1_Click()me!SinS=Area(me!SinR)End Sub在窗体模块中,建立求解圆面积的函数过程Area()。代码如下:Public Function Area(R As Single)As SingleIF RVal(me!Siny)ThenMsgbox x值大于y值,不需要排序,vbinformation,提示Me!Sinx.SetFocusElsea=Me!Sinxb=Me!SinySwap a,bMe!Sinx=aMe!Siny=bMe!Sinx.SetFocusEnd IfEnd Sub在窗体模
45、块中,建立完成排序功能的子过程Swap。代码如下:Public Sub Swap(x,y)Dim tt=xx=yy=tEnd Sub运行窗体,可实现输入数据的排序。在上面的例子中,Swap(x,y)子过程定义了两个形参x和y,主要任务是:从主调程序获得初值,又将结果返回给主调程序,而子过程名Swap是无值的。9.5.2 参数传递参数传递在VBA中,实参向形参的数据传递有两种方式,即传值(ByVal选项)和传址(ByRef选项),传址调用是系统默认方式。区分两种方式的标志是:要使用传值的形参,在定义时前面加有“ByVal”关键字,有“ByVal”关键字,为传值方式,否则为传址方式。(1)传值调用
46、的处理方式是:当调用一个过程时,系统将相应位置实参的值复制给对应的形参,在被调过程处理中,实参和形参没有关系。被调过程的操作处理是在形参的存储单元中进行,形参由于操作处理引起的任何变化均不反馈、影响实参的值。当过程调用结束时,形参所占用的内存单元被释放,因此,传值调用方式具有单向性。(2)传址调用的处理方式是:当调用一个过程时,系统将相应位置实参的地址传递给对应的形参。因此,在被调过程处理中,对形参的任何操作处理都变成了对相应实参的操作,实参的值将会随被调过程对形参的改变而改变,传址调用方式具有双向性。【例9.22】创建有参子过程Test(),通过主调过程Main_click()被调用,观察实
47、参值的变化。被调子过程Test():Public Sub Test(ByRef x As Integer)形参x说明为传址形式的整型量x=x+10 改变形参x的值End Sub主调过程Main_click():Private Sub Main_click()Dim n As Integer 定义整型变量nn=6 变量n赋初值6Call Test(n)MsgBox n 显示n值End Sub当主调过程Main_click()调用子过程Test()后,“MsgBox n”语句显示n的值已经发生了变化,其值变为16,说明通过传址调用改变了实参n的值。如果将主调过程Main_click()中的调用语句“Call Test(n)”换成“Call Test(n+1)”,再运行主调过程Main_click(),结果会显示n的值依旧是6。表明常量或表达式在参数的传址调用过程中,双向作用无效,不能改变实参的值。在上例中,需要操作实参的值,使用的是系统默认的传址调用方式,若使用传值调用方式,请读者分析处理结果的变化。9.6程序运行错误处理与调试该节内容可以融入到其他章节中,编写例子的时候进行调试、运行。注意语法错误和逻辑错误的调试调试的方法等图9.11 设置断点图9.12【调试】工具栏运行中断重新设置切换断点逐语句逐过程 跳出 立即窗口本地窗口监视窗口快速监视
限制150内