Come controllare l’inserimento dati 2 di 2

Ora che sappiamo come cambiare il colore al testo di un controllo che è stato modificato (vedi Come controllare l’inserimento dati 1 di 2), vediamo come intercettare il salvataggio vero e proprio operato da Microsoft Access e chiedere all’utente se conferma le modifiche.

Possiamo scrivere il nostro codice nell’evento a livello Maschera Prima di aggiornare:

prima_di_aggiornare

Private Sub Form_BeforeUpdate(Cancel As Integer)
' prima di aggiornare il record, se effettivamente almeno un campo è stato modificato
' riepilogo all'utente le modifiche effettuate e chiedo conferma
Dim strMess As String
' la funzione fncIsEdited restituisce Vero / Falso a seconda che almeno un campo sia stato modificato
If fncIsEdited = True Then
 ' la funzione fncRiepilogoModifiche crea la stringa che contiene il valore precedente e il valore corrente
 ' per ogni campo che è stato modificato
 strMess = fncRiepilogoModifiche()
 If MsgBox(strMess & vbLf & vbLf & "Confermi le modifiche?", vbYesNo) = vbNo Then
 ' se l'utente non ha confermato le modifiche, annullo ogni modifica con Undo
 DoCmd.RunCommand acCmdUndo
 End If
End If

Il codice richiama due funzioni: fncIsEdited, che controlla se almeno un dato è stato modificato.

Function fncIsEdited() As Boolean
'restituisce Vero / Falso a seconda che almeno un campo sia stato modificato
Dim ctl As Control
Dim bln As Boolean
For Each ctl In Me.Controls
 If TypeOf ctl Is TextBox Or TypeOf ctl Is ComboBox Then
 ' TODO: non viene gestito il caso di un checkbox
 ' se il valore precedente -ossia letto dalla tabella al momento del caricamento del record nella maschera-
 ' è diverso da quello attuale, la variabile bln è impostata a True
 If Nz(ctl.OldValue, "") <> Nz(ctl, "") Then
 bln = True
 ' posso uscire dal ciclo (inutile esaminare gli altri controlli)
 Exit For
 End If
 End If
Next
' assegno alla funzione il valore che sarà restituito al chiamante
fncIsEdited = bln
End Function

In caso affermativo, chiede all’utente conferma, riepilogando le modifiche, che sono concatenate all’interno di una variabile poi usata nella MsgBox. La funzione utilizzata è fncRiepilogaModifiche

Function fncRiepilogoModifiche() As String
' crea la stringa che contiene il valore precedente e il valore corrente di ogni campo modificato
'
Dim ctl As Control
Dim strCheck As String
For Each ctl In Me.Controls
 If TypeOf ctl Is TextBox Or TypeOf ctl Is ComboBox Then
 If Nz(ctl.OldValue, "") <> Nz(ctl, "") Then
 strCheck = strCheck & vbCrLf & ctl.Name & vbCrLf & " - prima: " & ctl.OldValue & " - adesso: " & ctl
 End If
 End If
Next
fncRiepilogoModifiche = strCheck
End Function

Infine devo resettare i controlli all’aspetto predefinito: colore nero ed etichetta. Utilizzo la funzione sResetControls:

Sub sResetControls()
' resetto le proprietà del controllo, impostando
' in nero il testo del campo modificato e togliendo il grassetto dalla relativa etichetta
Dim ctl As Control
For Each ctl In Me.Controls
 If TypeOf ctl Is TextBox Or TypeOf ctl Is ComboBox Then
 ctl.ForeColor = vbBlack
 ctl.Controls(0).FontBold = False
 End If
Next
End Sub

Il salvataggio del record può essere esplicitamente richiesto dall’utente premendo il pulsante Salva, ne cui evento clic il codice è il seguente:

Private Sub cmdSalva_Click()
DoCmd.RunCommand acCmdSaveRecord
End Sub

L’istruzione esegue il salvataggio del record, che a sua volta genera l’evento Prima di aggiornare: in tal modo il codice che abbiamo scritto viene comunque eseguito, così come viene eseguito se l’utente preme il selettore dei record, se chiude la maschera ecc.