VBA在代码执行期间更改错误处理方法

时间:2017-08-02 12:36:51

标签: excel vba

我有一个宏,部分代码涉及: 1)检测列是否包含空单元格 - 如果是,则填充一些值 2)检测列是否包含包含错误的单元格(例如N / A),如果是,则填充某些值

现在,如果列中没有错误/空单元格,找到它们的行会出现"运行时错误1004,找不到单元格"。

我使用错误处理来跳过GoTo。

下面是代码 - 第一个错误处理GoTo完美地工作,而第二个错误处理Goful预期错误,虽然有错误处理GoTo设置,似乎不起作用。带注释的代码:

On Error GoTo EErrorOne


'depending on file I get, below line will generate error and code successfully skips to ErrorOne label

Workbooks(nazwawb).Sheets(szitnr).Columns(ktorepole).SpecialCells (xlCellTypeBlanks)

' code to be skipped

    Workbooks(nazwawb).Sheets(szitnr).Columns(ktorepole).Select
    Selection.SpecialCells(xlCellTypeBlanks).Select
    Selection.Value = "Some Value"

' end of code to be skipped

EErrorOne:

' successfully skipped error line by now. Below line should set a new Error handling procedure.

On Error GoTo EErrorTwo



Workbooks(nazwawb).Sheets(szitnr).Columns(ktorepole).Select

' Below line generates an error but does not skip to EErrorTwo label as detailed in the current Error handling procedure

Selection.SpecialCells(xlCellTypeFormulas, 16).Select   

' code to be skipped


Selection.SpecialCells(xlCellTypeFormulas, 16).Select
    Selection.Value = "Some Value"

' end of code to be skipped


EErrorTwo:



' Below line should reset error handling procedure to normal for subsequent handling of other errors:
On Error GoTo 0

似乎忽略了错误处理过程(GoTo特定标签),而是显示错误消息,好像错误处理已重置为GoTo 0.如何跳过第二个错误?

2 个答案:

答案 0 :(得分:6)

发生错误时,您不会清除错误,只是试图跳过它们,代码就会想知道错误发生了什么。

Chip Pearson在他的网站上说:

  

当引发第一个错误时,执行转移到该行   跟随Err1:错误处理程序在第二个时仍然有效   发生错误,因此On不会捕获第二个错误   错误陈述

并继续

  

Resume语句指示VBA在指定的位置继续执行   在代码中指出。您只能在错误处理中使用Resume   块;任何其他用途都会导致错误。而且,Resume是唯一的   方式,除了退出程序,退出错误处理   块。不要使用Goto语句来引导代码执行   错误处理块。这样做会导致奇怪的问题   错误处理程序。   http://www.cpearson.com/excel/errorhandling.htm

理想的方法是首先避免错误 - 在打开工作簿之前检查它是否存在,在尝试引用它之前检查工作簿中是否存在工作表以及是否发生错误跳出例程的主体,处理错误,然后再次跳回来。

举个例子:

Sub Test()

    On Error GoTo ERR_HANDLE

    '.... code ....

FAST_EXIT:
    'Code to tidy up, clear references etc before finishing.

Exit Sub

ERR_HANDLE:
    Select Case Err.Number
        Case 1004
            'Code to resolve error
            '.
            '.
            'Resume - clear error, jump back to line that caused it.
            'Resume Next - clear error, jump to line after the one that caused error.
            'Resume FAST_EXIT - clear error and go to line label.

        Case 92 'Do something else to resolve error.

        Case Else
    End Select

End Sub

答案 1 :(得分:2)

在内部错误处理例程中,似乎定义新的错误处理例程将不起作用,除非您清除先前设置的错误例程(https://excelmacromastery.com/vba-error-handling/):

'...
EErrorOne:
On Error GoTo -1 'Clears error trap flag
On Error GoTo EErrorTwo 'Reset error handling
'...

接受后修改:
正如评论中所讨论的那样,On Error GoTo -1会清除错误陷阱标记,而Err.Clear只会清除错误。
下面的代码通过创建两个错误并尝试捕获它们来说明这一点。

On Error Goto -1允许On Error GoTo NextLabel行捕获第二个错误,并在发生错误时代码跳转到标签。
Err.Clear保持第一个错误,所以当第二个错误发生时,会显示错误消息,而不是代码跳转到标签。

Sub ClearErr()

    Dim x As Long
    Dim y As Worksheet

    'Jump to label when "Division by 0" occurs.
    On Error GoTo ErrorLabel

    x = 1 / 0
    Debug.Print x

ErrorLabel:

    'On Error GoTo -1 'Next error is trapped.
    Err.Clear   'Untrapped error on y=Worksheets(1)

    'Jump to label when "Object Variable not set" occurs.
    On Error GoTo NextLabel

    y = Worksheets(1)
    Debug.Print y.Name

NextLabel:

End Sub