Je zoekt waarschijnlijk verkeerd, want wat je wilt heeft niks met inlogscripts te maken, maar alles met Historie. En het is dan ook allemaal met redelijke standaard functionaliteit wel te maken. Je vraagt overigens nogal wat, want als ik je vraag goed begrijp, wil je alle mutaties van een gebruiker loggen, en dat betekent dat je db heel erg snel gaat vollopen. Ik zou dus in ieder geval een procedure erbij maken die de historietabel die je maakt regelmatig opschoont.
Wat je nodig hebt, is dus in ieder geval een Historie tabel. Zelf gebruik ik de tabel uit bijgaand plaatje. Die bevat dan bijvoorbeeld de volgende velden:
HistorieID
InlogNaam (of UserID)
Datum
Tijd
Tabel
Veld
Waarde_Ori
Waarde_Nieuw
De volgende stap is dat je die tabel gaat vullen. Dat kan alleen vanuit de formulieren, omdat je de oude waarden die
bij het laden van het record bestaan moet inlezen in variabelen, en vervolgens bij het opslaan van het record alle gemuteerde velden moet vaststellen. Het heeft geen zin om een compleet record op te slaan als je alleen de achternaam verandert. Bovendien kom je dan in de problemen als je meerdere tabellen wilt monitoren. Dus wat je met deze tabel doet, is voor elk gemuteerd veld een nieuw record aanmaken in tHistorie, waarin je vastlegt wie wat wanneer doet in welke tabel en in welk veld.
Dan nu de hamvraag: hoe vul je nu die tabel? Hieronder (een deel van) de code zoals ik die zelf gebruik.
Code:
For Each ctl In Controls
With ctl
Select Case .ControlType
Case acTextBox
If LCase(Left(.Name, 5)) = "tekst" Or LCase(Left(.Name, 4)) = "text" Then
If .Tag = "" Then MsgBox .Name
sVeld = .Tag
If Nz(.Value) <> Nz(Me(sVeld).Value) Then
sWaarde_Ori = Nz(Me(sVeld).Value)
sWaarde_Nieuw = Nz(.Value)
strSQL = "SELECT [" & sVeld & "] FROM tBronbestand WHERE Nr = " & Me.nr
With CurrentDb.OpenRecordset(strSQL)
If .RecordCount > 0 Then
.Edit
.Fields(sVeld).Value = sWaarde_Nieuw
.Update
.Close
Else
.Close
End If
End With
If Me.Dirty Then Me.Dirty = False
With CurrentDb.OpenRecordset("tHistorie")
.AddNew
!Med_NR = Me.nr
!UserID = VBA.Environ("Username")
!Datum = Date
!Tijd.Value = TimeSerial(Hour(Now()), Minute(Now()), 0)
!Tabel = Me.RecordSource
!Veld = sVeld
!Waarde_Ori = sWaarde_Ori
!Waarde_Nieuw = sWaarde_Nieuw
.Update
.Close
End With
If Me.Dirty Then Me.Dirty = False
End If
End If
End Select
End With
Next ctl
Het begint zoals je kunt zien met het uitlezen van de controls op het formulier. De belangrijkste regels (checken of een veld moet worden opgeslagen of niet) zijn deze:
Code:
sVeld = .Tag
If Nz(.Value) <> Nz(Me(sVeld).Value) Then
Op het formulier wordt, als een veld wordt gewijzigd, de oude waarde in de eigenschap <Extra Info> (Tag) gezet. Dus als je iets wijzigt in een veld, dan heeft de Tag de oude waarde, en het veld zelf uiteraard de nieuwe. Je hoeft een veld pas op te slaan als de twee niet gelijk zijn, en dat doet de check.
In het blok
Code:
With CurrentDb.OpenRecordset("tHistorie")
.AddNew
....
.Update
.Close
End With
wordt vervolgens het record aangemaakt in de historie tabel.
En dat is dus alles: je loopt, als je op de knop <Opslaan> klikt, door alle formuliervelden, en controleert de inhoud ervan. In dit voorbeeld doe ik dat alleen voor tekstvelden (Case acTextBox) die de correcte naam hebben, maar je kunt de code uiteraard nu makkelijk uitbreiden met Keuzelijsten (met invoervak) en selectievakjes.