如何判断我的代码执行的模块是什么?

时间:2009-06-26 18:35:32

标签: vba com vb6 error-handling documentation-generation

很长一段时间,当我有一个错误处理程序时,我会报告错误所引发的项目,模块和过程。我总是通过简单地通过常量存储它们来完成它。我知道在一个类中,你可以通过TypeName(Me)以编程方式获得名称,但很明显,只有当我不在“标准”模块中时才能获得三条信息中的一条。

使用常量我没有一个非常大的问题,只是人们并不总是让它们保持最新状态,或者更糟糕的是它们复制和粘贴然后你报告了错误的名称,等等。所以我想要的是什么要做的就是找出摆脱示例中显示的常量的方法,而不会丢失信息。

Option Compare Binary
Option Explicit
Option Base 0
Option Private Module

Private Const m_strModuleName_c As String = "MyModule"

Private Sub Example()
    Const strProcedureName_c As String = "Example"
    On Error GoTo Err_Hnd
Exit_Proc:
    On Error Resume Next
    Exit Sub
Err_Hnd:
    ErrorHandler.FormattedErrorMessage strProcedureName_c, m_strModuleName_c, _
        Err.Description, Err.Source, Err.Number, Erl
    Resume Exit_Proc
End Sub

有没有人知道如何让代码告诉它在哪里?如果你能最终证明不能完成,那也是一个答案:)

编辑:
我也知道项目名称在Err.Source中。我希望能够在没有例外的情况下获得它用于其他目的。如果你知道的很好,如果不是,我们可以将其定义为问题的范围之外 我也知道如何获取错误行,但是在不知道Module.Procedure的情况下,这些信息当然有点帮助。

4 个答案:

答案 0 :(得分:2)

这里有几个问题。

您可以通过调用App.Name获取项目名称 你无法得到你所使用的方法的名称。我建议使用MZ Tools中的自动程序模板,它会自动输入你需要的所有常数,你的头痛就会结束。

最后一篇文章可能必须知道调用ActiveX DLL的EXE(或lib)的名称。要解决这个问题,请尝试以下方法:

'API Declarations'
Private Declare Function GetModuleFileName Lib _
    "kernel32" Alias "GetModuleFileNameA" (ByVal _
    hModule As Long, ByVal lpFileName As String, _
    ByVal nSize As Long) As Long

Private Function WhosYourDaddy() As String
    Dim AppPath As String
    Const MAX_PATH = 260

    On Error Resume Next

    'allocate space for the string'
    AppPath = Space$(MAX_PATH)

    If GetModuleFileName(0, AppPath, Len(AppPath)) Then
        'Remove NULLs from the result'
        AppPath = Left$(AppPath, InStr(AppPath, vbNullChar) - 1)
        WhosYourDaddy = AppPath
    Else
        WhosYourDaddy = "Not Found"
    End If
End Function

答案 1 :(得分:2)

对于项目名称,我能想到的唯一方法是在Sub Main()中故意抛出错误,并在错误处理代码中将生成的Err.Source保存到全局变量g_sProjectName中。否则,我似乎记得有一个名为TLBINF32.DLL的免费第三方DLL,它做了COM反射 - 但这似乎超出了你想要做的事情,无论如何,公共和私人之间可能存在差异。类。最后,您可以使用二进制编辑器在EXE中搜索项目名称字符串,然后尝试从该位置读取字符串。虽然令人沮丧的是每个项目和代码模块的名称都嵌入在EXE中,但似乎没有可预测的方法,所以不建议这样做。

答案 2 :(得分:1)

不幸的是,您需要为单个模块和过程提供单独的On Error GoTo X语句。该项目始终存储在Err.Source中。 VBA错误处理在这方面并不是那么好 - 毕竟,项目名称作为错误的来源有多好,而不是程序/模块,你呢。

如果您手动或以编程方式对行进行编号(如旧式BASIC),则可以使用ERL列出发生错误的行号。但是要注意,在没有数字的行上发生的错误会使ERL抛出自己的错误,而不是返回零。可以找到更多信息at this blog post

如果您使用的是Access 2007(不确定其他Office应用程序/版本),请尝试从帮助文档中挖掘出此代码段:

Sub PrintOpenModuleNames()
    Dim i As Integer
    Dim modOpenModules As Modules

    Set modOpenModules = Application.Modules

    For i = 0 To modOpenModules.Count - 1

        Debug.Print modOpenModules(i).Name

    Next
End Sub

微软包含以下评论:

  • 所有打开的模块都包含在 模块集合,无论它们是什么 未编译,编译,都在 中断模式,或包含代码 正在运行。
  • 确定是否是个人 模块对象代表一个标准 模块或类模块,检查 模块对象的Type属性。
  • Modules集合属于 Microsoft Access Application对象。
  • 中的单个模块对象 模块集合已编制索引 从零开始。

到目前为止,我还没有找到任何关于引用当前项目或程序的内容。但这应该指向正确的方向。

答案 3 :(得分:0)

我建议你看一下CodeSMART for VB6,这个VB6插件有一个可自定义的 错误处理方案管理器,其宏将插入模块名称的字符串,方法名称等,使用单个上下文菜单选择进入错误处理代码。

还有其他一些非常好的功能 - Find In Files搜索优于我见过的任何东西,直到ReSharper,Tab Order设计师等等。

在我以前的雇主,我们使用这个工具多年,从2005版本开始。一旦你习惯了它,没有它就很难做到。