【发布时间】:2016-11-03 02:53:57
【问题描述】:
我有一个功能类似于此的模块:
主模块
Sub Test()
On Error Resume Next
Dim O1 As New Class1
O1.DoSomething
On Error GoTo 0
End Sub
还有一些类似的类:
Class1
Sub DoSomething()
FindStuff
'create similar objects who perform similar operations and raise similar errors
Dim O2 As New Class2
O2.DoSomething
End Sub
Function FindStuff() As Stuff
'scan the WorkBook, the file system, etc. and organize the members of the object
If CorruptedFileSystem Then Err.Raise 514, "File system corrupted"
If CorruptedWorkBook Then Err.Raise 515, "WorkBook corrupted"
If Found Then Set FindStuff = FoundStuff
End Function
如果我将错误捕获设置为Break in Class Module,那么On Error Resume Next 将被忽略,每个Err.Raise 都会停止类内的执行。
如果我将错误捕获设置为Break on Unhandled Errors,那么Err.Raise 将在主模块调用时停止执行,而不是在类内部。
所以在一种情况下我无法执行带有已处理错误的代码,在另一种情况下我无法调试未处理的错误。
当项目增长并且主模块创建一个对象,该对象打开一个创建更多对象的表单(这是另一个对象)时,问题变得难以管理。一些方法处理它们自己的错误,而另一些方法旨在中止并引发由调用者管理的错误。
有没有办法处理和调试类中的错误?
编辑
显然我的问题不够清楚。我更改了标题,我将尝试一个更清晰的示例。
模块1
Sub Test1()
Dim O As New Class1
O.UnhandledCall
End Sub
Sub Test2()
On Error Resume Next
Debug.Print 1 / 0
Dim O As New Class1
O.HandledCall
On Error GoTo 0
End Sub
Class1
Sub UnhandledCall()
Debug.Print 2 / 0
End Sub
Sub HandledCall()
Debug.Print 3 / 0
End Sub
测试1
设置Error Trapping = Break on Unhandled Errors 并执行Test1。调试器不会在未处理的错误2 / 0 处停止。相反,它将停在O.UnhandledCall,因此无法知道是哪一行导致了错误、局部变量值是什么、堆栈等。
测试2
设置Error Trapping = Break in Class Module 并执行Test2。调试器不会停在1 / 0,很好,因为错误已被处理。但是即使在调用函数内部处理了错误,它也会在类内部的3 / 0处停止,与1 / 0处于同一级别。
悲伤的总结
所以第一个设置我看不到哪里出现错误,第二个设置我不能运行一个干净地处理错误的宏。
这显然是一个过于简单的例子。我现在处理的真实世界案例是一个创建数十个对象的表单,一些对象检查一些文本文件,其他对象通过 COM 在 CAD 上打开图形,其他对象与数据库通信等。如果有任何一个条件不一致我想中止表单打开。
创建对象时,它们会执行数千行代码,其中包含数百个托管错误。当他们在文件、绘图或数据库中发现无法管理的内容时,他们会将错误处理推迟给调用者,将堆栈向上爬到应该无法打开的表单和应该检测到错误并执行的调用者关于它。
我希望调试器在托管错误中顺利运行,并在违规行出现非托管错误时停止。相反,调试器在模块中按预期工作,但在类中它要么停止所有错误,要么永远不会停止,无论它们是否被管理。
例如,如果我设置Error Trapping = Break in Class Module,所有托管错误都会像Test2 一样中断执行,并且我的调试会话将永远不会结束。
如果我设置了Error Trapping = Break on Unhandled Errors,那么我永远不会知道是什么触发了错误,因为调试器会爬过所有类直到第一个对象并告诉我这是导致错误的行,如Test1 .
【问题讨论】:
-
你为什么会有如此详尽的错误处理被如此广泛的
On Error Resume Next括起来? -
我不明白你的问题
-
On Error Resume Next抑制错误并让代码愉快地继续运行,违背了结构化错误处理的目的。您的顶级调用者应该有自己的On Error GoTo CleanFail或其他东西,以处理在调用堆栈中冒泡到该点的任何错误。 -
我同意你的观点,但我仍然不明白你的评论。你说的和我说的有什么区别?您是在谈论
CleanFail和0之间的区别吗?它们只是做同一件事的两种方法,不会改变我的问题的重点。我本可以添加一些关于如何管理故障的详细信息,但这与调试器处理已处理或未处理错误的行为方式无关。 -
有两个不同的评论者。考虑像@Doug Glancy 一样通知您已回复的人。除此之外,您还坚持自己目前的思维方式,祝您好运!
标签: excel vba debugging error-handling