gpt4 book ai didi

excel - 在 Excel 中调试 VBA 类中的错误

转载 作者:行者123 更新时间:2023-12-03 07:49:46 25 4
gpt4 key购买 nike

我有一个功能类似于此的模块:

主模块

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

1类
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 ,我的调试 session 将永远不会结束。

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

最佳答案

正如您所注意到的,您不能仅通过调整 IDE/调试器设置来找出类模块中引发的运行时错误并进行现场调试。

不过还有另一种方式。定义项目范围的条件编译值,例如 DEBUG_MODE :

VBAProject - Propect Properties

在您的类模块的错误处理程序中,使用条件编译逻辑进行编程中断:

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

如果您不介意 VBE 出现在您的困惑用户身上,那么您也可以使用 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

关于excel - 在 Excel 中调试 VBA 类中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38132790/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com