本文将详细地讨论在visual basic中处理错误发生的on error命令家族,它们的任务就是安装错误代理并解决错误的发生,并解释错误代码的含义。阅读完本文后,你将能编写基本的错误代理程序,有效地防止以外错误。 | ||
| 作者:甘冀平 | ||
| 2000-11-03 | ||
本文包括以下几节内容:
- 使用on error语句
- 如何离开错误处理程序
- 定义错误常数
- 将错误处理程序单独存放
- 理解错误处理的范围
- 不要嵌套使用错误处理程序
visual basic程序使用on error命令来登记错误处理程序,它有下面3种形式:
- on error goto 0
- on error resume next
- on error goto line
these forms tell visual basic what it should do when the program encounters an error. the three forms are described in the following sections.
这些代码告诉visual basic程序当遇到错误时应该做什么。下面详细介绍这3种语句。
on error goto 0
on error goto 0比较直接,它仅仅中止任何当前安装的错误处理代理(比如在前面安装的on error goto line或者on error resume next语句)。如果程序在其后遇到错误,那么就会崩溃。
on error resume next
这种方法使程序忽视发生的错误,当遇到一个错误时,程序继续在其后执行。如果程序使用了on error resume next命令,那么就应该在每次可能产生错误的操作后面检查一下err对象的数值。如果err.number不为零,就表明操作产生了错误,程序可以对此采取特殊的动作。注意:在可能发生问题的语句后,程序应该立即检查err.number的数值,因为,其他的错误操作将复位err对象并清除前面的错误信息。
许多开发人员在给用户一个通用对话框后使用on error resume next命令。 commanddialog控件的cancelerror属性指明了当用户cancel对话框时是否产生一个错误。下面的代码段显示了程序如何使用cancelerror判断是否继续一个操作,比如装入一个文件。
' 如果用户选择了cancel,就产生一个错误
dlgopenfile.cancelerror = true
' 忽视错误的发生
on error resume next
' 显示对话框
dlgopenfile.showopen
' 判断是否有错误
if err.number = cdlcancel then
' 如果是用户canceled,就什么也执行
exit sub
elseif err.number <> 0 then
' 如果是未知错误,就采取另外的行为
:
end if
' 恢复正常的错误处理
on error goto 0 |
on error goto line
使用这个方法,将登记一个新的错误处理代理。如果程序遇到错误,控制将转移到定义的程序行,然后再执行特殊的处理。
请看下面的代码:
private sub dosomething()
' 安装错误处理代理
on error goto unexpectederror
' 日常操作
:
' 使程序不进入下面的错误处理代理程序
exit sub
unexpectederror:
'将错误信息描述给用户
msgbox "unexpected error" & _
str$(err.number) & _
" in subroutine dosomething." & _
vbcrlf & _
err.description
exit sub
end sub |
|
如何离开错误处理程序 |
有下面几种方法可以使程序离开错误处理代理程序的控制,然后返回到正常的执行代码处:
- resume
- resume next
- exit sub/function/property
- end sub/function/property
- err.raise
resume
执行resume语句后,将重复执行发生错误的那条命令。如果那条命令仍然不正确,程序将再次发生错误,这将使程序进入一个不停的循环操作中。为了避免这种循环发生,一般不要使用resume命令,除非在错误处理代理程序中能对错误进行修复。
例如,下面的代码试图装入一个可能存储在软盘上地文件。如果失败,将报告错误,询问用户是否再试一试。如果磁盘不在软驱中,用户可以将之插入然后点击retry按钮。这里的程序就是使用了resume命令实现再次打开文件。当程序又一次失败时,就会再次转到错误处理代理程序中,给用户再次修正错误的机会。最终,直到用户修正了错误,或者点击了cancel按钮。如果点击了cancel按钮,程序退出,没有打开文件。
private sub loaddata(byval filename as string)
dim fnum as integer
'打开文件
fnum = freefile
on error goto openerror
open filename for input as fnum
' 读取数据
on error goto readerror
:
' 关闭文件
on error goto closeerror
close fnum
exit sub
openerror:
’打开文件失败,询问用户是否再次打开
if msgbox("error" & _
str$(err.number) & _
" opening file " & filename & "." & _
vbcrlf & err.description & vbcrlf & _
"check that the disk is properly " & _
"inserted and click the retry button.", _
vbretrycancel, _
"error opening file") = vbretry _
then
'再次打开文件
resume
end if
’否则,选择cancel退出这个过程
exit sub
readerror:
msgbox "error" & _
str$(err.number) & _
" reading file " & filename & "." & _
vbcrlf & err.description
'关闭文件
close fnum
exit sub
closeerror:
' 关闭文件发生错误
msgbox "error" & _
str$(err.number) & _
" closing file " & filename & "." & _
vbcrlf & err.description
exit sub
end sub |
|
resume next 执行resume next命令使程序在发生错误那条命令后继续执行,这对于程序和用户不能合理地修正错误时很有意义,但同时程序可能执行不完整。 比如,下面的代码使用cdate函数转换一个字符串为日期格式,如果失败了,错误处理代理程序就分配给start_date变量的值为当前的日期:
请注意,尽量不要使用这种方法处理错误,因为它采取了“安静”的方式,而不是明显地告诉用户发生了错误。应该是这样,当用户输入了非法日期后,就提示他发生了错误,并要求输入一个新的数值。 exit sub/function/property 如果程序不能继续它的任务,可以立即使用 exit sub、 exit function 或者 exit property 实现退出。下面的代码是上面那段程序的一个新版本,如果日期字符串非法,就告诉给用户,然后退出程序:
按照这种方式退出程序,调用的程序就不可能告诉用户错误发生了。这意味着:不管程序是否成功,调用程序能够合适地继续执行时,才适于采用这个方法。如果调用者必须要知道错误发生了,那么代码中就必须要使用err.raise命令来简短地进行一下描述。 end sub、 end function end property 如果错误处理代理程序最后接触到程序的 end sub、 end function 或者 end property 语句,就会产生自然执行exit命令的效果。比如,上面那段代码的最后部分可以这么编写:
可是有时候,这么处理会带来一些混淆。因为,也可能要处理新的错误,那么再随后添加新的错误处理代理程序时,就有可能注意不到上一个错误处理代理程序没有使用exit语句做为结尾,这样,就会发生上一个错误处理代理程序直接执行到下一个代码段中。比如,下面的代码段中,如果遇到一个非法日期,将会显示2段出错提示信息,而不是实际应该存在的1个:
因此,为了避免这种错误的发生,不要让错误处理代理程序直接接触到过程的end命令做为结束。要使用exit命令完成离开程序的功能! err.raise err对象提供了一个raise方法,它允许程序产生一个新错误,或者再次产生上一次的错误。它的语法如下: err.raise number, [source], [description], [helpfile], [helpcontext]
错误信息处理策略 |