Как узнать, в каком модуле выполняется мой код? - PullRequest
4 голосов
/ 26 июня 2009

Очень долго, когда у меня есть обработчик ошибок, я заставляю его сообщать, в какой проект, модуль и процедуру была добавлена ​​ошибка. Я всегда выполнял это, просто сохраняя их имя через константы. Я знаю, что в классе вы получаете имя программно с помощью 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 ]

2 голосов
/ 27 июня 2009

Здесь есть несколько вопросов.

Вы можете получить имя проекта, позвонив в App.Name Вы не можете получить название метода, в котором вы находитесь. Я рекомендую использовать шаблоны автоматических процедур из MZ Tools , которые автоматически вставят все необходимые вам константы, и ваша головная боль пройдет.

Последний кусок, возможно, должен знать имя EXE (или lib), который вызвал вашу ActiveX DLL. Чтобы понять это, попробуйте следующее:

'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
2 голосов
/ 27 июня 2009

Для имени проекта я могу думать только об этом, преднамеренно выбрасывая ошибку где-нибудь в Sub Main (), и в коде обработки ошибок сохраняйте полученный Err.Source в глобальную переменную g_sProjectName. В противном случае, я помню, что существовала бесплатная сторонняя DLL-библиотека TLBINF32.DLL, которая выполняла COM-рефлексию - но это кажется слишком сложным для того, что вы хотите сделать, и в любом случае, вероятно, есть разница между публичной и приватной классы. И, наконец, вы можете использовать бинарный редактор для поиска строки имени проекта в вашем EXE-файле, а затем попытаться прочитать строку с позиции. Хотя разочаровывает, что имена каждого проекта и модуля кода встроены в EXE-файл, кажется, что не существует предсказуемого способа сделать это, поэтому это НЕ рекомендуется.

1 голос
/ 26 июня 2009

К сожалению, вам понадобятся отдельные операторы On Error GoTo X для отдельных модулей и процедур. Проект всегда хранится в Err.Source. Обработка ошибок VBA не так уж велика в этой области - в конце концов, насколько хорошо имя проекта является источником ошибки, в отличие от процедуры / модуля, не так ли?

Если вы вручную или программно нумеруете свои строки (например, BASIC старой школы), вы можете использовать ERL, чтобы перечислить номер строки, на которой произошла ошибка. Имейте в виду, однако, что ошибка, которая возникает в строке без номера, заставит ERL выдавать свою собственную ошибку вместо возврата нуля. Более подробную информацию можно найти в этом блоге .

Если вы используете 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

И Microsoft включает эти замечания:

  • Все открытые модули включены в Коллекция модулей, будь они не скомпилированы, скомпилированы, находятся в прервать режим или содержать код это работает.
  • Чтобы определить, является ли человек Модуль объекта представляет собой стандарт модуль или модуль класса, проверьте Свойство Тип объекта модуля.
  • Коллекция Модули принадлежит Объект приложения Microsoft Access.
  • Отдельные объекты модуля в Коллекция модулей проиндексирована начиная с нуля.

Пока что мне не удалось найти что-либо, ссылающееся на текущий проект или процедуру. но это должно указать вам правильное направление.

0 голосов
/ 02 июля 2009

Я предлагаю вам взглянуть на CodeSMART для VB6 . Это дополнение для VB6 имеет настраиваемый Диспетчер схем обработки ошибок , с макросами, которые вставляют строки для Имя модуля, имя метода и т. д., в ваш код обработки ошибок с одним выбором контекстного меню.

Имеет и другие очень приятные функции - поиск в файлах, который превосходит все, что я видел до ReSharper, дизайнера Tab Order, и многое другое.

У моего предыдущего работодателя мы использовали этот инструмент много лет, начиная с версии 2005 года. Как только вы к этому привыкнете, без него действительно трудно обойтись.

...