Newsgroup: it.comp.appl.access
Titolo: Dirty non funziona

Salve e tutti,
in una mia applicazione vorrei testare se l'utente ha salvato i dati prima dell'uscita da una maschera; ho pensato di usare la proprietà Dirty:
 
Private Sub Form_Unload(Cancel As Integer)
On Error GoTo Err_Form_Unload
    If Me.Dirty = True Then
    ' effettua i controlli del caso
    End IF
Exit_Form_Unload:
    Exit Sub
Err_Form_Unload:
    MiaMsgBox "Si è verificato il seguente errore:@N° " & Err.Number & " - " & Err.Description & "@"
    Resume Exit_Form_Unload
End Sub
 
Purtroppo non funziona: se eseguo il codice passo passo (F8) Dirty risulta False (anche se il record è stato modificato) e il codice non esegue il controllo.
Girando su Internet ho trovato un suggerimento che dice di usare l'evento Before_Update, e così ho fatto:
 
Private Sub Form_BeforeUpdate(Cancel As Integer)
On Error GoTo Err_Form_BeforeUpdate
    If Me.Dirty = True Then
    ' effettua i controlli del caso
    End IF
Exit_Form_BeforeUpdate:
    Exit Sub
Err_Form_BeforeUpdate:
    MiaMsgBox "Si è verificato il seguente errore:@N° " & Err.Number & " - " & Err.Description & "@"
    Resume Exit_Form_BeforeUpdate
End Sub
 
Questa volta funziona tutto a dovere, Dirty risulta Vero (se è stato modificato il record) e i controlli vengono eseguiti.
Non mi spiego questa differenza di comportamento ma ... mi adeguo.
Però ora ho un altro problema ancora più grande: ho aggiunto un pulsante che salva il record prima di uscire:
 
Private Sub cmdSalva_Click()
On Error GoTo Err_cmdSalva_Click
    DoCmd.RunCommand acCmdSaveRecord
Exit_cmdSalva_Click:
    Exit Sub
Err_cmdSalva_Click:
    MiaMsgBox "Si è verificato il seguente errore:@N° " & Err.Number & " - " & Err.Description & "@"
    Resume Exit_cmdSalva_Click
End Sub
 
Purtroppo quando premo il pulsante cmdSalva viene prima processato l'evento Before_Update della maschera (che quindi chiede se voglio salvare le modifiche), mentre io mi aspetto che il salvataggio avvenga premendo tale pulsante.
Che cosa sbaglio?
 
La maschera visualizza un record alla volta, i pulsanti sono posti nel piè di pagina; uso Access 2016 a 64 bit.
 
Grazie a tutti
Franco

Tutto corretto...
Il primo dubbio che ti è venuto puoi chiarirtelo guardando la sequenza degli eventi di maschera... e ti accoRho che Unload vine scatenato DOPO il BEFOREUPDATE...ne consegue che la proprietà Dirty viene resettato li se il salvataggio viene eseguito.
 
La seconda questione è che forzando il Salvataggio... ovviamente viene seguita la sequenza di generazione eventi prevista... quindi il BEFOREUPDATE ecc... da lì il tuo problema.
Quindi hai 2 modi... resetti la proprietà Dirty prima del SAVE... oppure predisponi una variabile Private(Boolean) a livello di modulo della form che setti su CLICK esegui il SAVE poi redatti subito dopo.
Quindi su BEFOREUPDATE se trovi quella variabile a True significa che hai premuto il click e non serve fare la verifica.. 
 
Prova prima a resettare Dirty.
 
@Alex 


Grazie Alex,
non ho chiara una cosa: con la sequenza di eventi che hai esposto, se il salvataggio non è stato effettuato, o lo si intercetta con BeforeUpdate oppure, per l'evento Unload della maschera, la proprietà Dirty risulta comunque False?
 
Invece ho provato a modificare il codice per il pulsante di salvataggio, modificando la proprietà Dirty, ma non funziona, e non capisco dove sbaglio:
 
Private Sub cmdSalva_Click()
On Error GoTo Err_cmdSalva_Click
    Me.Dirty = False
    DoCmd.RunCommand acCmdSaveRecord
Exit_cmdSalva_Click:
    Exit Sub
Err_cmdSalva_Click:
    MiaMsgBox "Si ? verificato il seguente errore:@N? " & Err.Number & " - " & Err.Description & "@"
    Resume Exit_cmdSalva_Click
End Sub
 
Con il passo passo prima di settare il valore di Me.Dirty=False il codice salta sull'evento BeforeUpdate.
 
Grazie
Franco


Ho risolto usando il tuo secondo metodo:
 
Creo una variabile booleana (bolSalva) a livello di maschera e su Load la imposto a True; il pulsante cmdSalva la imposta a False, sull'evento BeforeUpdate la testo ed eseguo i controlli solo se è True, quindi salvo il record e la reimposto a True.
 
Private Sub cmdSalva_Click()
On Error GoTo Err_cmdSalva_Click
    bolSalva = False
    'a questo punto il codice salta all'evento BeforeUpdate
    'controlla e poi prosegue da qui
    DoCmd.RunCommand acCmdSaveRecord
    bolSalva = True
Exit_cmdSalva_Click:
    Exit Sub
Err_cmdSalva_Click:
    MiaMsgBox "Si ? verificato il seguente errore:@N? " & Err.Number & " - " & Err.Description & "@"
    Resume Exit_cmdSalva_Click
End Sub
 
Private Sub Form_BeforeUpdate(Cancel As Integer)
On Error GoTo Err_Form_BeforeUpdate
    If bolSalva = True Then            'non è stato premuto il tasto cmdSalva
        'eseguo i controlli
    End If
Exit_Form_BeforeUpdate:
    Exit Sub
Err_Form_BeforeUpdate:
    MiaMsgBox "Si ? verificato il seguente errore:@N? " & Err.Number & " - " & Err.Description & "@"
    Resume Exit_Form_BeforeUpdate
End Sub
 
Mi sembra un po' macchinoso ma funziona. Ma allora Dirty come si usa?
Grazie
Franco