|
关于程序错误处理,是一个常见而又非常被容易忽视的问题。错误处理,顾名思义就是程序在发生错误时的处理过程。为什么要有错误处理?如果没有错误处理又会怎么样呢?
我们首先来简单的说说上面两个问题。
一、为什么要有错误处理呢?这是因为任何一个程序都不可能说是不会发生任何错误的(注意:我们这里说的错误只是指的狭义的逻辑错,并不包括语法错)。
二、如果没有错误处理会发生什么呢?我们先来看一段简单的代码: - Sub Test()
- Dim M As Long
- Dim N As Long
- M = Val(InputBox("请输入一个整数", "M*N"))
- N = Val(InputBox("请输入一个整数", "M*N"))
- MsgBox CStr(M) & "×" & CStr(N) & "=" & CStr(M * N)
- End Sub
这是一个输入两个整数然后输出这个两数乘积的过程,这段程序有没有错误呢?——没有。输入一个"3",再输入一个"2",程序立即输出了"3×2=6"。那这段程序能永远不出错吗?答案也是否定的,两次输入时任意一次输入"A"程序就会报错了,那么是否只要保证两次输入都是整数程序就不会出错了呢,答案还是否定的,只要输出的两个数乘积大于2147483647,程序还是会出错。这正验证了一句话:永远都不要相信用户的输入。
既然程序这么容易出错,那么错误处理就是一个程序必不可少的部分,任何一个好的程序员都不能忽视这一环节,谁也不会想让自己的程序随时都可能弹个错误对话框后程序就被非法关闭了。
那么,现在我们就面对了一个新的问题:如何处理错误?
相信多数人立即想到了On Error Goto XXXX(XXXX表示一个标签或是一个行号)和On Error Resume Next。是的,这是两种最常见的错误处理方式。但是,有多少人真正了解这两条语句呢。我知道很多人天天都在用这两条语句,对它们的作用随口都能说出来。今天我们暂时就先不说明这两条语句的作用和意义了。我们先还是把它们拆开来看。On Error Goto XXXX和On Error Resume Next我们就先把它们拆成On Error、Goto、Resume Next。我们先来看看On Error的帮助。
On Error 语句
启动一个错误处理程序并指定该子程序在一个过程中的位置;也可用来禁止一个错误处理程序。
语法
On Error GoTo line
On Error Resume Next
On Error GoTo 0
On Error 语句的语法可以具有以下任何一种形式:
语句 描述
On Error GoTo line 启动错误处理程序,且该例程从必要的 line 参数中指定的 line 开始。line 参数可以是任何行标签或行号。如果发生一个运行时错误,则控件会跳到 line,激活错误处理程序。指定的 line 必须在一个过程中,这个过程与 On Error 语句相同; 否则会发生编译时间错误。
On Error Resume Next 说明当一个运行时错误发生时,控件转到紧接着发生错误的语句之后的语句,并在此继续运行。访问对象时要使用这种形式而不使用 On Error GoTo。
On Error GoTo 0 禁止当前过程中任何已启动的错误处理程序。
说明
如果不使用 On Error 语句,则任何运行时错误都是致命的;也就是说,结果会导致显示错误信息并中止运行。
一个“允许的”错误处理程序是由 On Error 语句打开的一个处理程序;一个“活动的”错误处理程序是处理错误的过程中允许的错误处理程序。如果在错误处理程序处于活动状态时(在发生错误和执行 Resume、Exit Sub、Exit Function 或 Exit Property 语句之间这段时间)又发生错误,则当前过程的错误处理程序将无法处理这个错误。控件返回调用的过程。如果调用过程有一个已启动的错误处理程序,则激活错误处理程序来处理该错误。如果调用过程的错误处理程序也是活动的,则控件将再往回传到前面的调用过程,这样一直进行下去,直到找到一个被允许的但不是活动的错误处理程序为止。如果没有找到被允许而且不活动的错误处理程序,那么在错误实际发生的地方,错误本身是严重的。错误处理程序每次将控件返回调用过程时,该过程就成为当前过程。在任何过程中,一旦错误处理程序处理了错误,在当前过程中就会从 Resume 语句指定的位置恢复运行。
注意 一个错误处理程序不是 Sub 过程或 Function 过程。它是一段用行标签或行号标记的代码。
大家看到这里是不是对On Error已经有了一个比较清晰的了解了吧。如果还不是很清楚的话可以再看看下面的过程,它演示了On Error Goto XXXX和On Error Resume Next,相信大家看完后就能立即明白这两条语句了。 - Sub TestError1()
- Dim I As Long
- On Error Resume Next ' 指定发生错误时不处理,直接运行下一条语句
- I = "A1" ' 发生错误,由于已经指定了发生错误时不处理,故Err对象立即返回直接运行下一条语句。
- Debug.Print "被忽略的错误,错误代码:" & Err.Number & " 错误信息" & Err.Description & " 错误源:" & Err.Source & " 当前I的值=" & I
- Err.Clear ' 清空所有错误记录
- On Error GoTo ERROR1 ' 指定下面的错误发生时直接跳转至Error1标号处
- I = 2147483648# ' 发生错误,由于指定了跳转,故直接转至Error1,而不会再执行下面的语句
- I = 100
- Debug.Print "程序正常返回,当前I的值=" & I
- Exit Sub
- ERROR1:
- Debug.Print "发生错误,错误代码:" & Err.Number & " 错误信息" & Err.Description & " 错误源:" & Err.Source & " 当前I的值=" & I
- End Sub
相信现在大家已经完全明白了这两条语句的用法了。但是,大家也看到了,第二条语句出错时,输出错误代码后程序直接退出了,或许有人又会想,如果当第二次错误发生时能不能输出错误代码后再返回到出错的下一条语句再断续执行程序呢?这时我们就要使用到Resume Next了。还是老规矩,把它拆成Resume、Next来看,我们看看Resume的帮助。Resume 语句
在错误处理程序结束后,恢复原有的运行。
语法
Resume [0]
Resume Next
Resume line
Resume 语句的语法可以具有以下任何一种形式:
语句 描述
Resume 如果错误和错误处理程序出现在同一个过程中,则从产生错误的语句恢复运行。如果错误出现在被调用的过程中,则从最近一次调用包含错误处理程序的过程的语句处恢复运行。
Resume Next 如果错误和错误处理程序出现在同一个程序中,则从紧随产生错误的语句的下个语句恢复运行。如果错误发生在被调用的过程中,则对最后一次调用包含错误处理程序的过程的语句(或 On Error Resume Next 语句),从紧随该语句之后的语句处恢复运行。
Resume line 在必要的 line 参数指定的 line 处恢复运行。line 参数是行标签或行号,必须和错误处理程序在同一个过程中。
说明
在错误处理程序之外的任何地方使用 Resume 语句都会导致错误发生。
我们看到了Resume Next,但是很明显,它只是Resume 三种调用方式中最常见的一种,不过上面的信息已经足够了,我们使用Resume Next就可以达到上面的要求了。 - Sub TestError2()
- Dim I As Long
- On Error Resume Next ' 指定发生错误时不处理,直接运行下一条语句
- I = "A1" ' 发生错误,由于已经指定了发生错误时不处理,故Err对象立即返回。
- Debug.Print "被忽略的错误,错误代码:" & Err.Number & " 错误信息" & Err.Description & " 错误源:" & Err.Source & " 当前I的值=" & I
- Err.Clear ' 清空所有错误记录
- On Error GoTo ERROR2 ' 指定下面的错误发生时直接跳转至Error2标号处
- I = 2147483648# ' 发生错误,由于指定了跳转,故直接转至Error1,而不会再执行下面的语句
- I = 100 ' 由于在Error2后面指定了Resume Next,所以程序还会再次返回到这里开始执行,这就是和过程TestError1不同之处
- Debug.Print "程序正常返回,当前I的值=" & I
- Exit Sub
- ERROR2:
- Debug.Print "发生错误,错误代码:" & Err.Number & " 错误信息" & Err.Description & " 错误源:" & Err.Source & " 当前I的值=" & I
- Resume Next ' 返回发生错误处的下一条语句,继续执行
- End Sub
|
评分
-
查看全部评分
|