2012-10-18 12 views
5

In un modulo di Microsoft Access, ogni volta che cambia il record corrente, qualsiasi modifica nei controlli associati viene salvata in modo silenzioso nelle tabelle del database. Questo va bene, ma non voglio che accada quando un utente chiude un modulo, perché è l'esatto opposto di quello che molti si aspetterebbero.Impedire la chiusura di pulsanti dal salvataggio di record in MS Access

L'esempio migliore è quando si tenta di chiudere un file excel con modifiche non salvate, chiede se le modifiche devono essere eliminate. Questo è esattamente ciò che sto cercando di ottenere in Access, ma non riesco a trovare alcun modo per intrappolare l'evento del pulsante di chiusura in VBA.

L'evento Unload del modulo è il primo evento che viene attivato quando qualcuno fa clic sul pulsante di chiusura, ma a quel punto le modifiche sono già state scritte nel database.

Questo è possibile o devo creare i miei pulsanti di chiusura? Sono a mio agio con la scrittura di grandi quantità di codice per cose banali come questa, ma odio dover ingombrare la GUI.

+1

Questo può non strettamente aiutare, ma questo è il motivo per cui maschera non associata di sono grandi con cui lavorare. Lo considero come questo: con i moduli associati devi impedire le modifiche che non vuoi, e con non si limita a commettere solo le modifiche che vuoi, dipende da quale parte desideri attaccare il problema. Tuttavia, le forme vincolate possono essere utili, ma le scelgo davvero solo quando ho bisogno di moduli continui. –

+1

In un modo che è esattamente quello che sto cercando, ma non voglio perdere tutto il sistema idraulico del codice che viene fatto per me quando lego i miei controlli. –

+0

È qui che entra in gioco il problema delle forme non vincolate, c'è molto più lavoro sul codice durante l'installazione, ma in definitiva è un prodotto più facile da controllare. –

risposta

0

In realtà, non è possibile intercettarlo, l'accesso funziona direttamente sul tavolo, ogni modifica viene già salvata quando il campo perde l'orientamento spostandosi su un altro campo, su un record o su un pulsante.

In realtà secondo me questo è un grande vantaggio rispetto a Excel

Se si vuole veramente un comportamento simile a Excel avresti bisogno di lavorare su una copia della tabella e un codice per l'aggiornamento.

+0

Ho sempre avuto l'impressione che i countrol associati siano effettivamente collegati ai campi della proprietà RecordSet del modulo. È una supposizione sbagliata? –

+0

@StevenDotNet, un record non viene salvato fino a quando non viene eseguito un salvataggio, oppure viene eseguito uno spostamento su un altro (o nuovo) record o il modulo viene chiuso. – SeanC

+0

Che è simile a come si deve chiamare 'RecordSet.Update()' per applicare le modifiche. Tranne che il modulo aggiorna il recordset anche quando non lo desidero. –

5

Devi collaborare con l'evento Form_BeforeUpdate. Di seguito è un esempio; tuttavia crea un tipico messaggio di avviso: "Al momento non è possibile salvare questo record. È possibile che si sia verificato un errore durante il tentativo di salvataggio di un record in Microsoft Access ...", a seconda delle impostazioni del database. È possibile utilizzare una soluzione alternativa di seguito per evitare la visualizzazione di tale messaggio.

+0

Mi sono dimenticato dell'evento BeforeUpdate, ma non si innescherebbe prima di uno degli eventi di chiusura del modulo? –

+0

Per chiarire, voglio solo cancel = true nel caso in cui l'utente abbia fatto clic sul pulsante di chiusura del modulo. –

+1

È possibile disabilitare facilmente il pulsante di chiusura (X) sul modulo (proprietà del modulo). – salih0vicX

2

questo è il codice che ho che controlla se il modulo viene chiuso o salvato.

Private Sub Form_BeforeUpdate(Cancel As Integer) 

If Not UsingSaveButton Then 
    If MsgBox("Abandon Data?", vbInformation + vbYesNo) = vbNo Then 
     Cancel = True 
    Else 
     DoCmd.RunCommand acCmdUndo 
    End If 
