Ziel: Wissen, wer wann was geändert hat
Access speichert keine Historie.
Wenn ein Wert überschrieben wird, ist der alte weg.
Du willst: nachvollziehen, wer was wann geändert hat – und was vorher drinstand.
Geht. Mit Bordmitteln und etwas Disziplin.
Variante 1: Änderungsprotokoll in einer eigenen Tabelle
Tabelle tblAudit
ID
(Autowert)Tabelle
Feld
DatensatzID
AlterWert
NeuerWert
GeändertAm
Benutzer
Funktion zum Protokollieren
Public Sub LogÄnderung(tabelle As String, feld As String, datensatzID As Long, alt As Variant, neu As Variant)
If Nz(alt, "") <> Nz(neu, "") Then
CurrentDb.Execute "INSERT INTO tblAudit (Tabelle, Feld, DatensatzID, AlterWert, NeuerWert, GeändertAm, Benutzer) " & _
"VALUES ('" & tabelle & "', '" & feld & "', " & datensatzID & ", '" & Replace(alt, "'", "''") & "', '" & Replace(neu, "'", "''") & "', Now(), '" & Environ("USERNAME") & "')"
End If
End Sub
Anwendung im Formular
Private Sub txtFirma_BeforeUpdate(Cancel As Integer)
Call LogÄnderung("tblKunden", "Firma", Me.ID, Me.txtFirma.OldValue, Me.txtFirma.Value)
End Sub
Nur Werte, die sich wirklich ändern, werden geloggt.
Variante 2: Komplettprotokoll auf Formular-Ebene
Wenn Du viele Felder hast:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Call LogÄnderung("tblKunden", "Name", Me.ID, Me.txtName.OldValue, Me.txtName.Value)
Call LogÄnderung("tblKunden", "PLZ", Me.ID, Me.txtPLZ.OldValue, Me.txtPLZ.Value)
' usw.
End Sub
Oder: Schleife über alle Felder, wenn Du’s generisch willst.
Variante 3: Tabellenweise Triggerlogik mit Zeitstempel
Jede Tabelle bekommt:
GeändertAm
GeändertVon
Im Formular:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Me.GeändertAm = Now()
Me.GeändertVon = Environ("USERNAME")
End Sub
Einfach. Schnell. Zeigt Dir zumindest, dass jemand was gemacht hat.
Variante 4: Tabelle duplizieren für „Versionen“
Du willst alte Stände aufbewahren? Dann brauchst Du:
Tabelle tblKunden_Historie
Gleich aufgebaut wie tblKunden
, nur mit zusätzlichem Feld VersionDatum
.
Bei jeder Änderung:
CurrentDb.Execute "INSERT INTO tblKunden_Historie SELECT *, Now() FROM tblKunden WHERE ID = " & Me.ID
Dann den echten Datensatz aktualisieren.
Nachteil: Speicherverbrauch
Vorteil: vollständige Historie
Variante 5: Automatische ID-Tracking-Lösung (nur Insert)
Wenn Du nur wissen willst, wer was angelegt hat:
Private Sub Form_BeforeInsert(Cancel As Integer)
Me.ErstelltAm = Now()
Me.ErstelltVon = Environ("USERNAME")
End Sub
Reicht für viele KMU-Prozesse schon aus.
Tipps für saubere Protokolle
- Benutzername immer per
Environ("USERNAME")
- Änderungsdatum immer mitloggen
- Freitext-Felder mit
Replace(..., "'", "''")
absichern - Felder mit Format (Währung, Datum, Checkbox) explizit umwandeln
- Audit-Funktionen zentral halten – nicht pro Formular wild einbauen
Einsatzszenarien
- Kundenakten nachverfolgen
- Änderungen an Preisen, Rabatten oder Zahlungszielen
- Revisionspflichtige Daten (z. B. HR, Medizin, Finanzen)
- Interne Freigabestrecken
- Fehleranalysen („Wer hat’s geändert?“)
Fazit für Entwickler
Access kann keine Trigger – aber mit ein bisschen Struktur bekommst Du trotzdem eine nachvollziehbare Änderungsverfolgung hin.
Und: SQL Server ist beim Auditieren um Längen überlegen.
Ich erklär Dir kurz beides – ohne Geschwafel.
Warum Access keine Trigger hat
Ein Trigger ist in SQL ein Datenbankobjekt, das automatisch bei bestimmten Ereignissen feuert – etwa bei INSERT
, UPDATE
, DELETE
.
Access (bzw. die Jet/ACE-Engine) unterstützt keine Trigger auf Tabellenebene.
Was Access kennt, sind:
- Formular-Ereignisse (
BeforeUpdate
,AfterUpdate
usw.) - Makros (ja, die gibt’s auch als „Datenmakros“ in Access Web-Apps – aber das ist veraltet und praktisch tot)
Das heißt:
Wenn Du Änderungen in Access nachverfolgen willst, musst Du das im Frontend (VBA) selbst tun.
Wenn jemand aber per ODBC, Abfrage oder Code auf die Tabelle zugreift und dort ändert – ist nix mit „BeforeUpdate“. Access merkt davon nichts.
Warum Trigger + Audit mit SQL Server besser sind
Wenn Du Dein Access-Frontend mit einem SQL Server-Backend kombinierst, kannst Du dort echte Trigger definieren.
Die laufen immer, egal ob jemand per Access, Power BI, Excel, .NET, Python oder sonst was auf die Tabelle schreibt.
Beispiel: SQL Server-Trigger auf Änderung
CREATE TRIGGER trg_Kunden_Audit
ON dbo.Kunden
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO dbo.Kunden_Audit (KundenID, Feld, AlterWert, NeuerWert, GeändertAm, GeändertVon)
SELECT
i.ID,
'Name',
d.Name,
i.Name,
GETDATE(),
SYSTEM_USER
FROM inserted i
JOIN deleted d ON i.ID = d.ID
WHERE i.Name <> d.Name
END
Vorteile:
- zentral
- unabhängig vom Access-Frontend
- läuft immer, auch bei Batch-Imports
- keine VBA-Pflege nötig
- automatisierbar und analysierbar per SQL
Weitere Stärken:
- Versionsverwaltung per „Change Tracking“ oder „Temporal Tables“
- Logging auch für Löschungen
- kombinierbar mit Security-Kontexten (
SYSTEM_USER
,SUSER_SNAME()
) - Exportierbar für Prüfungen, Revisionssicherheit, DSGVO-Dokumentation
- Access? Nur Frontend-Ereignisse. Keine echten Trigger.
- Wenn’s ordentlich, zentral und verlässlich sein soll: SQL Server
- Für KMU mit Compliance- oder Protokollanforderung: SQL Server + Trigger = Pflicht
No responses yet