VBA在代码执行期间更改error handling方法

我有一个macros,代码的一部分是关心:1)检测列是否包含空单元格 – 如果这样填充它们的某些值2)检测列是否包含单元格包含错误(如N / A),如果所以填补了一些价值

现在,如果列中没有错误/空单元格,find它们的行会出现“运行时错误1004未find单元格”。

我使用error handling来跳过这与GoTo。

下面是代码 – 第一个error handlingGoTo完美的工作,而第二个error handling,虽然有error handlingGoTo设置,似乎并没有工作。 代码与评论:

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 

看起来,error handling程序(GoTo特定标签)被忽略,而是显示错误消息,就好像error handling被重置为GoTo 0.如何跳过第二个错误?

在内部error handling例程中,似乎定义新的error handling例程将不起作用,除非您清除之前设置的错误例程( 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只清除错误。
下面的代码通过创build两个错误并试图捕获它们来说明这一点。

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 

在发生错误时,您不会清除错误,只是想跳过它们,代码想知道错误是怎么回事。

正如Chip Pearson在他的网站上所说:

当第一个错误发生时,执行转移到Err1之后的行。 发生第二个错误时,error handling程序仍处于活动状态,因此第二个错误不会由On Error语句捕获

并继续

Resume语句指示VBA在代码中的指定点恢复执行。 只能在error handling块中使用Resume; 任何其他用途都会导致错误。 而且,除了退出程序之外,恢复是除error handling块外的唯一方法。 不要使用Goto语句将代码执行导出error handling块。 这样做会导致error handling程序奇怪的问题。 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