我正在尝试这段时间来处理嵌套的子之间的错误。例如:

Sub A()
    On Error GoTo errormsg

    Call B
    Call C
    Exit Sub
errormsg:
    MsgBox "Error in A", vbOKOnly, "Warning"
End Sub

Sub B()
    On Error GoTo errormsg

    Call D
    Exit Sub
errormsg:
    MsgBox "Error in B",vbOKOnly,"Warning"
End Sub

Sub C()
    On Error Goto errormsg

    '...

    Exit Sub
errormsg:
    MsgBox "Error in C",vbOKOnly,"Warning"
End Sub

Sub D()
    On Error GoTo errormsg
    '...
    Err.Raise 6 'overflow error
    '...
    Exit Sub
errormsg:
    MsgBox "Error in D",vbOKOnly,"Warning"
End Sub

好吧,如果从B(从A)调用D时发生错误,则显示ErrorD,但不显示ErrorB,也不显示ErrorA。我在做什么/理解错了吗?

在此先多谢

最佳答案

On Error GoTo [error-handler-label]告诉VBA每当方法中发生运行时错误时都跳转到指定的标签。当您使用错误处理程序时,您是在告诉VBA“一切都很好,无需炸毁所有内容,我可以处理”。因此,当Sub D运行时:



当执行到达引发错误的行时,VBA跳转到errormsg标签,您应该看到“D中的错误”消息。然后执行返回到调用方(Sub B),就运行时而言,已解决了D中引发的错误(因为您使用On Error语句告诉它“我会处理”),因此执行使用Exit Sub语句继续,然后返回Sub A以运行Sub C

如果希望运行时错误“冒泡”,则需要在错误处理子例程中重新引发它们:

Err.Raise Err.Number 'per Err.Raise specs, current Err values are reused when only the Number parameter is specified

...或者您删除Sub D中的处理程序,并决定在调用堆栈中更高级别处理它。例如,如果您除去Sub A中的所有处理程序,那么您将看到“A中的错误”,错误消息实际上是Sub D中引发的错误的消息-不幸的是,没有任何方法可以告诉调用堆栈中该错误的位置之所以发生这种情况,是因为VBA没有公开其调用堆栈。

在每个错误处理程序中重新引发错误应按以下顺序 pop 以下消息:

D 中的
  • 错误
    B
  • 中的
  • 错误
  • 中的
  • 错误
  • [并且如果您重新加入A,则如果A是您的起点,那么VBA会在这里爆炸]

  • 09-19 05:17
    查看更多