How to read the Funct/Sub name from Vba code?

amorosik

Active member
Local time
Today, 16:57
Joined
Apr 18, 2020
Messages
753
In order to implement effective error handling, it would be useful if from code you could read the name of the sub/function inside which the code is running
A sort of Me.name for forms
Then the question is: how to read, via vba, the name of the function/sub inside which the code is running?
 
Only way is to include it in your message or if using a global error handler to pass the sub/function name as a parameter when it is called
 
I don't think it's available.
If you use MZ tools to insert a generic error handler it puts the name of the sub in, but I don't know where it gets it from?
 
best guess is it can read back from the location of the call to the error handle for find the word 'sub' or 'function' and determine the name from there - perhaps using saveastext to interrogate
 
Here is a summary of a chat I had with ChatGPT:-
Unless I'm completely missing something, the second part of the summary, re VBA.CallStack, is a complete nonsense hallucination of the AI.
I would prefer if you, as a knowledgeable VBA developer yourself, would filter such hallucination from your AI digests.
 
In order to implement effective error handling, it would be useful if from code you could read the name of the sub/function inside which the code is running
A sort of Me.name for forms
Then the question is: how to read, via vba, the name of the function/sub inside which the code is running?
Coincidentally, I spent several hours recently trying to figure out a way to do exactly this. I found one elaborate workaround on Stack Overflow IIRC, which I don't think is viable for realistic use.

The alternative that does work is MZ Tools, though. Here's a screenshot of my error handler template in MZ Tools and a sample of the resulting error handler.

1732889908447.png


MZ Tools provides Predefined variables, highlighted in yellow. The one you are looking for is the one I outlined in red. Of course, it works only in an MZ Tools environment, so you'd have to buy a license.

As an aside, originally I was referring to "forms" and "controls" on forms so I used sFrm and sCtl as arguments. Over time, I realized that is not particularly accurate, but now, with hundreds of procedures all using the same error handler in multiple accdbs, correcting that is a task for my heirs.

Code:
Public Sub testit()

100       On Error GoTo errHandler
          Dim x As Integer
110       x = 1 / 0

Cleanup:
          
120       On Error Resume Next

exitProc:
          
130       Exit Sub

errHandler:
140       Call GlblErrMsg( _
              sFrm:=Application.VBE.ActiveCodePane.CodeModule, _
              sCtl:="testit" _
              )
150       Resume Cleanup
160       Resume
End Sub

Although line numbers serve no other useful purpose that I know of, they are handy in reporting the erroring line.

Here's the error message produced by testit()

1732890311030.png


I do not log errors because it's my personal database and that is superfluous to its purpose, but in a production environment, you'd want to do that.

You may find other, useful variants as well.

For a more robust implementation of error handling, download and instantiate the Northwind Developer version. It handles some error situations which this simplistic approach does not, specifically what happens when an error is raised in a procedure called from a higher level procedure.
 
Some online research shows that VBA doesn't currently have such an ability directly.

This is an example of an old principle in programming. Most of the time, what you want isn't there. If you look at the documented functions of Access & VBA, there is no way to get this information. So you have to learn to program it yourself.

The practical solution is that you have to include the name of the entry point in every routine you create, by having every routine do its own error handling to include a name. Which means that you have to customize EACH and EVERY error handler routine to include a way to log or print some message containing that name. You ALSO could include line numbers for every line of code because there is a part of the ERR object that tells you the line number containing an error. Otherwise, you have nothing on which to "hang your hat." It would also mean that if you call a subroutine that doesn't have an error handler, it becomes invisible to this approach.

Part of the underlying problem is that to do what you ask, you have to be able to actually read and manipulate arbitrary addresses taken from the hardware stack pointer. But VBA doesn't inherently have that ability. If you were a good programmer in languages such as C++ or C#, you MIGHT be able to code something that could explore the program stack for you and return something like the name of the entry point. However, the peril at THAT point is that we don't know (because Access is NOT OpenSource) what actual subroutines get called "behind the scenes" for each subroutine/function call occurring inside VBA. Nor do we know exactly how the traceback data structure is built that enables Access to know where it is at a given time.
 
Yes I know MzTools and the possibility of using its functions to create the start and end routines
I wanted to understand if it was possible to do it only from Vba code
And it seems not to be possible
 
Yes I know MzTools and the possibility of using its functions to create the start and end routines
I wanted to understand if it was possible to do it only from Vba code
And it seems not to be possible

First, you aren't the first to ask that question across the various web sites (not limited to AWF).
Second, there doesn't seem to be an easy way if you limit yourself to VBA because it doesn't have the language construct you need (a "pure" address data type plus an operator to "follow the link" of an address datatype in the abstract sense of "follow.") Which is why I suggested writing something in any C or related variant language.
 
amorosik,
Further to what others have said, with VBA I don't think it is possible to get function/sub names during program execution. Best you can probably do is get the names at design time. Tom van Stiphout discusses this in this video on Northwind 2.2.
You could write code to modify code-- that is read your source and replace any/all error handling with your desired error handler. (The NW 2.2 shows a static class module that might be useful to you for this intended purpose.)
 
In principle, it is possible to read out the function name, as it can be read out by vbWatchdog. However, you have to be a "VBA magician" to do this ;)
I only know that it is not possible with VBA.
 
In principle, it is possible to read out the function name, as it can be read out by vbWatchdog. However, you have to be a "VBA magician" to do this ;)
I only know that it is not possible with VBA.
Just to add my agreement to this point
I spent many hours trying to do this almost 10 years ago using VB Extensibility Code. In the end I admitted defeat.
Whilst I know it can be done (as both MZ-Tools and vbWatchdog have proved), I suspect both are using non-VBA methods.
 
Mz-Tools only requires the name at design time, which can be handled using vbComponent and CodeModule.
The magic starts with vbWatchdog to provide the name at runtime. ;)
 
Mz-Tools only requires the name at design time, which can be handled using vbComponent and CodeModule.
The magic starts with vbWatchdog to provide the name at runtime. ;)
FWIW, this is the code I came up with about 10 years ago to try & get the current procedure name at runtime.
I placed it in the error handler as below:

Code:
Exit_Handler:
    Exit Sub
 
Err_Handler:
    strProc = Application.VBE.ActiveCodePane.CodeModule.ProcOfLine(Application.VBE.ActiveCodePane.TopLine, 0)
    MsgBox "Error " & Err.number & " in " & strProc & " procedure : " & Err.description
    Resume Exit_Handler

End Sub

This always returned the name of a procedure in that code module and often it was the currently running procedure
However, it wasn't reliable.
For example, sometimes it was the previous procedure or more often, the first procedure in that code module
 

Users who are viewing this thread

Back
Top Bottom