VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END Attribute VB_Name = "Log4vba" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False '------------------------------------------------------------------------------- 'File : Log4vba.cls ' Copyright mpl by ERB software ' All rights reserved ' http://wiki.yaslaw.info/dokuwiki/doku.php/vba/classes/log4vba 'Environment : VBA 2016+ 'Version : 1.1.0 'Name : Log4vba 'Author : Stefan Erb (ERS) 'History : 23.11.2016 - ERS - Creation ' 29.11.2016 - ERS - Die Outputmöglichkeit function hinzugefügt '------------------------------------------------------------------------------- Option Explicit 'Ein Logger für VBA 'Man kann die Klasse über die Singleton (Standardmethode) verwenden oder eigene Instanzen erstellen 'Hier ein Beispiel für die eigene Instanz. Der getLogger() ist in einem Modul im Projekt deponiert ' '/** ' ' * Logger für diese Apllikation ' ' * Bei Error keine MsgBox anzeigen sondern nur anhalten ' ' * @return Logger ' ' */ ' Public Property Get getLogger() As Log4vba ' Static cLog As Log4vba ' If cLog Is Nothing Then ' 'Im DebugMode starten ' Set cLog = Log4vba.instance(ltError, True) ' 'Warnings nur in der Konsole ausgeben. Kein Stopp ' cLog.typeSettings(ltWarning) = eprOutConsole ' 'Errors nur in der Konsole ausgeben. Assert als rückgabewert ' cLog.typeSettings(ltError) = eprOutConsole + eprReturnAssert ' End If ' Set getLogger = cLog ' End Property ' 'Anschliessend sieht meine Fehlerbehnadlung so aus. Der resume nach dem ExitSub habe ich um beim Debuggen wieder in den Code zu kommen ' Public Sub myFunction(ByVal iId As Long, ByRef iArray As Variant)s ' On Error GoTo Err_Handler ' //TODO: Code ' Exit Sub ' Err_Handler: ' Log4vba.extendErrSource Err, "testLog4vba", iId, iArray ' Debug.Assert getLogger.error(Err) ' Exit Sub ' Resume ' End Sub '------------------------------------------------------------------------------- ' -- ! SETTINGS ! '------------------------------------------------------------------------------- 'Den Standard Debug Mode Private Const C_DEBUG_MODE_DEFAULT = False 'Die folgenden 2 Module werden NICHT benötigt. Wenn sie eingebunden sind, 'dann können die Debug-Strings oder die Source-String detailierter ausgegeben werden. 'Angabe, ob das Modul lib_json in diesem Projekt vorhanden ist oder nicht 'http://wiki.yaslaw.info/dokuwiki/doku.php/vba/cast/json 'Ab lib_json Version 2.1.0 #Const lib_json_exists = False 'Angabe, ob das Modul lib_printR in diesem Projekt vorhanden ist oder nicht 'wiki.yaslaw.info/dokuwiki/doku.php/vba/functions/print_r #Const lib_printr_exists = False '------------------------------------------------------------------------------- ' -- Public Members '------------------------------------------------------------------------------- Public Event log(text As String) '/** ' * Typ zum Loggen ' */ Public Enum eLogType [_NA] = -1 'LogType ist ebi der übergabe nicht definiert. Je nach Methode nimmt er nachher den Standard-LogType oder alle [_FIRST_TYPE] = 1 ltDebug = 1 'Debug WIrd nur bei debugMode True ist geloggt ltInfo = 2 'Info ltWarning = 3 'Warning ltError = 4 'Error [_DEBUG] = 5 'Neben dem normalen debug, ein spezieller [_LAST_TYPE] = 5 [_DEFAULT] = ltInfo End Enum '/** ' * Die Auswahl an Möglichkeiten zur Ausgabe ' */ Public Enum eTypeSetting [_NA] = -1 eprNothing = 0 'Keine Rück-/Ausgabe 'Angaben über den Return_Wert. Sind nicht kombinierbar. Bei mehrfachwahl ist wird der Erste verwendet eprReturnAssert = 2 ^ 0 'Rückgabewert für debug.assert eprReturnMsg = 2 ^ 1 'Rückgabewert ist die Fehlermeldunf 'Angaben, was mit der Meldung gemacht werden soll. Sie können kombiniert werden eprOutConsole = 2 ^ 2 'Ausgabe ins Direktfenster eprOutMsgBox = 2 ^ 3 'Als MassegeBox ausgeben eprOutLogFile = 2 ^ 4 'In ein LogFile schreiben (DB-Pfad\DB-Name.log) eprOutFunction = 2 ^ 5 'Pro LogType kann eine Funktion angegeben werden, die ausgeführt wird 'Angaben zur Formatierung. Sie können kombiniert werden eprFrmtSourceExtend = 2 ^ 5 'Beim zusammensetzen der Source die Originalsource nicht ersetzen sondern erweitern eprFrmtJson = 2 ^ 6 'PrintR wird höher gewertet als json, wird nur verwendet wenn lib_json eingbunden ist eprFrmtPrintR = 2 ^ 7 'Json wird höher gewertet als printR eprFrmtNoSource = 2 ^ 8 'Die Source nicht anzeigen 'Standards pro logType [_DEBUG_DEFAULT] = eprOutConsole + eprFrmtPrintR + eprFrmtJson [_INFO_DEFAULT] = eprOutConsole [_WARNING_DEFAULT] = eprOutConsole + eprOutMsgBox [_ERROR_DEFAULT] = eprOutConsole + eprOutMsgBox + eprReturnAssert End Enum '------------------------------------------------------------------------------- ' -- Private Members '------------------------------------------------------------------------------- '/** ' * Alle Information zu einem Logeintrag ' */ Private Type tItem description As Variant 'String oder Array source As String variablen As String number As Long debugText As Variant timeStamp As Date logMsg As String logType As eLogType setting As eTypeSetting End Type Private pDebugMode As Boolean Private pTypeSettings(eLogType.[_FIRST_TYPE] To eLogType.[_LAST_TYPE]) As eTypeSetting Private pLastAssert As tItem Private pActualMethode As String Private pFunctionName As String '------------------------------------------------------------------------------- ' -- Public Constructors '------------------------------------------------------------------------------- '/** ' * Default. Handelt eine Singleton Instanz von Log4vba ' * @example Log4vba().info "Hallo Welt" ' * @param eLogType Standard LogType ' * @return Log4vba ' */ Public Function singleton(Optional ByVal iDebugMode = C_DEBUG_MODE_DEFAULT) As Log4vba Attribute singleton.VB_UserMemId = 0 'Attribute singleton.VB_UserMemId = 0 Static cLog As Log4vba: If cLog Is Nothing Then Set cLog = Log4vba.instance(iDebugMode) Set singleton = cLog End Function '/** ' * Erstellt eine neue Instanz von Log4vba ' * @param eLogType Standard LogType ' * @return Log4vba ' */ Public Function instance(Optional ByVal iDebugMode = C_DEBUG_MODE_DEFAULT) As Log4vba Set instance = New Log4vba: instance.construct iDebugMode End Function '/** ' * Setzt Standardwerte für eine bestehende Instanz ' * @param eLogType Standard LogType ' * @return Log4vba ' */ Public Function construct(Optional ByVal iDebugMode = C_DEBUG_MODE_DEFAULT) As Log4vba resetSettings debugMode = iDebugMode Set construct = Me End Function '/** ' * Startet eine Logging für eine Methode ' * @param String Name der Methode ' * @param Array<> Ein Arry mit den Aufrufparamtern der Method ' * @return Log4vba Ein Clone des Objektes ' */ Public Function startMethode( _ ByVal iSource As String, _ ParamArray iValueArray() As Variant _ ) As Log4vba Set startMethode = Me.clone If debugMode Then startMethode.debugMsg "started", iSource, CVar(iValueArray) startMethode.actualMethodeName = iSource End Function '------------------------------------------------------------------------------- ' -- Private Constructors '------------------------------------------------------------------------------- '/** ' * Standardwerte setzen ' */ Private Sub Class_Initialize() resetSettings End Sub '/** ' * Steam schliessen ' */ Private Sub Class_Terminate() logFileStream.Close If isMethodeLogger Then endMethode End Sub '------------------------------------------------------------------------------- ' -- Public Methodes '------------------------------------------------------------------------------- '/** ' * Beendet einen methodengebundenen Logger ' */ Public Sub endMethode() If isMethodeLogger And debugMode Then assert "ended", ltDebug, pActualMethode pActualMethode = Empty End Sub '/** ' * Setzt alle settings auf den Standard zurück ' * @param LogType Falls gesetzt, wird nur der eine Logtype zurückgesetzt ' */ Public Sub resetSettings( _ Optional ByVal iLogType As eLogType = eLogType.[_NA] _ ) If Not iLogType = eLogType.[_NA] Then debugMode = C_DEBUG_MODE_DEFAULT If iLogType = eLogType.[_NA] Or iLogType = ltInfo Then typeSettings(ltInfo) = eTypeSetting.[_INFO_DEFAULT] If iLogType = eLogType.[_NA] Or iLogType = ltWarning Then typeSettings(ltWarning) = eTypeSetting.[_WARNING_DEFAULT] If iLogType = eLogType.[_NA] Or iLogType = ltError Then typeSettings(ltError) = eTypeSetting.[_ERROR_DEFAULT] If iLogType = eLogType.[_NA] Or iLogType = ltDebug Then typeSettings(ltDebug) = eTypeSetting.[_DEBUG_DEFAULT] End Sub '/** ' * Nur eine Message im Debugmodus ausgeben ' * @param String Freier Text der im Log erscheint ' * @param String Name der Methode ' * @param Array<> Ein Arry mit den Aufrufparamtern der Method ' * @param eTypeSetting Die Setings für diesen Type einmalig übersteuern ' * @return Boolen/String Rückgabewert für debug.assert oder LogMessage ' */ Public Function debugMsg( _ ByVal iComment As String, _ Optional ByVal iSource As String, _ Optional ByRef iValueArray As Variant, _ Optional ByVal iOverwriteSetting As eTypeSetting = eTypeSetting.[_NA] _ ) As Variant If Not debugMode Then Exit Function debugMsg = assert(iComment, ltDebug, iSource, iValueArray, , iOverwriteSetting) End Function '/** ' * Debug für eine Variable ' * @param String Freier Text der im Log erscheint ' * @param Variant Variable, die ausgewertet werden soll ' * @param String Name der Methode ' * @param Array<> Ein Arry mit den Aufrufparamtern der Method ' * @param eTypeSetting Die Setings für diesen Type einmalig übersteuern ' * @return Boolen/String Rückgabewert für debug.assert oder LogMessage ' */ Public Function debugValue( _ Optional ByVal iComment As Variant, _ Optional ByVal iValue As Variant, _ Optional ByVal iSource As String, _ Optional ByRef iValueArray As Variant, _ Optional ByVal iOverwriteSetting As eTypeSetting = eTypeSetting.[_NA] _ ) As Variant If Not debugMode Then Exit Function 'Kein Value übergeben -> debugMsg If IsMissing(iValue) And Not IsArray(iValue) Then debugValue = debugMsg(iComment, iSource, iValueArray, iOverwriteSetting) Exit Function End If debugValue = assert(iComment, ltDebug, iSource, iValueArray, , iOverwriteSetting, iValue) End Function '/** ' * @param ErrObject/String ' * @param Long Error-Nummer ' * @param String Name der Methode ' * @param Array<> Ein Arry mit den Aufrufparamtern der Method ' * @param eTypeSetting Die Setings für diesen Type einmalig übersteuern ' * @return Boolen/String Rückgabewert für debug.assert oder LogMessage ' */ Public Function info( _ ByRef iError As Variant, _ Optional ByVal iSource As String, _ Optional ByRef iValueArray As Variant, _ Optional ByVal iNumber As Long, _ Optional ByVal iOverwriteSetting As eTypeSetting = eTypeSetting.[_NA] _ ) As Variant info = assert(iError, ltInfo, iSource, iValueArray, iNumber, iOverwriteSetting) End Function '/** ' * @param ErrObject/String ' * @param Long Error-Nummer ' * @param String Name der Methode ' * @param Array<> Ein Arry mit den Aufrufparamtern der Method ' * @param eTypeSetting Die Setings für diesen Type einmalig übersteuern ' * @return Boolen/String Rückgabewert für debug.assert oder LogMessage ' */ Public Function warning( _ ByRef iError As Variant, _ Optional ByVal iSource As String, _ Optional ByRef iValueArray As Variant, _ Optional ByVal iNumber As Long, _ Optional ByVal iOverwriteSetting As eTypeSetting = eTypeSetting.[_NA] _ ) As Variant warning = assert(iError, ltWarning, iSource, iValueArray, iNumber, iOverwriteSetting) End Function '/** ' * @param ErrObject/String ' * @param Long Error-Nummer ' * @param String Name der Methode ' * @param Array<> Ein Arry mit den Aufrufparamtern der Method ' * @param eTypeSetting Die Setings für diesen Type einmalig übersteuern ' * @return Boolen/String Rückgabewert für debug.assert oder LogMessage ' */ Public Function error( _ ByRef iError As Variant, _ Optional ByVal iSource As String, _ Optional ByRef iValueArray As Variant, _ Optional ByVal iNumber As Long, _ Optional ByVal iOverwriteSetting As eTypeSetting = eTypeSetting.[_NA] _ ) As Variant error = assert(iError, ltError, iSource, iValueArray, iNumber, iOverwriteSetting) End Function '------------------------------------------------------------------------------- ' -- Public Properties '------------------------------------------------------------------------------- '/** ' * Bei einem Methodengebundenen Logger steht hier der Name der Method ' * @return String ' */ Public Property Get actualMethodeName() As String: actualMethodeName = pActualMethode: End Property Public Property Let actualMethodeName(ByVal iName As String): pActualMethode = iName: End Property '/** ' * Gibt einen Clone des aktuelles Objektes zurück ' */ Public Property Get clone() As Log4vba Set clone = New Log4vba clone.debugMode = Me.debugMode Dim i As Integer: For i = eLogType.[_FIRST_TYPE] To eLogType.[_LAST_TYPE] clone.typeSettings(i) = Me.typeSettings(i) clone.functionName = Me.functionName Next i End Property '/** ' * DebugMode ein/ausschalten ' * @return Boolean ' */ Public Property Get debugMode() As Boolean: debugMode = pDebugMode: End Property Public Property Let debugMode(ByVal iDebugMode As Boolean): pDebugMode = iDebugMode: End Property '/** ' * Die gesammelten Paramter für ein Logtype ' * @return eTypeSetting ' */ Public Property Get typeSettings(ByVal iLogType As eLogType) As eTypeSetting typeSettings = pTypeSettings(iLogType) End Property Public Property Let typeSettings(ByVal iLogType As eLogType, ByVal iSetting As eTypeSetting) pTypeSettings(iLogType) = iSetting End Property '/** ' * Infos über den letzten Eintrag ' */ Public Property Get lastLogType() As eLogType: lastLogType = pLastAssert.logType: End Property Public Property Get lastLogMessage() As String: lastLogMessage = pLastAssert.logMsg: End Property Public Property Get lastLogSource() As String: lastLogSource = pLastAssert.source: End Property Public Property Get lastLogTimeStamp() As String: lastLogTimeStamp = pLastAssert.timeStamp: End Property '/** ' * Externe Public Function pro LogType, welche ausgeführt wird wenn eprOutFunction aktiviert ist ' * Es muss eine Funktion und keine Sub sein, denn die Sub kann mit eval() nicht ausgeführt werden ' * Die externe Funktion mussso definiert sein. Es können noch weitere optionale Attribute angehängt werden. Es wird nur der erste ausgefüllt ' * Public Function myFunction(ByVal iLogType As eLogType, ByVal iText As String) ' * @param String ' */ Public Property Get functionName() As String: functionName = pFunctionName: End Property Public Property Let functionName(ByVal iName As String): pFunctionName = iName: End Property '------------------------------------------------------------------------------- ' -- Private Methodes '------------------------------------------------------------------------------- '/** ' * Den Eintrag standartmässig handeln '/** ' * @param ErrObject/String ' * @param eLogType Typ der gelogt werden doll ' * @param Long Error-Nummer ' * @param String Name der Methode ' * @param Array<> Ein Arry mit den Aufrufparamtern der Method ' * @param eTypeSetting Die Setings für diesen Type einmalig übersteuern ' * @return Boolen/String Rückgabewert für debug.assert oder LogMessage ' */ Private Function assert( _ ByRef iError As Variant, _ Optional ByVal iLogType As eLogType = eLogType.[_DEFAULT], _ Optional ByVal iSource As String, _ Optional ByRef iValueArray As Variant, _ Optional ByVal iNumber As Long, _ Optional ByVal iOverwriteSetting As eTypeSetting = eTypeSetting.[_NA], _ Optional ByVal iDebugValue As Variant _ ) As Variant Dim item As tItem 'Flags vorbereiten Dim isErr As Boolean: isErr = IsObject(iError) Dim srcExt As Boolean: srcExt = outMethodeDetail(iLogType, eprFrmtSourceExtend) Or andB(iOverwriteSetting, eprFrmtSourceExtend) Dim haveSrc As Boolean: haveSrc = (iSource <> Empty) 'Standards festlegen If IsMissing(iError) Then iError = Empty If IsMissing(iValueArray) Then iValueArray = Array() 'LogType item.logType = iLogType 'Source/Methode ermitteln item.source = iSource If Not haveSrc And isErr Then item.source = iError.source ElseIf haveSrc And isErr And srcExt Then item.source = iError.source & "." & iSource End If item.variablen = varArray2String(iValueArray) 'Bei einem MethodeLogger die Source überschreiben If isMethodeLogger Then item.source = actualMethodeName 'restliche Infos aus einem ErrObject auslesen If isErr Then item.description = iError.description item.number = IIf(iNumber = 0, iError.number, iNumber) Else item.description = iError item.number = iNumber End If 'DebugValue als Zeilearray übergeben If Not IsMissing(iDebugValue) Then item.debugText = Split(var2string(iDebugValue, eprFrmtPrintR), vbCrLf) 'Die Settings auslesen item.setting = IIf(iOverwriteSetting = eTypeSetting.[_NA], typeSettings(iLogType), iOverwriteSetting) assert = writeMessage(item, iLogType) End Function '/** ' * Stellt die Source inkl. Paramtern als Einzeiler dar ' * @param Variant ErrObject oder String ' * @param String Name der Methode ' * @param Array Aulfistung der Argumente ' * @return String Source-String ' */ Private Static Function varArray2String( _ ByRef iValueArray As Variant _ ) As String Dim args() As Variant Dim value As Variant If Not UBound(iValueArray) = -1 Then ReDim args(UBound(iValueArray)) Dim i As Long: For i = 0 To UBound(iValueArray) ref value, iValueArray(i) If IsNumeric(value) Then value = val(value) args(i) = var2string(value, eprFrmtJson) Next i Else args = Array() End If varArray2String = Join(args, ", ") End Function '/** ' * Parst ein Wert in ein String. Wird fpr dieVeranschaulichung des Variabelninhaltes verwednet ' * @param Variant ' * @param eTypeSetting ggf. Information ob mit json oder printR gearbeitet werden soll ' * @return String ' */ Private Function var2string(ByRef iVar As Variant, Optional ByVal iVarPrint As eTypeSetting) As String If IsMissing(iVar) Then var2string = "Missing" Exit Function End If 'Rückgabe mit print_r #If lib_printr_exists Then If andB(iVarPrint, eprFrmtPrintR) Then var2string = print_r(iVar, prParamsDefault, prReturn) Exit Function End If #End If 'Rückgabe als Json #If lib_json_exists Then If andB(iVarPrint, eprFrmtJson) Then If IsArray(iVar) Or TypeName(iVar) = "Collection" Or TypeName(iVar) = "Dictionary" Then var2string = obj2json(iVar, jqmSingleQuote + jqmNoErrorForWrongType) Exit Function End If End If #End If 'Einfache version If IsObject(iVar) Then var2string = "<" & TypeName(iVar) & ">" ElseIf IsArray(iVar) Then Dim retArr() As Variant: If UBound(iVar) = -1 Then retArr = Array() Else ReDim retArr(LBound(iVar) To UBound(iVar)) Dim i As Long: For i = LBound(iVar) To UBound(iVar) retArr(i) = var2string(iVar(i), iVarPrint) Next i End If var2string = "[" & Join(retArr, ",") & "]" Else var2string = castSqlString(iVar) End If End Function '/** ' * Die Meldung in die verschieden Kanäle absetzen ' * @return Boolen/String Rückgabewert für debug.assert oder LogMessage ' */ Private Function writeMessage( _ ByRef ioItem As tItem, _ Optional ByVal iLogType As eLogType = eLogType.[_NA] _ ) As Variant ioItem.timeStamp = Now ioItem.logMsg = createLogText(ioItem, iLogType) 'Logfile If andB(ioItem.setting, eprOutLogFile) Then logFileStream.WriteLine ioItem.logMsg 'Konsole (Direktfenster) If andB(ioItem.setting, eprOutConsole) Then Debug.Print ioItem.logMsg 'MsgBox If andB(ioItem.setting, eprOutMsgBox) Then writeMessage = dialog(ioItem, iLogType) 'Assert-Wert If Not andB(ioItem.setting, eprReturnAssert) Then writeMessage = True 'externe Funktion ausführen If andB(ioItem.setting, eprOutFunction) Then Eval functionName & "(" & iLogType & ", '" & ioItem.logMsg & "')" 'Letzter Eintrag behalten pLastAssert = ioItem 'Logtype extra erst am Schluss übernehmen. Bei Thraw und Raise entsprechen ioItem.LogType nicht dem eigentlichen Type pLastAssert.logType = iLogType If andB(ioItem.setting, eprReturnMsg) Then writeMessage = ioItem.logMsg RaiseEvent log(ioItem.logMsg) DoEvents End Function '/** ' * Erstellt einen LogText ' * 0:Datum 1:Type 2:Methode - 3:[#Nummer] 4:Description 5:(Variablen) ' * @param tItem ' * @param eLogType ' * @return String ' */ Private Function createLogText(ByRef ioItem As tItem, Optional ByVal iLogType As eLogType = ltInfo) As String Const C_DATE_SIZE = 22 Const C_TYPE_SIZE = 10 Dim sTab As String: sTab = String(C_DATE_SIZE + C_TYPE_SIZE, " ") Dim sDate As String, sType As String, sSource As String, sNumber As String, sDescription As String, sVariablen As String 'Datum sDate = lPad(ioItem.timeStamp, C_DATE_SIZE) 'Type sType = lPad(getTypeText(iLogType), C_TYPE_SIZE) 'Methode If Not outMethodeDetail(iLogType, eprFrmtNoSource) Then sSource = IIf(isMethodeLogger, ioItem.source, ioItem.source) If Not sSource = Empty Then sSource = sSource & " - " End If 'Number If ioItem.number <> 0 Then sNumber = "[#" & ioItem.number & "] " 'Description sDescription = ioItem.description 'Variablen If Not ioItem.variablen = Empty Then sVariablen = " (" & ioItem.variablen & ")" 'Debugtext: überschreibt Variablen If IsArray(ioItem.debugText) Then Dim i As Long: For i = LBound(ioItem.debugText) + 1 To UBound(ioItem.debugText) ioItem.debugText(i) = sTab & ioItem.debugText(i) Next i sVariablen = ": " & Join(ioItem.debugText, vbCrLf) End If createLogText = sDate & sType & sSource & sNumber & sDescription & sVariablen End Function '/** ' * Gibt den Fehler Eintrag als Dialog aus ' * @param logType ' * @param VbMsgBoxStyle ' * @return VbMsgBoxResult ' */ Private Function dialog(ByRef ioItem As tItem, ByVal iLogType As eLogType) As Boolean Dim style As VbMsgBoxStyle Dim result As VbMsgBoxResult Dim msg As String msg = ioItem.description Select Case iLogType Case ltInfo: style = vbInformation Case ltWarning: style = vbExclamation Case ltError: style = vbCritical End Select If outMethodeDetail(iLogType, eprReturnAssert) Then style = style + vbYesNo result = vbNo msg = msg & vbCrLf & vbCrLf & "Stop for Debug?" Else style = style + vbOKOnly result = vbOK End If If ioItem.number <> 0 Then msg = "[" & ioItem.number & "] " & msg If ioItem.source <> Empty Then msg = ioItem.source & vbCrLf & vbCrLf & msg dialog = (MsgBox(msg, style, getTypeText(iLogType)) = result) End Function '/** ' * Gibt den Text zum Type zurück ' * @param eLogType ' * @return String ' */ Private Function getTypeText(ByVal iLogType As eLogType) As String Select Case iLogType Case ltDebug: getTypeText = "DEBUG" Case ltInfo: getTypeText = "INFO" Case ltWarning: getTypeText = "WARNING" Case ltError: getTypeText = "ERROR" Case eLogType.[_DEBUG]: getTypeText = "DEBUG" Case Else: getTypeText = "N/A" End Select End Function '------------------------------------------------------------------------------- ' -- Private Properties '------------------------------------------------------------------------------- Private Property Get isMethodeLogger() As Boolean isMethodeLogger = pActualMethode <> Empty End Property '/** ' * Setzt oder entfernt einen Paramter ' * @param eLogType ' * @param Boolean ' */ Private Property Get outMethodeDetail(ByVal iLogType As eLogType, ByVal iParam As eTypeSetting) As Boolean outMethodeDetail = andB(pTypeSettings(iLogType), iParam) End Property Private Property Let outMethodeDetail(ByVal iLogType As eLogType, ByVal iParam As eTypeSetting, ByVal iValue As Boolean) If Not andB(pTypeSettings(iLogType), iParam) And iValue Then pTypeSettings(iLogType) = pTypeSettings(iLogType) + iParam ElseIf andB(pTypeSettings(iLogType), iParam) And Not iValue Then pTypeSettings(iLogType) = pTypeSettings(iLogType) - iParam End If End Property '/** ' * Gibt einen Textstream auf die Log-Datei zurück ' * @return TextStream ' */ Private Property Get logFileStream() As Object Const ForAppending = 8 Static fso As Object Static stream As Object If fso Is Nothing Then Set fso = CreateObject("Scripting.FileSystemObject") If stream Is Nothing Then Dim logFilePath As String logFilePath = CurrentDb.Name logFilePath = fso.BuildPath(fso.GetParentFolderName(logFilePath), fso.GetBaseName(logFilePath) & ".log") Set stream = fso.OpenTextFile(logFilePath, ForAppending, True) End If Set logFileStream = stream End Property '------------------------------------------------------------------------------- ' -- Private Libraries '------------------------------------------------------------------------------- '/** ' * http://wiki.yaslaw.info/dokuwiki/doku.php/vba/functions/andb ' * Macht einen Bit-Vergleich ' * @param Long ' * @param Long ' * @return Boolean ' */ Private Function andB(ByVal iHaystack As Long, ByVal iNeedle As Long) As Boolean andB = ((iHaystack And iNeedle) = iNeedle) End Function '/** ' * Aus SQLScript kopiert ' * Gibt einen SQL-String anhand des Datentyp zurück ' * @param Variant Daten ' * @param VBA.VbVarType Datentype aus VarType() überschreiben ' * @return String SQL-String ' */ Private Function castSqlString(ByVal iValue As Variant, Optional ByVal iVarType As VbVarType = -1) As String Select Case IIf(iVarType = -1, VarType(iValue), iVarType) Case vbDate: castSqlString = "#" & format(iValue, "MM-DD-YYYY HH:NN:SS") & "#" Case vbNull: castSqlString = "NULL" Case vbEmpty: castSqlString = "''" Case vbBoolean: castSqlString = UCase(CStr(CBool(iValue))) 'CStr(CInt(iValue)) Case vbLong, vbInteger, vbByte, vbDouble, vbDecimal, vbSingle, vbCurrency castSqlString = CStr(iValue) Case Else: castSqlString = "'" & replace(CStr(iValue), "'", "\'") & "'" End Select End Function '/** ' * http://wiki.yaslaw.info/dokuwiki/doku.php/vba/functions/pad ' * Gibt den String iString zurück. Dieser wurde nach links mit dem String iPadString auf eine Länge von iLen Zeichen aufgefüllt. ' * Wenn iString länger als iLen ist, wird der Rückgabewert auf iLen Zeichen gekürzt. ' * @param String ' * @param Integer Neue Länge ' * @param String Zeichen mit dem verlängert wird ' * @return Erweiterter oder gekürzter String ' */ Private Function lPad( _ ByVal iString As String, _ ByVal iLen As Integer, _ Optional ByVal iPadString As String = " " _ ) As String lPad = Left(iString, iLen) lPad = lPad & String(iLen - Len(lPad), iPadString) End Function '/** ' * Bei einer Variablenübergabe muss immer unterscheiden werden, ob es ein Objekt ist oder nicht. ' * Diese Sub nimmt einem die Arbeit ab ' * ref(oNode, iNode) ' * @param Variant Variable, die den Wert bekommen soll ' * @param Variant Ret Wert selber ' */ Private Sub ref(ByRef oNode As Variant, ByRef iNode As Variant) If IsObject(iNode) Then Set oNode = iNode: Exit Sub oNode = iNode End Sub