vba 我们是否需要为每个子程序创建一个错误处理程序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6149273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do we need to create a error handler for each subroutine?
提问by lamwaiman1988
I copy a piece of code from SO as an example. The subroutine contains an error handler. Should one make an error handler for all Subs?
我从 SO 中复制了一段代码作为示例。该子例程包含一个错误处理程序。是否应该为所有订阅者创建一个错误处理程序?
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
And by the way, how does the flow of the control inside a subroutine when the code executor encounter a Exit Sub
, End Sub
and Resume
? And when it encounters a label such as ProcError:
during the execution, does it execute it, or does it skip it?
顺便说一句,当代码执行器遇到 a Exit Sub
,End Sub
和时,子程序内部的控制流程如何Resume
?而当它ProcError:
在执行过程中遇到一个标签时,它是执行它还是跳过它?
回答by Jean-Fran?ois Corbett
The short answer is: No, not only do you not needto have an error handler in each procedure, but in fact you would usually not wantan error handler in each procedure.
简短的回答是:不,您不仅不需要在每个过程中都有一个错误处理程序,而且实际上您通常不希望在每个过程中都有一个错误处理程序。
You will want to do the error handling where it makes most sense to do it. Often, you would only want an error handler in the highest-level procedure, i.e. the one that calls all the others; lower-level procedures should kick the problem upstairs and let errors "bubble up" to the higher-level procedure. Sometimes you will want some error handling in lower-level procedures.
您将希望在最有意义的地方进行错误处理。通常,您只需要最高级别过程中的错误处理程序,即调用所有其他程序的错误处理程序;较低级别的程序应该将问题踢到楼上,让错误“冒泡”到更高级别的程序。有时您需要在较低级别的过程中进行一些错误处理。
For more, I refer you to these two excellent answers by @jtolle:
有关更多信息,请参阅@jtolle 的这两个出色答案:
Also, an internet search will reveal that there is a whole literature on the web about error handling. Some of it is quite wrong, in my opinion! But if it sticks to what I wrote in the first two paragraphs, then it's worth considering.
此外,互联网搜索将显示网络上有关于错误处理的完整文献。在我看来,有些是完全错误的!但如果它坚持我在前两段中写的内容,那么就值得考虑。
Exit Sub
and End Sub
are fairly intuitive: the former stops execution of the current Sub and returns control to the procedure that called it (or stops execution entirely if the procedure was not called by another procedure). The latter is just a indication to the compiler that this where the code for this particular Sub ends -- and if executed, End Sub
behaves like Exit Sub
.
Exit Sub
并且End Sub
相当直观:前者停止执行当前 Sub 并将控制权返回给调用它的过程(如果该过程没有被另一个过程调用,则完全停止执行)。后者只是向编译器表明此特定 Sub 的代码在此处结束——如果执行,End Sub
其行为类似于Exit Sub
.
Resume
specifies what should happen next, after an error-handling routine is finished. Plain Resume
returns to the same statement that caused the error and tries to execute it again. Resume Next
skips the statement that caused the error, and instead goes to the statement immediately following it. Resume mylabel
goes to label mylabel:
.
Resume
指定在错误处理例程完成后接下来应该发生什么。PlainResume
返回到导致错误的同一语句并尝试再次执行它。Resume Next
跳过导致错误的语句,而是转到紧随其后的语句。Resume mylabel
转到标签mylabel:
。
If a label such as your ProcError:
is encoutered in the course of execution, then nothing special happens, and execution moves on to the next statement after the label. Of course in your example, ProcError:
will never get executed directly (i.e. not unless an error is raised) because there's an Exit Sub
just before it.
如果ProcError:
在执行过程中遇到诸如 your 之类的标签,则不会发生任何特殊情况,并且执行会继续执行该标签之后的下一条语句。当然,在您的示例中,ProcError:
永远不会直接执行(即除非引发错误,否则不会执行),因为Exit Sub
在它之前有一个。
By the way, the ProcExit:
block should probably start with an On Error Resume Next
(i.e. keep on closing everything and exiting regardless of any errors) or alternatively, as pointed out by @Phydaux, an On Error Goto 0
(on error, stop execution), otherwise if something in there triggers an error, you may get into an infinite ping-pong loop between the error handler and the ProcExit:
code.
顺便说一句,该ProcExit:
块可能应该以On Error Resume Next
(即继续关闭所有内容并退出而不管任何错误)或替代地,如@Phydaux 所指出的,an 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
回答by pintxo
Exit Sub will exit the subroutine immediatly like return in Java
Exit Sub 将立即退出子程序,就像 Java 中的 return
End Sub is just the marker for the end of the sub routine block like } in Java
End Sub 只是子程序块结束的标记,如 Java 中的 }
A label is simply a mark in the code wich is used to define a jump destination. In case you did not jump to the label but arrived there "regularly" the label itself will be ignored but the code after the label will be executed as if there was no label, the code in your example will be executed all the way to the Exit Sub statement as long as no error occurs. If one occures it will jump to ProcError
标签只是代码中用于定义跳转目标的标记。如果您没有跳转到标签而是“定期”到达那里,标签本身将被忽略,但标签之后的代码将被执行,就好像没有标签一样,您示例中的代码将一直执行到只要没有错误发生,就退出 Sub 语句。如果发生它会跳转到 ProcError
Resume will in this case execute ProcExit see more here
在这种情况下,简历将执行 ProcExit在这里查看更多