Non c'è niente per ottenere il nome della funzione corrente, ma è possibile creare un sistema di tracciatura piuttosto leggero utilizzando il fatto che le vite degli oggetti VBA sono deterministiche. Ad esempio, è possibile avere una classe chiamata 'Tracer' con questo codice:
Private proc_ As String
Public Sub init(proc As String)
proc_ = proc
End Sub
Private Sub Class_Terminate()
If Err.Number <> 0 Then
Debug.Print "unhandled error in " & proc_
End If
End Sub
e quindi utilizzare tale classe nella routine come:
Public Sub sub1()
Dim t As Tracer: Set t = New Tracer
Call t.init("sub1")
On Error GoTo EH
Call sub2
Exit Sub
EH:
Debug.Print "handled error"
Call Err.Clear
End Sub
Public Sub sub2()
Dim t As Tracer: Set t = New Tracer
Call t.init("sub2")
Call Err.Raise(4242)
End Sub
Se si esegue 'sub1', si dovrebbe ottenere questo uscita:
unhandled error in sub2
handled error
perché l'istanza Tracer in 'sub2' stato deterministicamente distrutta quando l'errore ha causato un'uscita dalla routine.
Questo modello generale è visto molto in C++, sotto il nome "RAII", ma funziona anche bene in VBA (oltre al fastidio generale dell'uso delle classi).
EDIT:
Per affrontare il commento di David Fenton che questa è una soluzione relativamente complicata per un semplice problema, non credo che il problema è in realtà così semplice!
Sto dando per scontato che siamo tutti d'accordo sul fatto che non vogliamo dare ad ogni singola routine nel nostro programma VBA il proprio gestore di errori. (Vedi il mio ragionamento qui: VBA Error "Bubble Up")
Se alcune routine interne non hanno i loro gestori di errori, poi quando ci facciamo cattura un errore, tutto quello che sappiamo è che è accaduto nella routine con il gestore degli errori che licenziato o in una routine da qualche parte più in profondità nella pila di chiamate. Quindi il problema come ho capito è in realtà uno dei tracciamento dell'esecuzione del nostro programma. Tracciare l'inserimento di routine è ovviamente facile. Ma il tracciamento dell'uscita può essere davvero piuttosto complicato. Ad esempio, potrebbe esserci un errore che viene generato!
L'approccio RAII ci consente di utilizzare il comportamento naturale della gestione della vita degli oggetti VBA per riconoscere quando siamo usciti da una routine, tramite un 'Exit', 'End' o un errore. Il mio esempio di giocattolo ha lo scopo di illustrare il concetto.Il vero "tracciante" nel mio quadro piccolo VBA è certamente più complesso, ma fa anche di più:
Private Sub Class_Terminate()
If unhandledErr_() Then
Call debugTraceException(callID_, "Err unhandled on exit: " & fmtCurrentErr())
End If
If sendEntryExit_ Then
Select Case exitTraceStatus_
Case EXIT_UNTRACED
Call debugTraceExitImplicit(callID_)
Case EXIT_NO_RETVAL
Call debugTraceExitExplicit(callID_)
Case EXIT_WITH_RETVAL
Call debugTraceExitExplicit(callID_, retval_)
Case Else
Call debugBadAssumption(callID_, "unrecognized exit trace status")
End Select
End If
End Sub
ma il suo utilizzo è ancora piuttosto semplice, ed è pari a meno boilerplate rispetto all'approccio "EH in ogni routine" in ogni caso:
Public Function apply(functID As String, seqOfArgs)
Const PROC As String = "apply"
Dim dbg As FW_Dbg: Set dbg = mkDbg(MODL_, PROC, functID, seqOfArgs)
...
generando automaticamente il testo standard è facile, anche se in realtà ho digitarlo e poi controllare automaticamente per fare i nomi sicuri di routine/arg corrispondono come parte dei miei test.
Sì, praticamente quello che ho sempre fatto, vedere il mio post modificato. Grazie. – maxhugen