如何在错误AKA上进行下一次迭代以模拟VBA中的Python的“ continue”语句

时间:2018-10-17 14:18:35

标签: vba excel-vba

在以下代码中,如何在遇到错误后使循环在下一个迭代(而不是下一行)上继续?

现在,代码不会超过x = 0:

Sub skip_iteration()

Dim x As Long

For x = 5 To -5 Step -1
    On Error GoTo errhandler:
    Debug.Print 15 / x
    Debug.Print "I don't want this to be printed on error"
Next x

errhandler:
If Err.Number = 11 Then
    Debug.Print ("Error on " & x)
End If

End Sub

我调查了这个答案: Skip to next iteration in loop vba等,但无法将其翻译为我的代码。

3 个答案:

答案 0 :(得分:2)

您需要Resume Next转到该行之后的下一行,从而导致错误。而且Err.Clear也是一种好习惯。

Exit Sub之前的errhandler也是一个好习惯:

Sub SkipIteration()

    Dim x As Long        
    For x = 5 To -5 Step -1
        On Error GoTo errhandler:
        Debug.Print 15 / x
        Debug.Print "testing"
    Next x        
    Exit Sub

errhandler:
    If Err.Number = 11 Then
        Debug.Print ("Error on " & x)
        Err.Clear
        Resume Next
    End If    
End Sub

ResumeResume Next之间的区别如下:

  • Resume尝试返回到它的调用位置。

TestMeResume过程中,它在Debug.Print a / b上引发错误11,并在错误处理程序中为其分配b =5。然后使用Resume重试Debug.Print a / b ,并且只要b不是0,它就会运行。

  • Resume Next转到被调用的位置,忽略该行并继续下一行。

TestMeResumeNext过程中,在a = 12处引发错误91,并触发了错误处理程序。在错误处理程序中,将a分配给Range("A14"),并使用Resume Next跳过a = 12,并继续Sub


Sub TestMeResumeNext()

    On Error GoTo TestMeResumeNext_Error

    Dim a As Range
    a = 12              'Error 91 here!
    Debug.Print a.Row   'Resume Next goes back here
    Exit Sub

TestMeResumeNext_Error:
    Set a = Range("A14")
    Resume Next
End Sub

Sub TestMeResume()

    On Error GoTo TestMeResume_Error

    Dim a As Long: a = 10
    Dim b As Long: b = 0
    Debug.Print a / b   'Error 11 here the first time
    Exit Sub

TestMeResume_Error:
    b = 5
    Resume
End Sub

答案 1 :(得分:1)

这里的另一个选项是内联错误处理程序。显而易见,您已经意识到特定代码行可能引发错误,并且不依赖Resume进行流控制。将错误放到函数底部的处理程序中,然后跳回代码的主行,可以使循环的预期行为变得不那么明显。

Sub SkipIteration()
    Dim x As Long

    For x = 5 To -5 Step -1
        On Error Resume Next
        Debug.Print 15 / x
        If Err.Number = 11 Then
            Debug.Print "Expected error on " & x
            On Error GoTo errhandler
        Else
            On Error GoTo errhandler
            Debug.Print "Process the rest of the loop"
        End If
    Next x

    Exit Sub
errhandler:
    Debug.Print "Unexpected error "; Err.Number
End Sub

更好的方法是将过程的关注点分开,以使执行的循环部分是一条语句:

Sub SkipIteration()
    On Error GoTo errhandler

    Dim x As Long
    For x = 5 To -5 Step -1
        If TheThingThatCanError(x) Then
            ActionThatDependsOnAbove x
        End If
    Next x

    Exit Sub
errhandler:
    Debug.Print "Unexpected error "; Err.Number
End Sub

Private Function TheThingThatCanError(x As Long) As Boolean
    On Error Resume Next
    Debug.Print 15 / x
    If Err.Number = 11 Then
        Debug.Print "Expected error on " & x
        Exit Function
    End If
    TheThingThatCanError = True
End Function

Private Sub ActionThatDependsOnAbove(x As Long)
    Debug.Print "I don't want this to be printed on error " & x
End Sub

答案 2 :(得分:-1)

如果您想跳过Error并继续下一次迭代,则一种可能的方法是使用GoTo并进行一些spaghetti code

Sub SkipIteration()
    Dim x As Long
    For x = 5 To -5 Step -1
        If IsError(Evaluate("15 / " & x)) Then GoTo Skipper
        Debug.Print 15 / x
        Debug.Print x
Skipper:
    Next x
End Sub

或使用整个IsError嵌入检查是否要使用GoTo。但是然后您必须在右侧转到一个选项卡并丢失缩进:

Sub SkipIteration()
    Dim x As Long
    For x = 5 To -5 Step -1
        If Not IsError(Evaluate("15 / " & x)) Then
            Debug.Print 15 / x
            Debug.Print x
        End If
    Next x
End Sub