2009-06-26 12 views
3

Für eine sehr lange Zeit, wenn ich einen Fehler-Handler habe ich es berichten, welche Projekt, Modul und Prozedur der Fehler geworfen wurde. Ich habe dies immer erreicht, indem Sie einfach ihren Namen über Konstanten gespeichert. Ich weiß, dass Sie in einer Klasse den Namen programmgesteuert mit TypeName (Me) erhalten, aber das bringt mir offensichtlich nur eine von drei Informationen und nur, wenn ich nicht in einem "Standard" -Modul bin.Wie kann ich feststellen, in welchem ​​Modul mein Code ausgeführt wird?

Ich habe kein wirklich großes Problem mit der Verwendung von Konstanten, es ist nur, dass Menschen sie nicht immer auf dem neuesten Stand halten, oder schlimmer, sie kopieren und einfügen und dann haben Sie den falschen Namen gemeldet usw. Also möchte ich einen Weg finden, die im Beispiel gezeigten Konstanten loszuwerden, ohne die Information zu verlieren.

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 

Kennt jemand Möglichkeiten für den Code zu sagen, wo es ist? Wenn Sie es schlüssig nachweisen können, nicht getan werden, das ist eine Antwort zu :)

Edit:
ich auch weiß, dass der Projektname in Err.Source ist. Ich hatte gehofft, ich könnte es ohne Ausnahme für andere Zwecke bekommen. Wenn Sie sich gut auskennen, können wir das außerhalb des Bereichs der Frage definieren.
Mir ist auch bekannt, wie man die Fehlerzeile bekommt, aber diese Information ist natürlich nur ein wenig hilfreich, ohne Module.Procedure zu kennen.

+0

Alle Antworten in diesem Thread waren gut und erkundeten gültige Techniken, obwohl mich keiner wirklich dorthin brachte, wo ich hin wollte. Ich akzeptierte das, was ich tat, weil es am nächsten kam, um das zu erreichen, was ich versuchte, und jemand sollte die Punkte bekommen. – Oorang

Antwort

2

Für die Projektnamen, der einzige Weg, mir bewusst, dies zu tun denken kann, ist ein Fehler irgendwo in Sub Main() zu werfen, und in dem Fehlerbehandlungscode, Speichern Sie die resultierende Err.Quelle in eine globale Variable g_sProjectName. Ansonsten erinnere ich mich daran, dass es eine kostenlose DLL von Drittanbietern mit dem Namen TLBINF32.DLL gab, die COM-Reflektionen verwendete - aber das scheint weit übertrieben zu sein, und in jedem Fall gibt es wahrscheinlich einen Unterschied zwischen öffentlich und privat Klassen. Und schließlich können Sie einen binären Editor verwenden, um in Ihrer EXE nach der Projektnamenzeichenfolge zu suchen, und dann versuchen, die Zeichenfolge von der Position aus zu lesen. Während es frustrierend ist, dass die Namen jedes Projekts und jedes Code-Moduls in der EXE eingebettet sind, scheint es keine vorhersehbare Möglichkeit zu geben, dies zu tun, daher wird es NICHT empfohlen.

+0

Hmmm, sieht aus wie dieser mit Visual Studio 6 ausgeliefert. Aber es ist nicht für Vista und Windows 7 unterstützt. Wenn möglich, würde ich gerne eine Lösung, die verwendet werden kann, ohne dlls nicht Teil der Standardinstallation. Trotzdem, gute Infos. +1 – Oorang

1

Leider müssen Sie individuelle On Error GoTo X Anweisungen für einzelne Module und Verfahren haben. Das Projekt wird immer in Err.Source gespeichert. Die VBA-Fehlerbehandlung ist in diesem Bereich nicht besonders gut - schließlich, wie viel Nutzen hat das Projekt als Fehlerquelle, im Gegensatz zu procedure/modul.

