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:
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.