如何在 VBA 中模拟 Python 的 "continue" 语句的错误 AKA 进行下一次迭代?



在下面的代码中,在遇到错误后,如何使循环在下一次迭代(而不是下一行(继续?

现在代码不会超过 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

我已经研究了这个答案: 跳到循环 vba 中的下一次迭代,但无法将其转换为我的代码。

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

errhandler前的Exit Sub也是一种很好的做法:

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,只要b0,它就会运行。

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

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


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

此处的另一个选项是内联错误处理程序。这很明显,您知道特定代码行引发错误的可能性,并且不依赖于流控制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

如果你想跳过Error并继续下一次迭代,一种可能的方法是使用GoTo并制作一些意大利面条代码:

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检查一个if并避免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

最新更新