VBA:如何显示错误消息,就像具有“调试”按钮的标准错误消息一样?

时间:2010-10-12 05:43:33

标签: excel vba scripting excel-vba ms-office

像往常一样,我使用On Error Goto语句创建一个错误处理程序,在那里我放了几行清理代码并显示错误信息,但现在我不想失去默认处理程序的舒适度这也指向了发生错误的确切行。我怎么能这样做?

提前致谢。

4 个答案:

答案 0 :(得分:43)

首先是好消息。此代码可以满足您的需求(请注意“行号”)

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

运行时,会显示预期的MsgBox:

alt text

现在是坏消息:
行号是旧版Basic的残留。编程环境通常负责插入和更新它们。在VBA和其他“现代”版本中,此功能丢失了。

然而,Here有几种“自动”添加行号的替代方案,为您省去了输入它们的繁琐工作......但所有这些都或多或少都很麻烦......或商业化。

HTH!

答案 1 :(得分:1)

如果错误处理程序与您正在执行和恢复的错误类型不匹配,则可以通过简单的方法在错误处理程序中禁用错误​​处理程序。

下面的处理程序再次检查每个错误类型,如果没有匹配,则将错误恢复返回到正常的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

答案 2 :(得分:0)

这个答案没有解决调试按钮(您必须设计一个表单并使用其上的按钮来执行next question中的方法)。但它确实解决了这一部分:

  

现在我不想失去默认处理程序的舒适度,它也指向了发生错误的确切行。

首先,我假设您不希望在生产代码中使用它 - 您希望它用于调试或您个人将要使用的代码。我使用编译器标志来指示调试;那么如果我正在对程序进行故障排除,我可以很容易地找到导致问题的那一行。

# 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

注意:Resume的例外情况是如果在没有错误处理例程的子过程中发生错误,那么Resume将带您到此proc中调用子过程的行有错误。但你仍然可以使用 F8 逐步进入子程序,直到它再次出错。如果子程序太长而不能使那个繁琐,那么你的子程序应该有自己的错误处理程序。

有多种方法可以做到这一点。有时对于较小的程序,我知道在进行故障排除时无论如何都会逐步完成它,我只是将这些行放在MsgBox语句之后:

    Resume ExitHere         ' Normally exits during production
    Resume                  ' Never will get here
Exit Sub

它永远不会进入Resume语句,除非您通过将下一个语句指针拖到该行或者按 Ctrl F9 ,光标在该行上。

这篇文章扩展了这些概念:Five tips for handling errors in VBA。最后,如果您正在使用VBA并且还没有发现Chip Pearson的网站,那么他会有一个页面解释Error Handling In VBA

答案 3 :(得分:0)

 

对于我,我只是想看看我的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

' ------------------