End If 
End Sub 

Ho un Flag booleano che è impostata su False il carico, e poi quando viene usato il mio pulsante Salva, ho impostato a true per consentire l'aggiornamento di correre attraverso.
Se il flag non è impostato, quindi stanno lasciando il record (o passando a un altro record, o chiudendo il modulo), quindi chiedo se vogliono effettivamente salvare le modifiche.
Il Cancel = True interrompe l'uscita del modulo o lo spostamento su un altro record se sono state apportate modifiche.
Il DoCmd.RunCommand acCmdUndo annulla qualsiasi modifica in modo che non vengano salvati.

+0

Questo suona davvero bene. Suppongo che 'UsingSaveButton = False' entri in' Form_AfterUpdate'? –

+0

Lo uso nel salvataggio eoutine. metti 'UsingSaveButton = True' all'inizio, e impostalo su false alla fine (assicurandoti che ogni gestione degli errori imposta anche il valore su false. Imposta il valore su false su ** form load **, o ** su current ** evento – SeanC

3

Sean ha dato una risposta quasi corretta ma lascia vuoti.

In generale, il FORM BeforeUpdate è l'evento di modulo più importante. È la tua ULTIMA linea di difesa e funziona SEMPRE prima che un record venga salvato indipendentemente da ciò che ha richiesto il salvataggio (chiusura modulo, nuovo record, pulsante di salvataggio, clic su una sottomaschera, ecc.) Anche se occasionalmente utilizzo l'evento BeforeUpdate del controllo solo così l'utente riceve il messaggio di errore prima, la maggior parte del codice di convalida che scrivo viene eseguita nell'evento Form_BeforeUpdate. Questo è l'evento che DEVE usare se si vuole assicurare che certi controlli non siano vuoti. Nessun evento del livello di controllo lo farà in modo affidabile per tutte le situazioni. Principalmente perché se il controllo non ottiene mai la messa a fuoco, nessun evento di livello di controllo si accende mai. Form_BeforeUpdate è anche l'evento che useresti se la tua convalida riguarda più campi.Se stai usando qualsiasi altro evento di controllo o evento, stai perdendo tempo. C'è sempre via intorno alla tua "trappola" e la tua tabella contiene quasi certamente dati non validi.

Per quanto riguarda la domanda dell'OP. Se vuoi forzare le persone a usare il tuo pulsante di salvataggio e a richiederle se non lo fanno, allora hai bisogno di una variabile di livello del modulo come suggerito da Sean. L'unica differenza è che è necessario impostarlo su False, nell'evento Current della form NON sull'evento Open. Vuoi che il flag venga ripristinato per OGNI nuovo record, non solo quando il modulo si apre. Quindi lo imposti su True nel tuo evento di clic sul pulsante di salvataggio, appena prima di forzare il salvataggio del record con DoCmd.RunCommand acCmdSaveRecord.

Infine, nell'evento Form_BeforeUpdate, si controlla il valore della variabile.

If bClose = False Then 
`If msgbox("Do you want to save the changes?", vbYesNo) = vbNo Then 
`  Cancel = True 
     If msgbox("Do you want to discard the Changes?", vbYesNo) = vbYes Then   
      Me.Undo 
     End If 
     Exit Sub 
    End If 
End If 
+1

La formattazione del codice migliorerebbe la tua risposta – ryanyuyu

+1

Questo è davvero molto intelligente. Peccato che questo non mi abbia colpito 3 anni fa –

-1

** è possibile utilizzare il pulsante di uscita con questo codice **

Private Sub Button_Click() 
If Me.Dirty = True Then 
    If MsgBox(" Save Change ", vbYesNo) = vbYes Then 
     Me.Dirty = False 
    Else 
     Me.Undo 
    End If 
End If 
DoCmd.Close acForm, "FormName" 
End Sub 
+1

Non ho votato questa risposta, ma credo che sia stata downvoted perché è solo codice senza descrizione –

+0

grazie per il tuo commento – user3003395

Problemi correlati