VBA:如何像具有“调试”按钮的标准错误消息一样显示错误消息?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3911973/
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
VBA: How to display an error message just like the standard error message which has a "Debug" button?
提问by Vantomex
As usual, I create an error-handler using On Error Gotostatement, there I put a few lines of cleaning codes and display the error message, but now I don't want to lose the comfortableness of the default handler which also point me to the exact line where the error has occured. How can I do that?
像往常一样,我创建了一个错误处理程序 usingOn Error Goto语句,在那里我放了几行清理代码并显示错误消息,但现在我不想失去默认处理程序的舒适性,它也将我指向确切的行发生错误的地方。我怎样才能做到这一点?
Thanks in advance.
提前致谢。
回答by Dr. belisarius
First the good news.This code does what you want (please note the "line numbers")
首先是好消息。此代码执行您想要的操作(请注意“行号”)
Sub a()
10: On Error GoTo ErrorHandler
20: DivisionByZero = 1 / 0
30: Exit Sub
ErrorHandler:
41: If Err.Number <> 0 Then
42: Msg = "Error # " & Str(Err.Number) & " was generated by " _
& Err.Source & Chr(13) & "Error Line: " & Erl & Chr(13) & Err.Description
43: MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
44: End If
50: Resume Next
60: End Sub
When it runs, the expected MsgBox is shown:
运行时,会显示预期的 MsgBox:


And now the bad news:
Line numbers are a residue of old versions of Basic. The programming environment usually took charge of inserting and updating them. In VBA and other "modern" versions, this functionality is lost.
现在坏消息是:
行号是旧版 Basic 的残余。编程环境通常负责插入和更新它们。在 VBA 和其他“现代”版本中,此功能已丢失。
However, Herethere are several alternatives for "automatically" add line numbers, saving you the tedious task of typing them ... but all of them seem more or less cumbersome ... or commercial.
然而,这里有几种“自动”添加行号的替代方法,为您节省了输入它们的繁琐任务......但所有这些都或多或少看起来很麻烦......或商业化。
HTH!
哼!
回答by Paul Haines
There is a simpler way simply disable the error handler in your error handler if it does not match the error types you are doing and resume.
如果错误处理程序与您正在执行的错误类型不匹配并恢复,则有一种更简单的方法可以简单地禁用错误处理程序中的错误处理程序。
The handler below checks agains each error type and if none are a match it returns error resume to normal VBA ie GoTo 0 and resumes the code which then tries to rerun the code and the normal error block pops up.
下面的处理程序再次检查每个错误类型,如果没有匹配项,它将错误恢复返回到正常的 VBA,即 GoTo 0 并恢复代码,然后尝试重新运行代码并弹出正常的错误块。
On Error GoTo ErrorHandler
x = 1/0
ErrorHandler:
if Err.Number = 13 then ' 13 is Type mismatch (only used as an example)
'error handling code for this
end if
If err.Number = 1004 then ' 1004 is Too Large (only used as an example)
'error handling code for this
end if
On Error GoTo 0
Resume
回答by GlennFromIowa
This answer does not address the Debug button (you'd have to design a form and use the buttons on that to do something like the method in your next question). But it does address this part:
此答案不涉及“调试”按钮(您必须设计一个表单并使用其上的按钮来执行类似于下一个问题中的方法的操作)。但它确实解决了这一部分:
now I don't want to lose the comfortableness of the default handler which also point me to the exact line where the error has occured.
现在我不想失去默认处理程序的舒适性,它也将我指向发生错误的确切行。
First, I'll assume you don't want this in production code - you want it either for debugging or for code you personally will be using. I use a compiler flag to indicate debugging; then if I'm troubleshooting a program, I can easily find the line that's causing the problem.
首先,我假设您不希望在生产代码中使用它 - 您希望它用于调试或您个人将使用的代码。我使用编译器标志来指示调试;然后,如果我正在对程序进行故障排除,我可以轻松找到导致问题的那一行。
# Const IsDebug = True
Sub ProcA()
On Error Goto ErrorHandler
' Main code of proc
ExitHere:
On Error Resume Next
' Close objects and stuff here
Exit Sub
ErrorHandler:
MsgBox Err.Number & ": " & Err.Description, , ThisWorkbook.Name & ": ProcA"
#If IsDebug Then
Stop ' Used for troubleshooting - Then press F8 to step thru code
Resume ' Resume will take you to the line that errored out
#Else
Resume ExitHere ' Exit procedure during normal running
#End If
End Sub
Note: the exception to Resumeis if the error occurs in a sub-procedure without an error handling routine, then Resumewill take you to the line in this proc that called the sub-procedure with the error. But you can still step into and through the sub-procedure, using F8until it errors out again. If the sub-procedure's too long to make even that tedious, then your sub-procedure should probably have its own error handling routine.
注意:例外情况Resume是如果错误发生在没有错误处理例程的子过程中,那么Resume将带您到这个过程中调用带有错误的子过程的行。但是您仍然可以单步执行子过程,使用F8直到它再次出错。如果子过程太长而不能使之乏味,那么您的子过程可能应该有自己的错误处理例程。
There are multiple ways to do this. Sometimes for smaller programs where I know I'm gonna be stepping through it anyway when troubleshooting, I just put these lines right after the MsgBox statement:
有多种方法可以做到这一点。有时对于较小的程序,我知道在故障排除时无论如何我都会逐步完成它,我只是将这些行放在 MsgBox 语句之后:
Resume ExitHere ' Normally exits during production
Resume ' Never will get here
Exit Sub
It will never get to the Resume statement, unless you're stepping through and set it as the next line to be executed, either by dragging the next statement pointer to that line, or by pressing CtrlF9with the cursor on that line.
它永远不会到达 Resume 语句,除非您逐步执行并将其设置为要执行的下一行,或者通过将下一个语句指针拖动到该行,或者通过CtrlF9在该行上按下光标。
Here's an article that expands on these concepts: Five tips for handling errors in VBA. Finally, if you're using VBA and haven't discovered Chip Pearson's awesome site yet, he has a page explaining Error Handling In VBA.
这是一篇扩展这些概念的文章:在 VBA 中处理错误的五个技巧。最后,如果您正在使用 VBA 并且还没有发现 Chip Pearson 很棒的网站,他有一个页面解释了VBA 中的错误处理。
回答by Hank Freeman
For Me I just wanted to see the error in my VBA application so in the function I created the below code..
对我来说,我只是想在我的 VBA 应用程序中看到错误,所以在我创建了以下代码的函数中..
Function Database_FileRpt
'-------------------------
On Error GoTo CleanFail
'-------------------------
'
' Create_DailyReport_Action and code
CleanFail:
'*************************************
MsgBox "********************" _
& vbCrLf & "Err.Number: " & Err.Number _
& vbCrLf & "Err.Description: " & Err.Description _
& vbCrLf & "Err.Source: " & Err.Source _
& vbCrLf & "********************" _
& vbCrLf & "...Exiting VBA Function: Database_FileRpt" _
& vbCrLf & "...Excel VBA Program Reset." _
, , "VBA Error Exception Raised!"
*************************************
' Note that the next line will reset the error object to 0, the variables
above are used to remember the values
' so that the same error can be re-raised
Err.Clear
' *************************************
Resume CleanExit
CleanExit:
'cleanup code , if any, goes here. runs regardless of error state.
Exit Function ' SUB or Function
End Function ' end of Database_FileRpt
' ------------------

