AuditTrail

Diskussionen über den Quellcode (Module, Klassenstruktur, Schnittstellen u.s.w.) der Access Code Library

AuditTrail

Beitragvon Andreas Vogt » Sa 9. Mai 2015, 18:04

Hallo,
habe eben eine Klasse AuditTrail.cls hochgeladen: form/data/AuditTrail.cls

Der Begriff AuditTrail ist denk ich klar.

Die Besonderheit bei dieser Klasse ist, dass sie sehr aufgeräumt ist. Keine riesigen Prozeduren die nach Steuerelementtypen filtern, wie man es von anderen AuditTrail Beispielen kennt.
Die Klasse ist imo uneingeschränkt Unterformularfähig, obwohl ich nur mit 1 Unterformular getestet habe.
Die Implementierung erfolgt im Projekt, indem folgender Code in die betreffenden Formulare geschrieben wird:

Code: Alles auswählen
Dim myAudit As clsAuditTrail

Private Sub Form_Load()
    Set myAudit = New clsAuditTrail
    Set myAudit.FormObj = Me
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set myAudit = Nothing
End Sub


Die zu überwachende Steuerelemente sind mit der Marke "Audit" zu versehen - ohne Anführungszeichen natürlich.

Die Log wird in eine Tabelle mit Namen "tblAuditTrail" geschrieben mit folgender Struktur:
  • AuditTrailID (AutoWert)
  • DateTime (Datum/Zeit)
  • UserName (Text)
  • FormName (Text)
  • Action (Text)
  • RecordID (Text)
  • FieldName (Text)
  • OldValue (Text)
  • NewValue (Text)

Es sei jetzt noch erwähnt, daß das Projekt ursprünglich auf http://www.fontstuff.com/access/acctut21.htm basierte,
welches aber nicht richtig funktioniert und imo ziemlich schlechten Code hat.

Gruß Andreas
Andreas Vogt
Entwickler
 
Beiträge: 165
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Re: AuditTrail

Beitragvon Andreas Vogt » So 10. Mai 2015, 07:39

Überarbeitete Version mit meinem Copyright, geänderte Tabellenstruktur:
Tabelle tblAuditTrailLog mit folgenden Feldern:
  • ID (AutoWert)
  • DateTime (Datum/Zeit)
  • UserName (Text)
  • FormName (Text)
  • ActionType (Text)
  • RecordID (Text)
  • FieldName (Text)
  • OldValue (Text)
  • NewValue (Text)
Gruß Andreas
Andreas Vogt
Entwickler
 
Beiträge: 165
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Re: AuditTrail

Beitragvon Josef Pötzl » So 10. Mai 2015, 10:15

Ich verschob die Klasse nach form/data und ergänzte den CodeLib-Block, damit man sie über den Import-Wizard einfügen und exportieren kann.
Sollte man im CodeLib-Block die Erstellung der Tabelle einbauen, falls sie noch nicht vorhanden ist?

Ein paar Gedanken zum Code:
Code: Alles auswählen
Private Sub DataChanges()
    Dim CTL As Control
    Dim lngInsertedID As Long

    Set rstAuditLog = New ADODB.Recordset
    With rstAuditLog
        .Open "SELECT * FROM tblAuditTrailLog", CurrentProject.Connection, adOpenDynamic, adLockOptimistic
        dtmCurrentDateTime = Now()
        strUserName = Environ("USERNAME")
        Select Case UserAction
        Case "EDIT"
            For Each CTL In m_frm.Controls
                If CTL.Tag = "Audit" Then
                    If Nz(CTL.Value) <> Nz(CTL.OldValue) Then
                        WriteEditLog CTL
                    End If
                End If
            Next CTL
        Case Else
            lngInsertedID = WriteNewDeleteLog(CTL)
            If UserAction = "DELETE" Then lastIdentifier = lngInsertedID
        End Select
    End With
    rstAuditLog.Close
    Set rstAuditLog = Nothing
End Sub


In der Prozedur wird ein Recordset geöffnet aber nicht genutzt.
Da es wahrscheinlich ist, dass Änderungen in mehreren Datenfeldern stattfinden, könnte man meiner Meinung nach durchaus in der Recordset-Edit-Variante bleiben. diese sollte schneller als ein Insert-Statement je geändertem Feld ablaufen.

Ich könnte mir so einen Aufruf vorstellen:
Code: Alles auswählen
WriteEditLog rstAuditLog, CLT



Klassenvariable "UserAction"
Das ist jetzt Geschmacksache: Ich persönlich würde diese Einstellung nicht in der Klasse abspeichern, sondern an die Prozeduren als Parameter übergeben, damit man nicht übersehen kann, diese Einstellung zu setzten.

LG
Josef
Josef Pötzl
Moderator
 
Beiträge: 805
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2016

Re: AuditTrail

Beitragvon Andreas Vogt » So 10. Mai 2015, 15:17

Ah, Recordset rausnehmen hab ich vergessen, ist ja jetzt überflüssig an dieser Stelle.
Ich glaube nicht dass die etwas geringere Geschwindigkeit eine Rolle spielt. Da finde ich es wichtiger dass durch die Separierung der Funktion die Lesbarkeit erhöht wird.

Tabellenerstellung und Prüfung ob nicht schon vorhanden kann ich noch rein nehmen
Wegen UserAction, ich persönlich finde es so besser, aber da sich alles innerhalb der Klasse abspielt und somit gekapselt ist, spielt das doch überhaupt keine Rolle.

Update mach ich heute noch.

Andreas
Andreas Vogt
Entwickler
 
Beiträge: 165
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Re: AuditTrail

Beitragvon Josef Pötzl » Di 12. Mai 2015, 13:14

Hab noch eine kleine Code-Korrektur vorgenommen:

Code: Alles auswählen
    Set cnn = CurrentProject.Connection
    cnn.Execute strSQL, RecordsAffected
    If RecordsAffected > 0 Then
        Set rstTemp = cnn.Execute("SELECT @@IDENTITY")
        WriteNewDeleteLog = rstTemp(0)
        rstTemp.Close ' das gehört hierher
    End If
   
    'rstTemp.Close .... wenn RecordsAffected 0 wäre, würde das Close an dieser Stelle einen Fehler auslösen
    'cnn.Close     .... nicht schließen, da CurrentProject.Connection keine selbst geöffnete Connection ist!

 


LG
Josef
Josef Pötzl
Moderator
 
Beiträge: 805
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2016

Re: AuditTrail

Beitragvon Andreas Vogt » Di 12. Mai 2015, 13:38

Hallo,
ah ja das hab ich in der Eile übersehen.
Danke.

Gruß Andreas
Andreas Vogt
Entwickler
 
Beiträge: 165
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten


Zurück zu Quellcode

cron