lam*_*988 5 error-handling vba program-flow
我从SO复制一段代码作为例子.子例程包含错误处理程序.是否应该为所有Subs制作错误处理程序?
Public Sub SubA()
On Error Goto ProcError
Connection.Open
Open File for Writing
SomePreciousResource.GrabIt
ProcExit:
Connection.Close
Connection = Nothing
Close File
SomePreciousResource.Release
Exit Sub
ProcError:
MsgBox Err.Description
Resume ProcExit
End Sub
Run Code Online (Sandbox Code Playgroud)
顺便说一下,如何做一个子程序内部的控制流时,代码执行遇到Exit Sub,End Sub和Resume?当它遇到诸如ProcError:执行期间的标签时,它是执行它还是跳过它?
简短的回答是:不,你不仅不需要在每个过程中都有一个错误处理程序,但实际上你通常不希望在每个过程中都有一个错误处理程序.
您将需要在最有意义的情况下执行错误处理.通常,您只需要在最高级别的过程中使用错误处理程序,即调用所有其他过程的错误处理程序; 较低级别的程序应该将问题解决到楼上,让错误"冒泡"到更高级别的程序.有时您会希望在较低级别的过程中进行一些错误处理.
更多信息,请参阅@jtolle的这两个优秀答案:
此外,互联网搜索将揭示网上有关于错误处理的整个文献.在我看来,有些是非常错误的!但如果它坚持我在前两段写的内容,那么值得考虑.
Exit Sub并且End Sub相当直观:前者停止当前Sub的执行并将控制返回到调用它的过程(或者如果该过程未被另一个过程调用则完全停止执行).后者只是对编译器的一个指示,即这个特定Sub的代码结束 - 如果执行,则End Sub表现得像Exit Sub.
Resume指定错误处理例程完成后应该发生的事情.Plain Resume返回导致错误的同一语句并尝试再次执行它.Resume Next跳过导致错误的语句,而是转到紧跟其后的语句.Resume mylabel去标签mylabel:.
如果ProcError:在执行过程中遇到像你这样的标签,那么没有什么特别的事情会发生,并且执行会转移到标签之后的下一个语句.当然在你的例子中,ProcError:永远不会直接执行(即除非出现错误),因为Exit Sub它就在它之前.
顺便说一下,ProcExit:块可能应该从一开始On Error Resume Next(即继续关闭所有内容并退出而不管任何错误),或者正如@Phydaux指出的那样On Error Goto 0(出错,停止执行),否则如果其中的某些内容触发了错误,您可能会在错误处理程序和ProcExit:代码之间进入无限的乒乓循环.
ProcExit:
On Error Resume Next ' or, alternatively, On Error Goto 0
Connection.Close
Connection = Nothing
Close File
SomePreciousResource.Release
Exit Sub
Run Code Online (Sandbox Code Playgroud)