在Excel中debuggingVBA类中的错误

我有一个类似于这个function的模块:

MainModule

Sub Test() On Error Resume Next Dim O1 As New Class1 O1.DoSomething On Error GoTo 0 End Sub 

和一些类似的类:

1类

 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 ErrorsBreak on Unhandled Errors那么Err.Raise将停止主模块调用的执行,而不是在类中。

所以在一种情况下,我不能执行处理错误的代码,在另一种情况下,我不能debugging未处理的错误。

问题变得难以pipe理,当项目增长,主模块创build一个对象,打开一个窗体(这是另一个对象),创build更多的对象。 一些方法处理他们自己的错误,一些被devise成中止并且引起由调用者pipe理的错误。

有没有办法处理和debugging类错误?

编辑

显然我的问题还不够清楚。 我改变了标题,我会尝试一个更清晰的例子。

模块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 

1类

 Sub UnhandledCall() Debug.Print 2 / 0 End Sub Sub HandledCall() Debug.Print 3 / 0 End Sub 

testing1

设置Error Trapping = Break on Unhandled Errors并执行Test1 。 debugging器不会停止在未处理的错误2/0。 相反,它会停在O.UnhandledCall ,使得不可能知道哪一行导致错误,什么是局部variables值,堆栈等等。

TEST2

Set Error Trapping = Break in Class Module并执行Test2 。 debugging器不会停在1 / 0 ,好,因为错误被处理。 但是,即使错误在调用者函数中处理,在1/0的同一级别上,它也会在类内的3/0处停止。

悲伤的总结

所以在第一个设置中,我看不到错误在哪里,第二个设置我不能运行一个macros来处理错误。

这显然是一个简单的例子。 我正在处理的真实世界的情况是创build数十个对象,某些对象检查一些文本文件,其他对象通过COM在CAD上打开graphics,其他对象与数据库对话等的forms。如果条件不一致,我想中止表格的打开。

随着对象被创build,它们执行数千行代码,并带有数百个pipe理错误。 当他们在文件,graphics或数据库中发现不可pipe理的东西时,他们将error handling推迟给调用者,将堆栈上升到应该检测到错误的调用程序,然后执行有关它的一些事情

我希望debugging程序能够顺利地运行托pipe错误,并在违规行中出现非托pipe错误时停止运行。 相反,debugging器按照预期在模块中工作,但是在类中它可以停止所有的错误,或者不会停止,不pipe它们是否被pipe理。

例如,如果我Error Trapping = Break in Class Module设置Error Trapping = Break in Class Module所有的托pipe错误都会像Test2一样中断执行,而且我的debugging会话将永远不会结束。

而如果我设置Error Trapping = Break on Unhandled Errors那么我永远不会知道是什么触发了错误,因为debugging器将爬过所有类到第一个对象,并告诉我,这就是导致错误,如Test1

正如你已经注意到的那样,你不能通过调整IDE /debugging器设置来冒充类模块中引发的运行时错误进行现场debugging。

还有另一种方法。 定义一个项目范围的条件编译值,比如说DEBUG_MODE

VBAProject  -  Propect属性

在你的类模块的error handling程序中,使用条件编译逻辑来编程:

 Public Function FetchResults(ByVal filter As String) As Collection On Error GoTo CleanFail Dim results As Collection Set results = this.Repository.Where(filter) CleanExit: Set FetchResults = results Exit Function CleanFail: #If DEBUG_MODE = 1 Then Stop #Else Err.Raise Err.Number 'rethrows with same source and description #End If Set results = Nothing Resume CleanExit End Sub 

如果你不介意在困惑的用户上popupVBE,那么你也可以使用Debug.Assert语句在条件不满足时中断执行:

 Public Function FetchResults(ByVal filter As String) As Collection On Error GoTo CleanFail Dim results As Collection Set results = this.Repository.Where(filter) CleanExit: Set FetchResults = results Exit Function CleanFail: Debug.Assert Err.Number <> 0 ' will definitely break here Set results = Nothing Resume CleanExit End Sub