2009-06-26 58 views
3

很长一段时间,当我有一个错误处理程序时,我会报告项目,模块和过程错误是在哪里引发的。我总是通过简单地通过常量存储它们的名称来完成此任务。我知道在一个类中,你可以通过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的情况下才会有所帮助。

+0

所有在此线程的答案是好的,探索有效的技术,虽然没有真的让我到哪里,我试图去。我接受了我所做的一个,因为它最接近完成我正在尝试做的事情,并且有人应该得到要点。 – Oorang 2009-10-06 14:02:12

回答

2

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

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 

而微软包括以下言论:

  • 所有打开的模块都包含在 模块集合中,无论它们是 未编译,编译,处于中断模式的 还是包含运行的代码 。
  • 要确定单个模块对象是代表标准 模块还是类模块,请检查模块对象的类型属性 。
  • Modules集合属于 Microsoft Access应用程序对象。
  • 模块集合中的单个模块对象索引为 ,从0开始。

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

+0

你好,我很抱歉,我应该在我问的问题上更具体。我编辑了主要问题,试图缩小范围。 + +1) – Oorang 2009-06-26 18:55:06

+0

添加的信息应该有所帮助,即使它只是根据模块提供粒度。 – 2009-06-26 19:48:11

+0

On Access和VBIDE等...这是一个很好的想法,但它不会告诉你你在代码中的位置:)此外,VBIDE带有AV行李。 – Oorang 2009-06-26 20:10:46

2

这里有几个问题。

您可以通过调用App.Name 你不能让你在方法的名字。我建议使用从MZ Tools自动程序模板,会自动把你需要的所有常量并获得项目名称您头痛将结束。

最后一块可能是不必知道你的调用DLL的ActiveX 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 
0

我建议你看一看CodeSMART for VB6,这VB6插件具有定制错误处理方案经理,与宏将插入模块的名称,方法名等字符串,到你的错误处理代码一个上下文菜单选择。

具有其他的一些很不错的功能,以及 - 一个在文件中查找搜索这是超越任何我见过,直到ReSharper的,Tab键顺序设计师,等等。

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

相关问题