(转)VB程序错误处理方法小结
一、VB的编译选项
VB有两个设置项会在很大程度上影响我们创建非常坚实的代码的能力。一个设置项是Compile On Demand(按需要进行编译),另一个设置项是Background Compile(后台编译)。可以打开Options对话框,选定General选项卡,然后对这两个设置项进行设置,如下图1所示。当选定Compile On Demand时,如果单击工具栏上的Run按钮,或者按F5键,VB并不全面编译我们的项目。相反,只在引用过程时,才对这些过程进行编译。使用Compile On Demand,通常可使比较大的项目或者速度较慢的计算机上的项目能够更快地启动运行,但是它也会产生某些不被注意的编译错误。
在发现和纠正所有编译错误之前,不能将项目编译成.exe或.dll之类的可发布文件,因此,选定Compile On Demand并不能够发布带有编译错误的代码。但是,选定Compile On Demand后,会导致编译错误随着时间的推移而不断增加,从而在最后试图进行全面编译时,迫使我们对代码进行大量的纠错。如果在IDE中调试项目,VB常常必须停止(不只是暂停)运行,以便进行纠错操作。这使得调试正在运行的项目时对大量编译错误的纠正操作变得非常麻烦。如果能够在合理的时间内全面编译项目,那么可以考虑关闭Compile On Demand。也可以使Compile On Demand保持选定状态,但是要定期按Ctrl+F5键,以便重新运行我们的项目。这使我们在编程时能够定期纠正编译错误,而不必一次性纠正大量的编译错误。
图1 编译时选中Compile On Demand和Background Compile两个选项
二、Err对象
在能够编写有效的错误处理代码之前,我们必须了解VB的Err对象,这是个运行期对象,它包含了关于最新错误的信息。当程序运行时遇到一个错误,或者当我们使用Err对象的Raise方法故意引发一个错误时,便形成Err对象的属性。当遇到On Error语句(比如On Error Resume Next),并且在使用Exit Sub、Exit Function或Exit Property语句退出一个过程后,Error对象的属性值就被清除。若要显式清除Err对象,可以调用它的Clear方法。下表1列出了Err对象的属性。
属性
|
说明
|
Number | 用于标识该错误的专用号码 |
Source | 当前VB项目的名字 |
Description | 表义性的错误消息。如果某个错误没有这个字符串,本属性就会指明"应用程序定义的错误或对象定义的错误" |
HelpFile | 与错误相关的VB 帮助文件所在的驱动器、路径和文件名 |
HelpContext | VB 帮助文件用于该错误的上下文ID |
LastDLLError | 在32位Microsoft Windows操作系统上,上次调用动态链接库(DLL)的系统错误代码。LastDllError属性是只读属性 |
三、错误处理程序的类型
将一个项目当作已经编译的程序运行时,未捕获的错误会造成致命的后果,它们会导致程序终止运行。必须尽一切努力防止发生这种情况。
若要捕获错误,基本上可以使用下面两种方法:
当出现错误时,使用On Error GoTo,转移到别的代码上去执行。
使用On Error Resume Next语句,不中断代码的执行,也不转移到别的代码上去执行,而是忽略该错误。
可以在一个过程中创建多个错误处理程序,但每次只能激活一个错误处理程序。VB将最新的On Error语句中指明的处理程序视为已经激活的错误处理程序。切换一个过程中的不同位置上的错误处理程序,往往是很有好处的,理解各个错误处理程序如何运行,是利用这一功能的关键。
1、使用On Error Resume Next以忽略错误
对错误进行处理的最简单(和最危险)的方法是使用On Error Resume Next语句。On Error Resume Next语句规定,代码中的错误将完全被忽略,存在错误的代码行被跳过,然后继续执行下一个语句。例如,下面这个过程存在一个运行期错误(即一个被0除的错误),它由On Error Resume Next错误处理程序来处理:
Private Sub cmdGenerateError_Click() '* Purpose: Test On Error Resume Next On Error Resume Next Debug.Print 10 / 0 End Sub |
Debug.print语句产生了一个被0除的错误。但是,由于存在一个已经激活的错误处理程序(由On Error Resume Next指定),因此该错误被忽略,并在下一个语句(即End Sub语句)上恢复执行。错误被忽略并不意味着我们无法知道错误已经发生。当一个语句产生了一个错误之后,尽管没有显示出错消息,Err对象仍然包含关于该错误的信息。
2、使用On Error GoTo转移执行的代码流
除非我们捕获了一个意料之外的错误,比如上面代码中的那种错误,否则忽略代码中的错误是非常危险的,并且是一种不得已时采用的办法。当一个过程中出现了意料之外的错误时,该过程就会产生许多问题。如果忽略该错误,就会对用户产生严重的影响,比如数据没有保存,或者保存不正确。许多情况下,当出现代码错误时,必须执行某些操作,将代码的执行转移到On Error GoTo语句中指定的错误处理程序。该语句的句法如下:
On Error GoTo line |
请注意,line必须是指与On Error GoTo语句相同的过程中的一个语句。
在这个句法中, line有两个意思。首先它是指出现错误时要转移到的这个代码行号。不过这个行号并不是过程中的代码行的物理位置。请看下面这个代码例子:
Private Sub TestErrorHandler() |
我们可能认为,被0除的错误会导致代码在输出文本line 4这个语句上继续执行,因为这是代码的第四个语句(不是计数注释)。不仅这种情况不会发生,而且该代码实际上会导致产生一个编译错误,并且代码根本不会执行。
3、用调试方式激活错误处理程序和取消其激活状态
虽然我们不希望已编译程序中的错误不被捕获,但是,当程序在IDE中运行时如果出现错误,让VB中止代码的执行,这样做常常是非常不利的。当代码的执行中止时,会看到一条相关的出错消息,并告诉我们出现错误的代码行,这对于代码的调试来说是大有帮助的。VB为处理代码设计时遇到的错误而使用的方法取决于VB IDE的Error Trapping(捕获错误)属性。Error Trapping属性是VB环境的一个属性,不是某个项目的属性。我们操作的每个项目,即使在关闭和重新启动VB之后,均使用该设置值。若要为VB的当前会话设置Error Trapping选项,而不必为将来的会话修改默认值,请使用代码窗口的快捷菜单上的Toggle命令(见图2)。
图2 从任何代码窗口的快捷菜单中选择Toggle命令
可以将Error Trapping属性设置为下列值中的一个:
Break On All Errors(在所有错误上中止)。
Break In Class Module(在类模块中中止)。
Break On Unhandled Errors(在未处理的错误上中止)。
Break On All Errors实际上可使所有错误处理程序均取消激活状态。当出现一个错误时,无论是否激活了处理程序,代码均在出错的语句上进入中止方式,同时VB显示一条出错消息。这使我们能够在IDE进行测试时处理意料不到的错误。