Как узнать, в каком модуле выполняется мой код?
Очень долго, когда у меня есть обработчик ошибок, я заставляю его сообщать, в какой проект, модуль и процедуру была добавлена ошибка. Я всегда выполнял это, просто сохраняя их имя через константы. Я знаю, что в классе вы получаете имя программным способом с помощью 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 ответа
Что касается имени проекта, я могу думать только об этом, преднамеренно выбрасывая ошибку где-нибудь в Sub Main(), а в коде обработки ошибок сохраняйте полученный Err.Source в глобальную переменную g_sProjectName. В противном случае, мне кажется, что я помню, что была бесплатная сторонняя DLL-библиотека TLBINF32.DLL, которая отражала COM - но это, кажется, слишком для того, что вы хотите сделать, и в любом случае, вероятно, есть разница между публичной и приватной классы. И, наконец, вы можете использовать бинарный редактор для поиска строки имени проекта в вашем EXE, а затем попытаться прочитать строку с позиции. Хотя разочарование вызывает то, что имена каждого проекта и модуля кода встроены в EXE-файл, кажется, что не существует предсказуемого способа сделать это, поэтому это НЕ рекомендуется.
Здесь есть несколько вопросов.
Вы можете получить имя проекта, вызвав 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
К сожалению, вам нужно иметь индивидуальный 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 включает эти замечания:
- Все открытые модули включены в коллекцию модулей, независимо от того, являются ли они некомпилированными, скомпилированы, находятся в режиме прерывания или содержат код, который выполняется.
- Чтобы определить, представляет ли отдельный объект Module стандартный модуль или модуль класса, проверьте свойство Type объекта Module.
- Коллекция модулей принадлежит объекту приложения Microsoft Access.
- Отдельные объекты модуля в коллекции модулей индексируются, начиная с нуля.
До сих пор я не смог ничего найти по ссылкам на текущий проект или процедуру. но это должно указать вам в правильном направлении.
Я предлагаю вам взглянуть на CodeSMART для VB6. Это дополнение для VB6 имеет настраиваемый диспетчер схем обработки ошибок, с макросами, которые вставляют строки для имени модуля, имени метода и т. Д. В код обработки ошибок с помощью одного выбора контекстного меню.
Имеет и другие очень приятные функции - поиск в файлах, который превосходит все, что я видел до ReSharper, дизайнера Tab Order и многое другое.
У моего предыдущего работодателя мы использовали этот инструмент много лет, начиная с версии 2005 года. Как только вы к этому привыкнете, без этого действительно трудно обойтись.