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 习题