简体   繁体   English

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

[英]How can I tell what module my code is executing in?

For a very long time, when I have an error handler I make it report what Project, Module, and Procedure the error was thrown in. I have always accomplished this by simply storing their name via constants. 很长一段时间,当我有一个错误处理程序时,我会报告错误所引发的项目,模块和过程。我总是通过简单地通过常量存储它们来完成它。 I know that in a Class you get the name programmatically with TypeName(Me), but obviously that only gets me one out of three pieces of information and only when I'm not in a "Standard" module. 我知道在一个类中,你可以通过TypeName(Me)以编程方式获得名称,但很明显,只有当我不在“标准”模块中时才能获得三条信息中的一条。

I don't have a really huge problem with using constants, it's just that people don't always keep them up to date, or worse they copy and paste and then you have the wrong name being reported, etc. So what I would like to do is figure out a way to get rid of the Constants shown in the example, without losing the information. 使用常量我没有一个非常大的问题,只是人们并不总是让它们保持最新状态,或者更糟糕的是它们复制和粘贴然后你报告了错误的名称,等等。所以我想要的是什么要做的是找出摆脱示例中显示的常量的方法,而不会丢失信息。

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

Does anyone know ways to for the code to tell where it is? 有没有人知道如何让代码告诉它在哪里? If you can conclusively show it can't be done, that's an answer too:) 如果你能最终证明它无法完成,那也是一个答案:)

Edit: 编辑:
I am also aware that the project name is in Err.Source. 我也知道项目名称在Err.Source中。 I was hoping to be able to get it without an exception for other purposes. 我希望能够在没有例外的情况下获得它用于其他目的。 If you know great, if not we can define that as outside the scope of the question. 如果你知道的很好,如果不是,我们可以将其定义为问题的范围之外。
I am also aware of how to get the error line, but that information is of course only somewhat helpful without knowing Module.Procedure. 我也知道如何获取错误行,但是在不知道Module.Procedure的情况下,该信息当然只是有些帮助。

There are several questions here. 这里有几个问题。

You can get the Project Name by calling App.Name You cannot get the name of the method you are in. I recommend using the automated procedure templates from MZ Tools , which will automatically put in all the constants you need and your headache will be over. 您可以通过调用App.Name获取项目名称您无法获取所在方法的名称。我建议使用MZ Tools中的自动程序模板,它将自动输入您需要的所有常量,您的头痛将会结束。

The last piece is possibly having to know the name of the EXE (or lib) that invoked your ActiveX DLL. 最后一部分可能必须知道调用ActiveX DLL的EXE(或lib)的名称。 To figure this out, try the following: 要弄清楚这一点,请尝试以下方法:

'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

For the project name, the only way I can think of doing this is by deliberately throwing an error somewhere in Sub Main(), and in the error handling code, save the resulting Err.Source into an global variable g_sProjectName. 对于项目名称,我能想到的唯一方法是在Sub Main()中故意抛出错误,并在错误处理代码中将生成的Err.Source保存到全局变量g_sProjectName中。 Otherwise, I seem to remember that there was a free 3rd party DLL called TLBINF32.DLL which did COM reflection - but that seems way over the top for what you want to do, and in any case there is probably a difference between public and private classes. 否则,我似乎记得有一个名为TLBINF32.DLL的免费第三方DLL,它做了COM反射 - 但这似乎超出了你想要做的事情,无论如何,公共和私人之间可能存在差异。类。 And finally, you could use a binary editor to search for the project name string in your EXE, and then try to read the string from the position. 最后,您可以使用二进制编辑器在EXE中搜索项目名称字符串,然后尝试从该位置读取字符串。 Whilst it is frustrating that the names of every project and code module is embedded in the EXE, there seems to be no predictable way of doing this, so it is NOT recommended. 虽然令人沮丧的是每个项目和代码模块的名称都嵌入在EXE中,但似乎没有可预测的方法,因此不建议这样做。

Unfortunately, you'll need to have individual On Error GoTo X statements for individual modules and procedures. 不幸的是,您需要为各个模块和过程提供单独的On Error GoTo X语句。 The project is always stored in Err.Source . 该项目始终存储在Err.Source The VBA error handling isn't all that great in this area -- after all, how much good does the project name as the source of the error, as opposed to procedure/module, do you. VBA错误处理在这个领域并不是那么好 - 毕竟,项目名称作为错误的来源有多好,而不是程序/模块。

If you manually or programatically number your lines (like old-school BASIC), you can use ERL to list the line number the error occurred on. 如果您手动或以编程方式对行进行编号(如旧式BASIC),则可以使用ERL列出发生错误的行号。 Be warned, though, that an error that occurs on a line without a number will make ERL throw its own error, instead of returning a zero. 但是要注意,在没有数字的行上发生的错误会使ERL抛出自己的错误,而不是返回零。 More information can be found at this blog post . 更多信息可以在这篇博客文章中找到。

If you're using Access 2007 (not sure about other Office apps/versions), try this code snippet dug out of the help documentation: 如果您使用的是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

And Microsoft includes these remarks: 微软包括以下这些评论:

  • All open modules are included in the Modules collection, whether they are uncompiled, are compiled, are in break mode, or contain the code that's running. 所有打开的模块都包含在Modules集合中,无论它们是未编译的,是否已编译,处于中断模式,还是包含正在运行的代码。
  • To determine whether an individual Module object represents a standard module or a class module, check the Module object's Type property. 要确定单个Module对象是表示标准模块还是类模块,请检查Module对象的Type属性。
  • The Modules collection belongs to the Microsoft Access Application object. Modules集合属于Microsoft Access Application对象。
  • Individual Module objects in the Modules collection are indexed beginning with zero. 模块集合中的单个模块对象从零开始编制索引。

So far, I haven't been able to find anything on referencing the current Project or Procedure. 到目前为止,我还没有找到任何关于引用当前项目或程序的内容。 but this should point you in the right direction. 但这应该指向正确的方向。

I suggest you take a look at CodeSMART for VB6 , This VB6 addin has a customizable Error Handling Schemes Manager , with macros that will insert strings for module name, method name, etc., into your error handling code with a single context menu selection. 我建议你看看CodeSMART for VB6 ,这个VB6插件有一个可自定义的 错误处理方案管理器 ,带有将模块名称,方法名称等字符串插入到错误处理代码中的宏,只需一个上下文菜单选项。

Has some other very nice features as well - a Find In Files search that's superior to anything I'd seen till ReSharper, a Tab Order designer, and much more. 还有一些其他非常好的功能 - Find In Files搜索优于我见过的任何东西,直到ReSharper,Tab Order设计师等等。

At my previous employer, we used this tool for many years, starting with the 2005 version. 在我以前的雇主,我们使用这个工具多年,从2005版本开始。 Once you get used to it,it's really hard to do without it. 一旦你习惯了它,没有它就很难做到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM