Transcript Document

第14章
调试应用程序
本章主要内容:
● 错误类型及防错要点
● 调试应用程序
● 错误陷阱
14.1
错误类型及防错要点
使用VB时可能会遇到三类错误:语法错误、运行时期错
误及逻辑错误。
14.1.1 语法错误
用户在输入代码时,VB会自动对变量类型、对象属性等
提供列表选择框以尽量避免输入错误,减少用户记忆工作
量,如图14-1所示。对于某些出错的关键字会立即显示出
错信息框,如图14-2所示。
14.1.2
运行时期错误
如果语句执行了无法完成的任务时就会发生此类错误,
此类错误在语法检查时通常不会被发现。如图14-3所示的
分母为零和图14-4所示的数据类型不匹配等。
14.1.3
逻辑错误
程序中所有语句均通过了VB的自动语法检查,运行时也
未出现错误信息提示,但运行的结果却不正确,这种情况
通常是逻辑错误造成的。例如,将模块级变量的定义语句
写到了某一过程中,使之无法返回相应的数据、将本应写
入Text2的内容写到了Text1中、运算符号出现了错误(把
“+”写成了“-”)、程序运行时用户输入了非法的数据等
等。逻辑错误具有隐蔽性,不易被察觉。是排错的重点,
也是难点。
程序出错虽然不可避免,但遵循下列原则将有助于减少出错
的机会:
① 使用Option Explicit语句强制声明变量,避免因变量误用引发逻辑错误。
② 整理清楚与应用程序相关的所有事件,妥善定义每个事件过程和通用
过程。
③ 加入适量的注释,将增强程序的可读性,有助于对程序的理解。
④ 使用一致的变量和对象命名规则。
⑤ 尽可能说明对象的类型,尽量少使用Variant类型变量。
⑥ 通过设计错误处理程序,捕获、处理错误或显示出错提示。
14.2
调试应用程序
14.2.1
VB的三种工作模式
VB创建的应用程序从创建开始到最终完成,其状态可以分
为三种模式:设计时、运行时和中断方式时。
1. 设计时
创建应用程序的大多数工作都是在设计时完成的。在设计
时,可以设计窗体、绘制控件、编写代码并使用“属性”窗
口来设置或查看属性设置值。除了可以设置断点和创建监视
表达式外,不能使用调试工具。
在“运行”菜单中选择“启动”,或单击“运行”按钮切
换到运行时。如果应用程序在启动时执行了代码,而且本身
又包含这些代码,那么就选择“运行”菜单中的“单步”,
或按下F8键,使应用程序在第一个可执行语句处被置为中断
模式。
2. 运行时
当应用程序进行控制时,可像用户那样与应用程序交
往。可查看代码,但不能改动它。选择“运行”菜单中
的“结束”,或单击“结束”按钮切换回设计时。
3. 中断方式时
选择“运行”菜单中的“中断”,或单击“中断”按
钮,或按Ctrl+Break键切换到中断模式。
运行应用程序时也可中止执行。可以查看并编辑代码
(执行“视图”菜单中的“代码”命令,或按F7键)、
检查或修改数据、重新启动应用程序、结束执行或从中
止处继续运行。可以在设计时设置断点或监视表达式,
但其它调试工具只能在中断模式下使用。
为测试和调试应用程序,在任何时刻都要知道应用程序
正处在三种模式的哪种模式之下。在设计时可用VB创建应
用程序,而在运行时运行这个程序,而在中断模式下能够
中断程序的执行,从而得以检查和改变数据。工作模式的
状态分别用[设计]、[运行]和[break]标记直接显示在标题栏
中,识别十分容易,如图14-5、图14-6和图14-7所示。
14.2.2 调试工具
VB提供了一些非常有效的调试工具,可以帮助用户分析
程序的执行过程,分析变量和对象属性的变化情况。借助于
调试工具用户可以深入到应用程序内部观察,方便地分析并
找出程序出错的原因。VB提供的主要的调试工具及用途,
如表14-1所示。
表14-1 主要调试工具及用途
调试工具
说明
断点
在“代码”窗口中确定一行,VB在该行终止应用程序的执行
跟踪
执行应用程序代码的下一个可执行行,并跟踪到过程中
单步
执行应用程序代码的下一个可执行行,但不跟踪到过程中
单步出
执行当前过程的其它部分,并在调用过程的下一行处中断执行
本地窗口
显示局部变量的当前值
立即窗口
当应用程序处于中断模式时,允许执行代码或查询值
监视窗口
显示选定表达式的值
快速监视
当应用程序处于中断模式时,列出表达式的当前值
调用堆栈
当处于中断模式时,呈现一个对话框来显示所有已被调用但尚未完
成运行的过程
另外,VB提供了一个调试工具栏,使用它可以解决大多
数程序调试问题。在集成开发环境的工具栏上单击鼠标右键
,在弹出的快捷菜单中选择“调试”,即可打开图14-8所示
的“调试”工具栏。
缺省情况下,“调试”工具栏是浮动在主窗口中的,用户
可以将它拖动到“标准”工具栏的下方使之固定,也可以单
击工具栏上按钮将其关闭。
14.2.3
调试方法
1. 设置断点
设置断点的操作步骤如下:
① 在代码窗口中将光标移动到欲设置断点的语句行,按
F9键或直接用鼠标单击语句行首灰色标记区,也可以通过
执行“调试”菜单中的“切换断点”命令完成断点的设置。
如图14-9所示,此时在标记区会出现一个大圆点,语句行
也变成了其他颜色。注意,根据需要,在程序中可以设置
多个断点。
② 当程序执行到断点语句时,会暂停执行。用户可以在
立即窗口中键入命令查看当前变量、属性的值。如图14-10
所示,在立即窗口中键入print i,a,b命令可以显示出当前三
个变量的取值情况。如果需要程序继续执行下去可按F5键
或单击工具栏中的“”按钮。
2. 清除断点
(1) 清除单个断点
如果要清除单个断点,可采用下面几种方法之一:
l 直接用鼠标单击标记区中的断点标记,这是最简单的
方法。
l
将光标移动到断点所在行后,执行“调试”菜单中
的“切换断点”命令或按F9键。
(2) 清除所有断点
如果希望清除程序中设置的所有断点,可以用下面的方法
之一:
l
按Ctrl+Shift+F9键。
l
执行“调试”菜单中的“清除所有断点”命令。
(3) 使用Stop语句
在程序的适当位置插入一条Stop语句,则执行该语句后,
程序将暂停并切换至中断模式,这是设置断点的一种变通方
法。Stop语句除了暂停程序的执行外,不做任何事情。可以
按F5键或单击工具栏中按钮,使继续程序的运行。
注意,在程序调试结束完毕准备进行编译之前,一定要将
所有的Stop语句删除,否则编译后的.exe程序会把Stop语句当
作End语句来处理,而且不触发任何QueryUnload或Unload事
件。
2. 跟踪执行轨迹
VB提供了4种跟踪方式:逐语句(Step Into)、逐过程(
Step Over)、跳出(Step Out)和运行到光标处(Run to
Cursor)。
14.2.4 使用调试窗口
1. 立即窗口
可以帮助用户检查变量或属性的值,同时也可以通过它
重新设置变量或属性的值。其优点是:不中断程序的执行
,即可看到结果且不影响原有窗体的外观。
立即窗口的使用方法有:
l
直接在窗口中键入简单的语句。
l
在程序中插入Debug.Print表达式列表语句,将某
些值直接输出到立即窗口。
2. 本地窗口
显示当前过程所有变量及对象的取值时,随着从一个过
程切换到另一过程,本地窗口的内容也随之变化。列表中
的第一个变量Me是一个特殊的模块变量,可用来扩充显示
出当前模块中的所有模块层次变量,单击它前面的“+”号
可以显示进一步的信息,如图14-11所示。但应注意,全局
变量以及其它工程中的变量都不能从本地窗口中访问。
3. 用监视表达式监视数据
(1) 添加监视表达式
添加监视表达式的操作方法为:
① 执行“调试”菜单中的“添加监视”命令,打开“添加
监视”对话框,如图14-12所示。
② 从代码窗口中将需要监视的表达式拖放到“表达式”输
入框中。
③ 在“上下文”中选择过程和模块。
④ 在“监视类型”中,选择“监视表达式”或根据监视值
的情况使程序中断。
⑤ 对于已建立的监视表达式,可以通过“调试”菜单中
执行“编辑监视”命令打开“编辑监视”对话框进行编辑
、修改,如图14-13所示。
⑥ 在监视窗口中选中表达式后,可以按Delete键或在“
编辑监视”对话框中单击“删除”按钮删除表达式。
(2) 使用快速监视
在中断模式下,有时需要查看那些未定义监视表达式的
属性、变量和表达式的值。此时可以使用“快速监视”对
话框。
在代码区选定需要监视的表达式,使用“调试”工具栏
中的按钮,或“调试”菜单中的相应命令,或按Shift+F9
键,均可打开“快速监视”对话框,如图14-14所示。单击
“添加”按钮,可以将表达式添加到监视窗口中。
4. 调用堆栈窗口
通过“调用堆栈”窗口可以显示正在执行的过程、程序
和方法程序。第一个程序运行时,该程序名列在“调用堆
栈”窗口中,如图14-15所示。
如果调用了第一个程序中的子程序或子过程,同时又在
执行第二个程序,两个程序的名字均显示在“调用堆栈”
窗口中,如图14-16所示。本例主程序调用了ChangeColdr
子程序。
14.3
14.3.1
错误陷阱
On Error语句
设置错误陷阱可以使用On Error语句,其语法形式见表
14-2。
表14-2 On Error语句的语法形式
语句
说明
On Error GoTo line
转去以line为行号的程序行继续执行
On Error Resume Next
从出错语句的下一条语句继续执行
On Error GoTo 0
关闭当前过程中所有已启动的错误处理程序
错误处理程序的设计一般可分为以下三步:
① 使用On Error语句捕获错误,并把程序流程转向由标
号指示的错误处理程序段。
② 编写错误处理代码,对所有可能预见的错误都做出相应
的安排。
③ 根据错误类型可使用Resume语句重新执行出错语句,
或使用ResumeNext语句执行出错语句的下一条语句继续运
行程序。
【例14-1】
14.3.2
Err对象
1. Err对象的方法
Clear方法的语法格式为:
Err.Clear
在处理错误之后,可以使用Clear来清除Err对象,例如,
在对On Error Resume Next使用拖延错误处理时就可使用
Clear。每当执行下列语句时就会自动调用Clear方法:
l
任意类型的Resume语句。
l
Exit Sub, Exit Function, Exit Property。
l
任何On Error语句。
注意,当处理因访问其他对象产生的错误时,与其使用
On Error GoTo,不如使用On Error Resume Next。每一次
与对象打交道之后都检查Err,则可消除代码访问对象时的
含混之处。可以确认是哪个对象将错误引入Err.Number中,
也可以确认最初是哪个对象产生了这个错误(Err.Source中
指定的对象)。
【例14-2】
2. Raise方法
当运行时错误发生时,Err对象的属性被填入明确识别错
误的信息以及处理这个错误所使用的信息。为了在代码中
生成运行时错误,应使用Raise方法。
其语法格式为:
Err.Raise number, source, description, helpfile, helpcontext
各参数的含义见表14-3。
表14-3
参数
number
Raise参数的含义及说明
说明
必需的。Long整数,识别错误性质。VB错误(既有VB定义的错误也有用户定义的错
误)的范围在0~65535之间。从0~512的范围保留为系统错误;从513~65535的范围
可以用做用户定义的错误。当在类模块中将Number属性设置成自己的错误代码时,
可将错误代码号添加到 vbObjectError常数上。例如,为了产生错误号513,可将
vbObjectError+513赋值到Number属性
source
可选的。字符串表达式,为产生错误的对象或应用程序命名。当设置对象的这一属性
时,要使用窗体project.class。如果没有指定source,则使用当前Visual Basic工程的程
序设计ID
description
可选的。描述错误的字符串表达式。如果没有指定,则检查Number的值。如果可以
将错误映射成VB运行时错误代码,则将Error函数返回的字符串作为Description使用。
如果没有与Number对应的错误,则要用到消息“应用程序定义的错误或对象定义的
错误”
helpfile
可选的。帮助文件的完整限定的路径,在帮助文件中可以找到有关错误的帮助信息
helpcontext 可选的。识别helpfile内的标题的上下文ID,而helpfile提供有助于了解错误的描述
3. Err对象的属性
Err对象的缺省属性是Number。因为该缺省属性可以用
对象名称Err表示,所以不必修改以前用Err函数或Err语句
书写的代码,Err对象的常用属性见表14-4。
表14-4 Err对象的常用属性
属性
说明
Number
返回或设置表示错误的数值。Number是Err对象的缺省属性
Description
返回或设置一个字符串表达式,包含与对象相关联的描述性字符串
HelpContext
HelpFile
返回或设置一个字符串表达式,包含 Microsoft Windows帮助文件中的主题的
上下文ID
返回或设置一个字符串表达式,表示帮助文件的完整限定路径
LastDLLError
返回因调用动态链接库 (DLL) 而产生的系统错误号
Source
返回或设置一个字符串表达式,指明最初生成错误的对象或应用程序的名称
14.4
习题