返回首页
当前位置: 主页 > Excel教程 > Excel VBA教程 >

Excel/VBA的错误处理基础教程

时间:2014-04-30 23:04来源:Office教程学习网 www.office68.com编辑:麦田守望者

如果不提供错误处理方法,VBA在出错时会停留在出错之处。Excel/VBA提供On Error关键词来处理程序运行过程中的错误,具体有下面两种用法:

  1. On Error Resume Next:当出错时跳到下一行继续运行。
  2. On Error Goto Line:出错时跳到行号Line。这里行号Line可以为数字(不为0和-1),也可以为字符串。

其它与之相关的还有:

  1. On Error Goto 0:运行后,对错误的捕获被关闭。程序出错时将自动中止。
  2. On Error Goto -1:运行后,「Resume」和「Resume Next」将失效。
  3. Resume:跳回并重新运行出错的行
  4. Resume Next:跳回并运行出错位置的下一行。

上面各种语句的组合可以非常复杂。下面是我半天时间的研究成果。

1.VBA处理出错的两种方式

设置On Error Resume Next在出错时直接运行下一行,然后可以通过Err.Number来判断是否出错然后进行相关处理。

Sub Demo1()
    On Error Resume Next

    Call doing_thing1
    If Err.Number > 0 Then
        Call err_handler1   ' err handler deals with err in doing_thing2
        Err.Clear
    End If

    Call doing_thing2
    If Err.Number > 0 Then
        Call err_handler2   ' err handler deals with err in doing_thing2
        Err.Clear
    End If

    On Error GoTo 0
    Call doing_next_thing
End Sub

On Error Goto Line的方法更强大,在错误处理完毕之后还可以通过ResumeResume Next返回原出错点或出错点的下一行。

Sub Demo2()
    On Error GoTo err_handler_line1
    Call doing_thing1

    On Error GoTo err_handler_line1
    Call doing_thing2

    On Error Resume Next    ' On Error Resume Next和 On Error Goto可以混着用
    Call doing_next_thing

    Exit Sub

err_handler_line1:
    Call err_handler1
    Resume        ' return and re-run the error line
    ' 上面一行Resume、Resume Next、Exit Sub可根据情况任选其一
    ' 而且必须选一个,否则doing_thing1出错时,下面的Err_hander2也会被运行
err_handler_line2:
    Call err_handler2
    Resume Next   ' resume to next of the error line
End Sub

2.Err变量

VBA有一个全局变量Err,它保存了程序运行过程中出现的最后一个错误的相关信息(比如错误编码、错误描述等)。一般我们可以通过Err.Number > 0来判断是否出错;通过Err.Description查看具体出错信息。

Err可以通过Err.Clear手工清除。

VBA在每次碰到On Error Resume NextOn Error GotoResumeResume Next都会自动清空Err。我们需注意重复设置错误处理代码的副作用。比如在上面Demo2添加一行,后面的错误处理程序就失效了:

Sub Demo3()
    On Error Resume Next
    Call doing_thing        '?如果此处出错,Err将保存错误信息

    On Error Resume Next    ' 此处Err对象被清空

    If Err.Number > 0 Then
        Call err_handler    ' 由于Error被清空,此处错误处理程序已经失效。
        Err.Clear
    End If

    Call doing_next_thing
End Sub

Err是全局变量,母函数的错误信息会带入到子函数,子函数的错误信息也会被返回母函数。但实际表现非常复杂,具体请参考本文第五部分。

3.isErrorHanderEnabled

VBA里对错误处理有两个状态。一个是isErrorHanderEnabled,另一个是isErrorHanderActive。这两个变量名不是真实的变量,只是为了更好解释这个问题。

isErrorHanderEnabled指目前是否捕获程序发生的错误,具体而言即是否设置了On Error Resume NextOn Error Goto Line。如果isErrorHanderEnabled == False,一旦某行代码出错,VBA便会中止运行,并提示出错。如果isErrorHanderEnabled == True,则按照设置方法,VBA在出错后直接跳转或者继续运行下一行。

On Error Goto 0相当于取消前面设置的On Error Resume NextOn Error Goto Line,即重设isErrorHanderEnabled = False。接下来代码运行过程中一旦出错,便会中止运行。

isErrorHanderEnabled是一个局部变量,即子函数和母函数的状态互不影响。每个函数刚开始时,isErrorHanderEnabled的默认状态都是False

4.isErrorHanderActive

isErrorHanderActive是指VBA现在是否正在处理错误。如果设置了On Error Goto Line,然后程序出错时,此时程序自动跳转到Line位置开始运行,并设置isErrorHanderActive = True

On Error Goto -1用来告诉VBA目前错误已经处理完毕,VBA应该回到正常运行状态,并设置isErrorHanderActive = False

isErrorHanderActive一样,isErrorHanderEnabled也是一个局部变量,即子函数和母函数的状态互不影响。每个函数刚开始时,isErrorHanderActive的默认状态也是False

需注意isErrorHanderActiveErr.Number>0并无直接关系,比如下面例子:

Sub Demo5()
    Dim i As Long
    On Error Resume Next
    i = 1 / 0        ' err occurs
    MsgBox "Here: Err.Number > 0 but isErrorHanderActive = False"

    On Error GoTo err_handler:
    i = 1 / 0        ' err occurs, set isErrorHanderActive = True

err_handler:
    On Error Resume Next        ' this will clear err
    MsgBox "Here: Err.Number = 0 but isErrorHanderActive = True"
End Sub

5.函数调用时发生什么?

VBA的子函数和母函数在处理错误之间的关系比较复杂。一般情况尽量让各自函数处理各自的问题,避免子函数将错误抛给母函数。

------分隔线----------------------------
标签(Tag):excel excel2007 excel2010 excel2013 excel2003 excel技巧 excel教程 excel实例教程
------分隔线----------------------------
推荐内容
猜你感兴趣