I am currently maintaining some code, which is likely to be refactored soon. Before that happens, I want to make the standard error handling code, which is injected by an Add-In, more efficient and take up less space. One thing that annoys me is that every module has a constant called m_ksModuleName
that is used to construct a big string, which is then rethrown from the error handler so we can trace the error stack. This is all template code, i.e., repetitive, but I could easily strip it down to a procedure call. Now, I have fixed the code so tha开发者_如何学Pythont you can pass the Me reference to the procedure - but you can't do that for the BAS modules. Nor can you access the project name (the part which would be passed as part of a ProgramID, for instance) - although you get given it when you raise an error yourself.
All these strings are contained in the EXE, DLL or OCX - believe me, I've used a debugger to find them. But how can I access these in code?
AFAIK there's no way to get the name of a BAS module in code. The usual solution is to use a module-level constant as in Mike's answer.
AFAIK the only way to get the ProgID (programmatic ID, Project Name in project properties dialog) is to raise an error in a BAS module, trap it, and read the Err.Source
.
It's all quite a hassle, and that's why we don't usually bother including the module name or the ProgID in our standard error handlers. We "roll our own" call stack, with the names of the routines. That's always enough information to find out which modules are involved. Routines in BAS modules usually have unique names, right?
Something like this, and you can add this automatically with the free MZTools VB6 add-in.
Sub / Function whatever
On Error Goto Handler
do some stuff
Exit Sub / Function
Handler:
Err.Raise Err.Number, "(function_name)->" & Err.source, Err.Description
End Sub
Every top-level routine in a DLL or OCX has a similar error handler but also includes App.ExeName
so we can tell when errors cross component boundaries.
I'm not sure of an easy way to programmatically get the name of the module that you are in. The usual solution is to set a variable at the top of each method to the name of the module, and then it is available to the error handler for use in logging:
'In MyModule.bas'
Public Sub Foo()
Const MODULE_NAME As String = "MyModule"
On Error GoTo ErrorHandler
' Code here '
Exit Sub
ErrorHandler:
LogError Err.Number, Err.Description, MODULE_NAME
End Sub
If you are using an add-in such as MZTools, you have it generate this boilerplate code for you.
As for getting the current component name, you can access this using App.EXEName
(despite the name, this works for other project types such as DLL's). This value is pulled from the Project Name field in the project's properties (Project -> Properties) when running in the IDE, and from the name of the compiled binary file (minus the file extension) when running outside the IDE.
精彩评论