当函数中发生错误时,我想知道导致它的事件序列,特别是当从十几个不同的地方调用该函数时。有没有办法在VB6中检索调用堆栈,或者我是否必须以困难的方式执行它(例如,每个函数和错误处理程序中的日志条目等)?
答案 0 :(得分:11)
你必须以艰难的方式去做,但并不是所有的 都 很难......说真的,一旦你写了一次模板,它就是一个快速复制/粘贴/修改以将Err.Raise语句中的函数名称与实际函数名称匹配。
Private Function DoSomething(ByVal Arg as String)
On Error GoTo Handler
Dim ThisVar as String
Dim ThatVar as Long
' Code here to implement DoSomething...
Exit Function
Handler:
Err.Raise Err.Number, , "MiscFunctions.DoSomething: " & Err.Description
End Function
当你有嵌套调用时,这会在每个例程命中其Handler并将其名称添加到错误描述时展开。在顶级函数中,您将获得一个“调用堆栈”,其中显示了被调用的例程列表,以及实际发生的错误的错误号和描述。它并不完美,因为你没有获得行号,但我发现你通常不需要它们来找到解决问题的方法。 (如果你真的想要行号,你可以把它们放在函数中,并使用Erl变量在Err.Raise语句中引用它们。没有行号,只返回0。)
另外,请注意,在函数本身中,您可以使用消息中有趣变量的值来引发自己的错误,如下所示:
Err.Raise PCLOADLETTER_ERRNUM, , "PC Load Letter error on Printer """ & PrinterName & """"
(语法高亮显示在预览中看起来很糟糕......我想知道发布后它会是什么样子?)
答案 1 :(得分:9)
我很确定你必须以艰难的方式去做。在我以前的工作中,我们使用DCOM组件对VB6进行了非常优雅的错误处理过程。但是,必须将大量冗余代码添加到每个方法中,以至于我们使用本土工具为您插入所有这些代码。
我无法提供太多关于其实施的见解(因为我已经忘记了大部分内容并且他们有可能将其视为商业秘密)。确实突出的一点是方法名称无法在运行时派生,因此它被添加为字符串变量(一些开发人员将复制粘贴而不是使用该工具,这将导致错误堆栈的谎言。 ..)。
HTH
答案 2 :(得分:3)
艰难的手动方式几乎是唯一的方法。如果您查看this问题,有人建议使用名为MZTools的工具,它将为您完成大部分繁重的工作。
答案 3 :(得分:1)
正如其他人所说(多年前,我看到......但是有很多人还在使用VB6!:)),我认为除非你使用某些第三方工具,否则无法以编程方式检索调用堆栈。
但是如果你需要为了调试目的而这样做,你可以考虑在被调用例程中添加一个Optional输入字符串变量,你是否会把调用者的名字。
Sub MyRoutine
(...) ' Your code here
call DoSomething (Var1, Var2, Var3, "MyRoutine")
' ^
' Present routine's name -----------+
(...) ' Your code here
End Sub
Public DoSomething (DoVar1, DoVar2, DoVar3, Optional Caller as string = "[unknown]")
Debug.Print " DoSomething Routine Called. Caller = " & Caller
... ' (your code here)
End Sub
也许并不那么优雅,但它对我有用。
此致 马克斯 - 意大利
答案 4 :(得分:0)
Compuware(当时是Numega)用于Visual Basic 6的DevStudio用于执行此操作。方法是为每个调用添加指令添加一个调用添加到代码堆栈的非常小的片段。如果出现任何错误,它会抛弃该callstack,然后执行诸如邮件之类的操作或将所有的debuging信息发布到Web服务器上。添加和删除检测是一种潜在的致命操作(特别是当时我们使用VSS作为源代码控制时),但是如果它起作用,它运行良好。
作为Darrel pointed out,你可以通过使用MZTools和设置模板来添加非常类似的东西。这是很多工作,并且可能比奖励更有效但是如果你很难追踪错误,它可能会有所帮助)。