像往常一样,我使用 "On Error Goto "语句创建了一个错误处理程序,在那里我放了几行清洁代码并显示错误信息,但现在我不想失去默认处理程序的舒适性,因为它还能指出发生错误的确切行。我怎样才能做到这一点呢?
提前感谢。
首先是好消息。这段代码做了你想要的事情(请注意"行号")。
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被显示出来:
现在是坏消息:</b>; 行号是旧版本Basic的残留物。编程环境通常负责插入和更新它们。在VBA和其他"现代"版本中,这一功能已经丢失。
然而,这里有几个替代方案可以自动添加行号,省去了输入行号的繁琐工作......但所有这些方案都或多或少显得有些麻烦......或者说是商业化。
HTH!
有一个更简单的方法,只要在你的错误处理程序中禁用错误处理程序,如果它不符合你所做的错误类型,就可以恢复。
下面的处理程序再次检查每个错误类型,如果没有匹配的,则返回错误恢复到正常的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
这个答案并没有解决调试按钮的问题(你必须设计一个表单并使用上面的按钮来做类似于你下一个问题中的方法)。但它确实解决了这一部分:
现在我不想失去默认处理程序的舒适性,因为它也能让我找到发生错误的确切行。
首先,我假设你不希望在生产代码中这样做--你希望它用于调试或用于你个人将使用的代码。我使用一个编译器标志来表示调试;然后如果我在排除程序故障时,我可以很容易地找到导致问题的那一行。
# 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
注意:"恢复 "的例外情况是,如果错误发生在一个没有错误处理程序的子程序中,那么 "恢复 "将把你带到这个程序中调用出错子程序的那一行。但是你仍然可以使用F8进入并通过该子程序,直到它再次出错。如果子程序太长,甚至让人觉得乏味,那么你的子程序可能应该有自己的错误处理程序。
有多种方法可以做到这一点。有时,对于较小的程序,我知道在排除故障时,无论如何我都要通过它,我只是在MsgBox语句后面加上这些行:
Resume ExitHere ' Normally exits during production
Resume ' Never will get here
Exit Sub
它永远不会到达 "恢复 "语句,除非你把它作为下一行来执行,通过拖动下一个语句指针到该行,或者在光标位于该行时按下CtrlF9。
这里有一篇文章对这些概念进行了阐述:在VBA中处理错误的五个提示。 最后,如果你正在使用VBA并且还没有发现Chip Pearson's awesome site,他有一个页面解释了Error Handling In VBA。