第9章 VBA与模块
9.1 VBA基础
宏的功能很强大而且易于掌握,如果要对数据库对象进行更复杂、更灵活的控制,就需要编程来实现。模块对象可以解决此类问题,它是一种重要的Access数据库对象,以VBA(Visual Basic for Application)语言为基础编写的,是功能更强大的程序代码集合。利用模块可以将数据库中的各种对象联结起来,从而使其构成一个完整的系统。
VBA是一种应用程序开发工具,是基于VB(Visual Basic)发展而来的。微软将VB引入Office软件中用于开发应用程序,这种集成在Office中的VB被称为VBA(Visual Basic for Application)。
使用VBA编写的程序保存在Access数据库文件中,无法脱离Access应用程序环境而独立运行。
9.1.1 VBA的编程环境
VBA开发环境又称为VBE(Visual Basic Editor),在VBE中可以编写VBA函数、过程和VBA模块。VBE的打开方法同标准模块的创建方法,也可以使用Alt+F11快捷方式打开编辑环境。
VBE窗口通常由一些常用工具和多个窗口组成,如图9-1所示。
图9-1 VBE窗口
VBE编辑器主要由代码窗口、立即窗口、监视窗口、本地窗口、属性窗口、对象浏览器以及工程资源管理器等组成。
1.代码窗口
用来编写、显示和修改VBA代码。
2.工程资源管理器窗口
列出了所有的模块以及类对象。
3.属性窗口
属性窗口列出了所选对象的各个属性。
4.立即窗口
当单步执行程序时,使用该窗口可以直接输入语句或命令并查看执行结果。
5.监视窗口
用于显示当前工程中定义的监视表达式的值。
6.本地窗口
用于显示所有在当前过程在执行过程中的变量声明和变量值。
7.对象浏览器
用于显示对象模型中以及工程过程中的可用类、属性、方法、事件及常数变量。
9.1.2 VBA的语法
任何程序语言编写的代码都是由语句组成的,而语句又是由数据、表达式、函数等基本语法单位构成的。下面我们来介绍一下VBA的标准数据类型、常量、变量、运算符、表达式等内容。
VBA语句由保留字及语句体组成,而语句体由命令短语和表达式组成。
保留字和命令短语中的关键字是系统规定的专用符号,通常由英文单词或其缩写表示,必须严格按照系统要求来写。
通常每条语句占一行,一行最多允许有255个字符;如果一行书写多个语句,语句之间用冒号“:”隔开;如果某个语句在一行内没有写完,可用下划线“_”作为连接符。
1.数据类型
与其他的编程语言一样,VBA为数据操作提供了数据类型,称为基本数据类型。表9-1列出了VBA程序中的基本数据类型,以及它们所占用的存储空间、取值范围等。
表9-1 VBA的基本数据类型
2.常量
常量是指在程序可以直接引用的量,其值在程序运行期间保持不变。常量有文字常量、符号常量和系统常量3种表示形式。
文字常量也称直接常量,实际就是常数,直接出现在代码中。例如#2014-5-1#是日期型常量,5000是数值型常量,如此等等。
符号常量是用标识符来表示常量的名称,使用关键字Const来声明。例如,ConstPI= 3.14159。符号常量一般要求大写,以便与变量区分。
系统常量是Visual Basic系统预先定义的常量,用户可以直接引用。例如,vbBlack是color常数,表示黑色;True是逻辑型常量,表示真;vbOKOnly是MsgBox常数,如此等等。
3.变量
变量是在程序运行期间其值可以改变的量,是内存单元中用于存储数值的临时存储单元,可以存放各种类型的数据。
每个变量都有一个名字,需要通过变量名来引用变量。一般来说,变量的命名要有一定的意义,必须以字母开头,不能含有空格、运算符以及@、$等特殊字符,也不能使用系统保留字作为变量名。
一般来说,在程序中使用变量时需要先声明,声明变量可以起到两个作用:一是指定变量的名称和数据类型;二是指定变量的取值范围。
在变量使用之前进行声明,称为显式声明。也可以不声明直接使用变量,系统将默认该变量是变体数据类型,这种声明方式称为隐式声明。
也可以在程序开始处直接输入语句“Option Explicit”进行强制声明。变量声明语句的语法格式为:
Dim 变量名 [As 类型名|类型符] [,变量名[As 类型名|类型符]]
该语句的功能是,定义指定的变量并为其分配内存空间。“As 类型名”用于指定变量的类型。如省略,则默认变量为Variant类型。
例如,
Dim x As Single '声明了一个单精度型变量x。
Dim name $, address $ '声明了两个字符串变量name,address,$是字符型数据的类型符。Dim m As Currency '声明了一个货币型变量m。
变量都有一定的作用范围,即作用域。按照变量的作用域可以将变量分为局部变量、模块级变量、全局变量。
在过程内部声明的变量称为局部变量,仅仅在过程范围内有效。
在模块的起始位置、所有过程之外声明的变量,称为模块级变量,在该模块中有效。
在标准模块起始位置、所有过程之外,用Public关键字声明的变量称为全局变量,在所有类模块和标准模块的所有过程中都是可见的。
4.表达式
表达式是指用运算符将常量、变量和函数连接起来的式子。表达式的构成必须符合VBA的语法规则。
5.运算符
VBA提供许多运算符来完成各种计算和处理。根据运算的不同,可以分为算术运算符、连接运算符、关系运算符和逻辑运算符。
算术运算符用于数值的算术运算,共有7个,如表9-2所示。
表9-2 算术运算符
连接运算符用于连接两个字符串,有&和+这两种运算符。使用&运算符,会将数值型数据先转换成字符串类型后再进行连接。使用+,当字符串类型数据是数字字符串时,则直接进行加法运算。
关系运算符也称为比较运算符,其结果为布尔型数据True或者False。关系运算符有6个,分别是<,<=,>,>=,<>,=。
逻辑运算符也称为布尔运算符,运行结果为布尔型数据True或者False。按照优先级,逻辑运算符依次为Not,And,Or。
6.内部函数
内部函数也称标准函数,是VBA为用户提供的标准过程。使用这些函数,可以使某些特定的操作更加简便。
根据标准函数的功能,可以将标准函数分为数学函数、字符串函数、转换函数、日期函数、测值函数、颜色函数等。
数学函数用于数学计算,表9-3列出了常用的数学函数。
表9-3 数学函数
说明:表中的自变量x可以为常量、变量和数值表达式,但必须写在圆括号中。
字符串函数是指自变量或函数值为字符串的函数。表9-4列出了常用的字符串函数。
表9-4 字符串函数
说明:表中的n和s分别表示数值表达式和字符表达式,函数名和参数后可带后缀“$”,表明函数值为字符串。
日期函数对日期型数据进行运算,表9-5列出了常用的日期函数。
表9-5 日期函数
9.2 VBA的程序控制
VBA与其他程序设计语言一样,也具有结构化程序设计的3种结构:顺序结构、选择结构和循环结构。
9.2.1 顺序结构
在顺序结构中,通常使用赋值语句、输入语句、输出语句、注释语句等。
1.赋值语句
变量声明以后,需要为变量赋值,为变量赋值应使用赋值语句。
赋值语句的语法格式为:
变量名=表达式
该语句的功能是,首先计算表达式的值,然后将该值赋给赋值号“=”左边的变量。
已经赋值的变量可以在程序中使用,还可以改变变量的值。
2.输入语句
可以利用InputBox函数进行数据的输入。
3.输出语句
可以利用MsgBox语句进行信息输出,它没有返回值,通常使用该语句显示一条提示信息。
4.注释语句
注释语句用于对程序或语句的功能给出解释和说明。
注释语句的语法格式为:
格式1:
Rem 注释内容
格式2
'注释内容
【例9-1】在“教学管理”数据库中,创建一个模块,在其中创建一个welcome过程,可以根据输入的人名,弹出消息框表示欢迎。
操作步骤如下:
(1)打开“教学管理”数据库,选择“创建”选项卡中的“宏与代码”组,单击“模块”按钮,打开VBE窗口。
(2)在模块1的代码窗口(见图9-2)中,输入如表9-5所示的代码。
图9-2 welcome过程
(3)单击运行按钮,或者按F5功能键,查看运行效果。
9.2.2 选择结构
选择结构也称为分支结构,对给定的条件进行分析、比较和判断,并根据判断结果决定程序的走向。选择结构语句有If条件语句和Select Case语句两种。
1.If语句
1)单分支If语句
单分支If语句的语句格式如下:
格式1:
If <表达式> Then <语句>
格式2:
If <表达式> Then
<语句序列>
End If
功能:先计算表达式的值,当表达式的值为真(True)时,执行<语句序列>中的语句,然后执行if语句的下一条语句,如果表达式的值为假(False),直接执行if语句的下一条语句。
【例9-2】北京市内快递的收费标准是3公斤内收费10元,超出部分5元/公斤。编写程序根据货物的重量计算快递费用。
分析:根据题意,计算规则为:如果重量不大于3公斤,费用为10元;如果重量大于3公斤,费用为10+(重量-3)*5元。
操作步骤如下:
(1)打开“教学管理”数据库,打开VBE窗口。
(2)在模块1的代码窗口中,输入下面的代码。
Sub mailfee( )
Dim w, fee As Single
w=InputBox("请输入货物重量(公斤)","输入重量")
If w<=3 Then fee=10
If w>3 Then fee=10+(w-3)*5
MsgBox "需要支付的邮费是:"&fee&"元",vbOKOnly,"计算结果"
End Sub
(3)单击“运行”按钮,或者按F5功能键,查看运行效果。
2)双分支If语句
双分支If语句的语句格式如下:
格式1:
If <表达式> Then <语句1> Else <语句2>
格式2:
If <表达式> Then
<语句序列1>
Else
<语句序列2>
End If
功能:先计算<表达式>中表达式的值,当表达式的值为真(True)时,执行<语句序列1>中的语句,然后执行If语句的下一条语句;当表达式的值为真(False)时,执行<语句序列2>中的语句,然后执行If语句的下一条语句。
【例9-3】使用双分支语句重新计算例9-2中的邮费。
将代码修改如下:
Sub mailfee2( )
Dim w, fee As Single
w=InputBox("请输入货物重量(公斤)","输入重量")
If w<=3 Then
fee=10
Else
fee=10+(w-3)*5
End If
MsgBox "需要支付的邮费是:"&fee&"元",vbOKOnly,"计算结果"
End Sub
3)If嵌套条件语句
格式:
If <表达式1> Then
<语句序列1>
ElseIf <表达式2> Then
<语句序列2>
……
ElseIf <表达式n> Then
<语句序列n>
Else
<语句序列n十1>
End If
功能:判断条件,执行第一个满足条件的语句序列。当多个条件为True时,只能执行第一个条件为True的语句块。
【例9-4】输入一个学生的成绩score(百分制),当score=100时,输出“满分”;当90<=score<100时,输出“优秀”;当80<=score<90时,输出“良好”;当70<=score<80时,输出“一般”;当60<=score<70时,输出“及格”;当score<60时,输出“不及格”。
操作步骤如下:
(1)打开“教学管理”数据库,打开VBE窗口。
(2)在模块1的代码窗口中,输入下面的代码:
Sub grade( )
Dim score As Integer
score=InputBox("请输入成绩(0至100分)","输入成绩")
If score=100 Then
MsgBox "满分"
ElseIf score>=90 Then
MsgBox "优秀"
ElseIf score>=80 Then
MsgBox "良好"
ElseIf score>=70 Then
MsgBox "一般"
ElseIf score>=60 Then
MsgBox "及格"
Else
MsgBox "不及格"
End If
End Sub
(3)单击“运行”按钮,或者按F5功能键,查看运行效果。
2.Select Case语句
对于多种选择来说,可以通过If语句嵌套实现,但如果嵌套的层次多了,则容易引起混乱,因此,使用多分支控制结构将会更清晰、有效地解决此类问题。多分支控制结构语句又称情况语句。
Select Case <表达式>
Case <表达式值列表1>
<语句序列1>
Case <表达式值列表2>
<语句序列2>
……
Case <表达式值列表n>
<语句序列n>
Case Else
<语句序列n+1>
End Select
功能:执行该语句时,计算<表达式>的值,然后进行判断,如果表达式的值与第i(i=1,2,…,n)个表达式值列表的值相匹配,则执行语句序列i中的语句,如果<表达式>的值与所有的<表达式列表>中的值都不匹配时,则执行语句序列n+1。
【例9-5】使用Select Case重新编程实现例9-4的功能。
将代码修改如下:
Sub grade2( )
Dim score As Integer
Dim s As Integer
score=InputBox("请输入成绩(0至100分)","输入成绩")
s=Int(score/10)
Select Case s
Case10
MsgBox"满分"
Case9
MsgBox"优秀"
Case8
MsgBox"良好"
Case7
MsgBox"一般"
Case6
MsgBox"及格"
Case Else
MsgBox"不及格"
End Select
End Sub
9.2.3 循环结构
循环结构能够使某些语句或程序段重复执行若干次。每一个循环都由循环的初始状态、循环体、循环计数器和条件表达式等4个部分组成。实现循环结构的语句有3种:For…Next语句、While…Wend语句和Do…Loop语句。
1.For…Next语句
如果能够确定循环执行的次数,可以使用For…Next语句。For…Next语句通过循环变量来控制循环的执行,每执行一次,循环变量会自动增加(减少)。
For…Next语句的语句格式为:
For <循环变量>=<初值> to <终值> [Step<步长>]
<循环体>
[ExitFor]
Next <循环变量>
功能:用循环计数器<循环变量>来控制<循环体>内的语句的执行次数。先将<初值>赋给<循环变量>,然后判断<循环变量>是否超过<终值>,若超过则结束循环,执行Next后面的语句;否则执行<循环体>内的语句,再将<循环变量>自动增加一个<步长>,再重新判断<循环变量>的值是否超过<终值>,若结果为真,则结束循环,重复上述过程。
说明:
(1)<循环变量>是数值型的变量,通常为整型变量。
(2)<步长>是<循环变量>的增量,通常取大于0或小于0的数。
(3)<循环体>是在For语句和Next语句之间的语句序列,可以是一条或多条语句。
(4)Next后面的循环变量与For语句中的循环变量必须相同,For语句和Next语句必须成对出现。
(5)Exit For:当执行到该语句时,退出循环,执行Next下面的语句。
语句执行过程:
(1)将初值赋给循环变量,并自动记下终值和步长。
(2)判断循环变量的值是否超过终值。如果没有超过,执行一次循环体;如果超过就结束循环,执行Next后面的语句。这里所说的“超过”有两种含义,即大于或小于。当步长为正值时,循环变量大于终值为“超过”;当步长为负值时,循环变量小于终值为“超过”。
(3)执行Next语句,将循环变量增加一个步长值,转到(2)继续循环。
【例9-6】编写程序求1+3+5+…+99的值。
操作步骤如下:
(1)打开“教学管理”数据库,打开VBE窗口。
(2)在模块1的代码窗口中,输入下面的代码:
Sub Sum( )
Dim Sum As Integer, i As Integer
Sum=0 '保存累加和,先清零
For i=1 To 99 Step2
Sum=Sum+i
Next i
MsgBox "1+3+5+…+99=" & Sum
End Sub
(3)单击“运行”按钮,或者按F5功能键,查看运行效果。
2.While…Wend语句
While…Wend语句的格式如下:
While<条件表达式>
<循环体>
Wend
功能:计算<条件表达式>的值并进行判断,如果为假,则退出循环,执行Wend下面的语句;如果为真,则执行<循环体>的语句,然后再判断条件表达式的值,重复该过程。
说明:
(1)While循环语句本身不能修改循环条件,所以必须在While…Wend语句的循环体内设置相应语句,使得整个循环趋于结束,以避免死循环。
(2)While循环语句先对条件进行判断,然后才决定是否执行循环体。如果开始条件就不成立,则循环体一次也不执行。
语句执行过程:
(1)判断条件是否成立,如果条件成立,就执行循环体;否则转到(3)执行。
(2)执行Wend语句,转到(1)执行。
(3)执行Wend语句下面的语句。
【例9-7】编写程序求1+2+3+…+100的值。
操作步骤如下:
(1)打开“教学管理”数据库,打开VBE窗口。
(2)在模块1的代码窗口中,输入下面的代码:
Sub Sum2( )
Dim Sum As Integer, i As Integer
Sum=0 '保存累加和,先清零
i=1
While i<=100
Sum=Sum+i
i=i+1
Wend
MsgBox "1+2+3+…+100=" & Sum
End Sub
(3)单击“运行”按钮,或者按F5功能键,查看运行效果。
3.Do…Loop语句
Do…Loop也是实现循环结构的语句,它有Do While…Loop和Do…Loop While 2种形式。
Do While…Loop的语句格式:
Do While<条件表达式>
<循环体>
Loop
功能:计算<条件表达式>的值并进行判断,如果为假,则退出循环,执行Loop下面的语句;如果为真,则执行<循环体>的语句,然后再判断条件表达式的值,重复该过程。
Do…Loop While的语句格式:
Do
<循环体>
Loop While<条件表达式>
功能:首先执行<语句序列>的语句,然后计算<条件表达式>的值并进行判断,如果<条件表达式>为假,则退出循环,执行Loop下面的语句;如果为真,则执行<循环体>的语句,重复该过程。
【例9-8】编写一个程序,使用两种Do…Loop形式计算由键盘输入的任意个学生成绩的平均值。
操作步骤如下:
(1)打开数“教学管理”据库,打开VBE窗口。
(2)在模块1的代码窗口中,输入下面的代码:
Sub avg1( )
Dim Data As Integer,Sum As Integer,n As Integer
Dim Average As Single
Sum=0
n=0
Data=InputBox("输入第"& n+1 &"个同学的成绩","求平均分")
Do While Data < >-1 '-1表示结束输入
Sum=Sum+Data
n=n+1
Data=InputBox("输入第"& n+1 &"个同学的成绩","求平均分")
Loop
Average=Sum/n
MsgBox n & "位同学的平均分为"& Average,vbOKOnly,"求平均分"
End Sub
(3)在模块1的代码窗口中,输入下面的代码:
Sub avg2( )
Dim Data As Integer,Sum As Integer,n As Integer
Dim Average As Single
Sum=0
n=0
Data=InputBox("输入第"&n+1&"个同学的成绩","求平均分")
Do Until Data=-1 '-1表示结束输入
Sum=Sum+Data
n=n+1
Data=InputBox("输入第"&n+1&"个同学的成绩","求平均分")
Loop
Average=Sum/n
MsgBox n &"位同学的平均分为"& Average,vbOKOnly,"求平均分"
End Sub
请读者比较两种代码的不同。
9.3 模块
9.3.1 模块的概念
模块是VBA代码的容器,使用模块可以建立自定义函数或者过程,引用数据库中的对象。模块主要由VBA声明语句和一个或者多个过程组成。
声明部分主要包括Option声明,变量、常量或者自定义数据类型的声明。
1.Option Explicit语句
强制显式声明模块中的所有变量,即要求变量在使用之前必须先进行声明。如果没有使用Option Explicit语句,变量未经定义就可以使用。
2.Option Base 1语句
声明模块中数组下标的默认下界为1,不声明则为0。
3.Option Compare Database语句
声明模块中需要字符串比较时,将根据数据库的区域ID确定的排序级别进行比较;不声明则按字符ASCⅡ码进行比较。
9.3.2 模块的分类
在Access中,模块分为两种类型:类模块和标准模块(简称模块)。
类模块是与类对象相关联的模块,当为窗体等类对象或者控件创建第一个事件过程的时候,Access将自动创建与之关联的类模块。同嵌入宏一样,类模块不会出现在导航窗格的模块对象中。
用户也可以自己定义一个独立的类模块,包括成员变量和方法的定义,然后在过程中通过定义的类来创建对象。独立的类模块是可以在导航窗格中看到的,这涉及面向对象编程思想,在此不做过多阐述。
标准模块是存放通用过程的模块,主要包含公用函数过程和子过程,这些公用过程不与任何对象关联,可以被任何数据库对象使用。标准模块中的公共变量或公共过程具有全局性,其作用范围在整个应用程序的生命周期内。
9.3.3 模块的创建
1.窗体模块和报表模块的创建
只要为窗体或者报表创建了第一个事件过程,就创建了对应的代码模块。在窗体或者控件的属性表中,单击事件选项卡中某个事件后面的生成器按钮,选择“代码生成器”,即可打开VBA编辑器,此时系统自动创建一个类模块。
2.标准模块的创建
标准模块的创建有3种方法:
(1)在数据库窗口“创建”选项卡上的“宏与代码”组中单击“模块”按钮。
(2)在数据库窗口“创建”选项卡上的“宏与代码”组中单击“Visual Basic”按钮,打开VBA编辑器。在“插入”菜单中选择“模块”。
(3)在VBA编辑器中的“工程管理器”任意区域,从右键快捷菜单中插入模块。
9.3.4 过程
过程是模块的主要组成部分,也是VBA编写程序的最小单元,用于完成一个相对独立的操作。过程可以分为事件过程和通用过程。
事件过程就是事件的处理程序,用于完成窗体等对象事件的任务,如按钮的单击事件等,它是为了响应用户或系统引发的事件而运行的过程。
通用过程是用户自行编写的程序代码,可以独立运行或者由别的过程调用。
事件过程与通用过程的区别是前者的名字是由系统自动生成,并且依附于窗体等对象而存在,而后者是由用户自己按照习惯命名并且是独立存在的。
过程是由VBA代码组成的单元。它包含一系列执行操作或计算值的语句和方法。过程分两种类型:Sub子过程和Function函数过程。
1.Sub过程
Sub子过程执行一项操作或一系列操作,是执行特定功能的语句块。Sub子过程可以被置于标准模块或类模块中。所有的Sub过程都要事先定义,然后被其他的模块调用。Sub过程定义的格式如下:
[Public|Private] [Static] Sub 子过程名(<形参表>)
[子过程语句]
[ExitSub]
[子过程语句]
End Sub
Sub过程由Sub语句开头,以End Sub结束。Public和Private关键字用于说明子过程的访问属性。Static表示子过程为静态子过程。Sub子过程不需要返回值。
调用子过程的语句格式如下:
Call子过程(实参表)
或
子过程(实参表)【例9-9】编写一个程序,计算斐波那契数列的第10项。分析:斐波那契级数是这样定义的:第一、二项为1,第三项开始,每一项的值是前两项值之和。
操作步骤如下:
(1)打开“教学管理”数据库,打开VBE窗口。
(2)在模块1的代码窗口中执行“插入”菜单的“过程”命令,弹出“添加过程”对话框,如图9-3所示。
图9-3 “添加过程”对话框
(3)创建一个名称为fab的过程,系统会自动生成如下代码:
Public Sub fab( )
End Sub
这就是使用菜单添加过程的方法,与手工输入代码的效果是一样的。
在该过程内输入:
Dim A,B,i,T As Integer
A=1
B=1 '生成级数第一、二项
For i=3 To 10
T=A+B '产生级数新的一项
A=B '让B成为下一组的A
B=T '原来A+B的值成为下一组的B
Next i
MsgBox "斐波那契数列的第10项是:"&B
运行该过程,查看运行结果。
2.Function函数过程
函数定义的格式如下:
[Public|Private] [Static] Function 函数过程名(<形参表>)[As 数据类型]
[函数过程语句]
[ExitFunction]
[函数过程语句]
函数名=表达式
End Function
Function函数过程与Sub过程的区别是它可以有返回值。
【例9-10】编写一个程序,计算斐波那契数列的任意项。
分析:可以先写一个Function函数过程,参数为n,用以计算斐波那契数列的第n项,然后在另外一个过程中调用这个函数。
操作步骤如下:
(1)打开“教学管理”数据库,打开VBE窗口。
(2)在模块1的代码窗口中执行“插入”菜单的“过程”命令,弹出“添加过程”对话框,如图9-4所示。
图9-4 “添加过程”对话框
(3)创建一个名称为f的函数,系统会自动生成Function函数过程的框架,增加参数和代码如下:
Public Function f (n As Integer)
Dim A,B,i,T As Integer
A=1
B=1 '生成级数第一、二项
For i=3 To n
T=A+B '产生级数新的一项
A=B '让B成为下一组的A
B=T '原来A+B的值成为下一组的B
Next i
f=B
End Function
注意:这个函数是不能直接执行的,必须新建一个过程fab1( )来调用它,代码如下:
Public Sub fab1( )
Dim m As Integer
m=InputBox("计算第几项斐波那契数列?")
MsgBox "第" & m & "项斐波那契数列是:"& f(m)
End Sub
在过程fab1( )中调用了f函数,而m是从键盘得到的项数,用作f函数的参数。
9.4 VBA程序的调试
VBA代码输入后,在运行过程中,不可避免地会出现各种错误。这时,就需要借助调试工具,快速定位错误。VBE环境提供了一整套完整的调试工具和方法。
VBA代码运行时,可能会产生3种类型的错误:编译时错误、运行时错误和逻辑错误。
编译时错误是在程序编译时,由于变量未定义、忘了语句配对(如If和End If或者For和Next)或拼写错误等原因产生的不正确代码而引起的错误。
运行时错误发生在应用程序开始运行之后的错误。运行时错误包括企图执行非法运算,例如被零除或向不存在的文件中写入数据。
逻辑错误是编程人员在程序设计或者编写的时候犯下的错误,无法得到预期的运行结果。例如,循环变量的初值和终值设置错误、变量类型不正确、语句代码顺序不正确等。
9.4.1 错误调试
1.设置断点
通过设置断点,可以挂起代码。挂起的代码仍在运行当中,只是在某个语句位置暂停下来。
将光标定位到准备设置断点的代码行,单击“调试菜单中的切换断点”按钮,或者按F9功能键,可以设置或者取消断点。
下面以计算1+3+5+…+99的sum过程为例,来设置断点调试程序。
在Sum=Sum+i所在的代码行设置一个断点,如图9-5所示。
图9-5 设置断点
设置好断点后,按运行按钮或者F5功能键,则运行到该过程的断点行时程序会停下来,该代码行以黄色显示。
此时查看本地窗口,可以观察到当前过程中的所有变量和其当前值,如图9-6所示。
图9-6 本地窗口
2.单步执行
单步执行用于检查程序每一条语句的执行结果,可以与本地窗口配合,观察每个变量的变化情况。
在程序运行到断点所在的代码行时,执行“调试”菜单中的“逐语句”命令或者按下F8功能键,则当前代码被执行(下一条待执行的代码会黄色显示)。此时观察本地窗口,可以看到Sum值发生了变化。反复单步执行,能够在本地窗口中观察到Sum变量累加的过程。
当代码出现错误时,可以在代码中的适当位置添加MsgBox语句,或者使用debug.print语句(结果显示在立即窗口中,也可以在立即窗口中输入“debug.print变量名”来查看变量值),显示代码中变量的值,从而推断错误出处。
9.4.2 错误处理
错误处理,就是当代码运行时,如果发生错误,可以捕获错误,并按照程序设计者事先设计的方法来处理。使用错误处理的好处是:代码的执行不会中断,甚至可以让用户感觉不到错误的存在。
在代码中使用On Error语句,当运行错误发生时,将错误拦截下来。
On Error语句的形式有3种:
1.On Error Resume Next
当错误发生时,忽略错误行,继续执行下面的语句,不停止代码的执行。
2.On Error GoTo语句标号
当错误发生时,直接跳转到语句标号位置所示的错误处理代码,错误处理代码需要实现写好。
3.On Error GoTo 0
禁止当前过程中任何已启动的错误处理程序。
思考题
(1)什么VBA?
(2)VBA有哪几种程序控制结构?
(3)什么是模块,简述类模块和标准模块的区别?
(4)什么是事件过程?什么是通用过程?
(5)事件过程和通用过程有什么区别?
(6)过程与函数有什么区别?
上机题
(1)出租车的计价方式为:起步3公里13元,每超出1公里加收2元。编写一个taxi( )过程,根据用户输入的里程(单位:公里)计算应支付金额。
(2)编写一个mysum过程,分别为For…Next语句、While…Wend语句和Do…Loop语句,计算1+2+…+100。(3)编写一个add过程,用来计算1+2+…+n,n是大于1的整数,由用户从键盘输入。(4)编写一个函数add(n),用来计算1+2+…+n,n是大于1的整数,从另外一个过程mainadd( )调用这个函数得到计算结果。
(5)创建一个窗体“查看日期”,新建一个命令按钮,单击该按钮时会弹出一个消息框,提示当前日期。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。