Wenn Sie Ihre Zeilen manuell oder programmatisch nummerieren (wie Old-School-BASIC), können Sie ERL verwenden, um die Zeilennummer aufzulisten, an der der Fehler aufgetreten ist. Seien Sie jedoch gewarnt, dass ein Fehler, der in einer Zeile ohne Nummer auftritt, ERL einen eigenen Fehler verursacht, anstatt eine Null zurückzugeben. Weitere Informationen finden Sie unter at this blog post.

Wenn Sie mit Access 2007 (nicht sicher über andere Office-Anwendungen/Versionen), versuchen Sie diesen Code-Schnipsel aus der Hilfedokumentation gegraben:

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 

Und Microsoft enthält diese Bemerkungen:

  • Alle offenen Module sind in der Module Sammlung enthalten sind, ob sie unkompilierten sind, zusammengestellt, sind in Pause-Modus oder den Code enthalten, die ausgeführt wird.
  • Um zu bestimmen, ob ein einzelnes Modulobjekt ein Standardmodul oder ein Klassenmodul darstellt, überprüfen Sie die Type-Eigenschaft des Modulobjekts .
  • Die Module-Auflistung gehört zu dem Microsoft Access Application Objekt .
  • Einzelne Modulobjekte in der Modulesammlung sind indexiert beginnend mit Null.

Bis jetzt konnte ich nichts finden, wenn ich auf das aktuelle Projekt oder die Prozedur verweise. aber das sollte dich in die richtige Richtung weisen.

+0

Hallo, ich entschuldige mich, ich hätte genauer sein sollen in dem, was ich gefragt habe. Ich habe die Hauptfrage bearbeitet, um den Umfang etwas zu verengen. +1 für Aufwand :) – Oorang

+0

Die hinzugefügten Informationen sollten helfen, auch wenn es nur Granularität basierend auf dem Modul gibt. –

+0

On Access und VBIDE und dergleichen ... Das ist ein guter Gedanke, aber es sagt dir nicht, wo du im Code bist :) Auch VBIDE kommt mit AV-Gepäck. – Oorang

2

Hier sind einige Fragen.

Sie können den Projektnamen erhalten, indem Aufruf App.Name Sie nicht den Namen der Methode bekommen Sie in. Ich empfehle die automatisierte Prozedur Vorlagen aus MZ Tools verwenden, die automatisch in allen Konstanten stellen, die Sie benötigen und Ihre Kopfschmerzen werden vorbei sein.

Das letzte Stück muss möglicherweise den Namen der EXE (oder lib) kennen, die Ihre ActiveX-DLL aufgerufen hat. Um dies herauszufinden, versuchen Sie Folgendes:

'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 
+0

Wie es passiert, verwende ich MZ-Tools :) Ruft nicht wirklich den Modulnamen, aber immer noch sehr hilfreich. +1 – Oorang

+0

+1. Die Syntaxhervorhebung funktioniert übrigens besser, wenn Sie am Ende jeder Kommentarzeile ein einfaches Anführungszeichen hinzufügen. Ansonsten denkt es, dass der Kommentar mehrere Zeilen umfasst. – MarkJ

+0

Ich habe es versucht - scheint nicht zu funktionieren. Fühlen Sie sich frei, meine Antwort zu bearbeiten. Sieht aus, als hättest du jetzt das Recht, dass du über 2000 Wiederholungen hast. – AngryHacker

0

Ich schlage vor, Sie nehmen einen Blick auf CodeSMART for VB6, Dieses VB6 Addin hat eine anpassbareFehlerbehandlung Schemes-Manager, mit Makros, die Zeichenketten für Modulnamen, Methodennamen usw. in Ihre Fehler einfügen wird der Code verarbeitet mit ein einzelnes Kontextmenü Auswahl.

Hat noch ein paar sehr nette Features - eine Suche in Dateien, die allem, was ich bis ReSharper gesehen habe, überlegen ist, einem Tab-Order-Designer und vielem mehr.

Bei meinem früheren Arbeitgeber haben wir dieses Tool seit vielen Jahren verwendet, beginnend mit der Version 2005. Sobald man sich daran gewöhnt hat, ist es wirklich schwer, ohne es auszukommen.

Verwandte Themen