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)TabelleFeldDatensatzIDAlterWertNeuerWertGeändertAmBenutzer
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ändertAmGeä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,AfterUpdateusw.) - 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