为什么 On Error Goto Label 在第一次成功绕过错误后不起作用?

问题描述

目前,我在 VBA 代码中遇到了一个问题。

Option Explicit
Dim X As Integer
Dim Rng As String
 
 
Sub runtime91()
Sheet1.Select               'Select the first sheet
        
For X = 1 To 43             'Setting the loop
Rng = Sheets("Reference").Cells(153 + X,8).Value   'assigning variable for cells containing the last registration dates
If Rng = "0" Or Rng = "" Then           'Logical testing for periods with the last registration dates
Else
    On Error GoTo continue
    Cells.Find(What:=Rng,After:=Range("A1"),LookIn:=xlValues,LookAt:= _
            xlWhole,SearchOrder:=xlByRows,SearchDirection:=xlNext,MatchCase:=False _,SearchFormat:=False).Select       'Find the last registration dates based on reference datas
    If ActiveCell.Column = 1 Then
    ActiveCell.Offset(0,9).Value = ActiveCell  'Write the last registration dates
    ElseIf ActiveCell.Column = 9 Then
    ActiveCell.Offset(0,1).Value = ActiveCell  'Write the last registration dates
    End If
End If
continue:
Next
 
End Sub

代码正在从引用选项卡中的单元格 H154 到单元格 H196 进行检查。这些单元格包含日期作为字符串。如果当前单元格为空或等于 0,则转到下一次迭代。如果单元格包含日期字符串,则它会尝试在 Sheet1 选项卡中查找相应的日期。

问题是:它在第二次尝试在 Sheet1 选项卡中找不到日期时给出了运行时错误 91。 On Error Goto continue 绕过了第一次找不到日期的尝试 - 它直接进入下一次迭代。

我很困惑,因为 On Error Goto continue 只绕过错误一次,因为我预计它会绕过错误直到循环结束。

如果您需要,下面是工作表的保管箱链接

https://www.dropBox.com/scl/fi/cc83cwku0d8kk7le2j7yi/Runtime-error-91.xlsm?dl=0&rlkey=64yovaxo87wlosjgc235j6dlj

对此事的任何建议表示赞赏。

解决方法

当您只能检查返回值时,不要使用错误处理。

Dim foundCell As Range

Set foundCell = Cells.Find(What:=Rng,After:=Range("A1"),LookIn:=xlValues,_
    LookAt:=xlWhole,SearchOrder:=xlByRows,SearchDirection:=xlNext,_
    MatchCase:=False,SearchFormat:=False)

If foundCell Is Nothing Then
    ' value not found

elseIf foundCell.Column = 1 Then
    foundCell.Offset(0,9).Value = foundCell.Value  'Write the last registration dates

ElseIf foundCell.Column = 9 Then
    foundCell.Offset(0,1).Value = foundCell.Value  'Write the last registration dates

end if
,

您需要在每个错误之间重置错误处理程序:

Option Explicit

Sub errtest()
    Dim A As Integer

    On Error GoTo Continue
    A = 1 / 0                 'Will cause an error that is handled here
Continue:
    MsgBox "Took care of error"
    On Error GoTo -1        'Reset error handling
    On Error GoTo Continue2 'Set error handling
    A = 1 / 0
Continue2:
    MsgBox "Took care of error again"
    A = 1 / 0
    MsgBox "Took care of error yet another time" 'Will never be executed
End Sub

在此处阅读更多信息: https://excelmacromastery.com/vba-error-handling

,

听起来像per this MS documentation on the On Error statement;

如果在错误处理程序处于活动状态时发生错误(在错误发生和 Resume、Exit Sub、Exit Function 或 Exit Property 语句之间),则当前过程的错误处理程序无法处理该错误。

>

由于您没有以任何方式处理错误,您可能会发现使用 On Error Resume Next 代替,例如:

On Error Resume Next
'Do some loops and code here
'More code doing things
'Code doing things has finished now,onto the next task
On Error GoTo -1     'This resets the error handling

注意:此方法将忽略所有错误,而不仅仅是预期的错误,因此对于意外结果要小心。

最好的方法是,如果您预计会出现错误,请修改您的代码以检查会导致错误的条件并防止一起抛出错误。