Salvare i dati su Form_Close

di il
8 risposte

Salvare i dati su Form_Close

Buonasera a tutti, come da titolo ho questo problemino, ho cercato in rete ma sembra che non riesco a venirne a capo.

Il codice che vi posto, inserito su una form, in fase di chiusura funziona correttamente
Private Sub Form_Close()
On Error Resume Next

    Beep
    If MsgBox("Salvare le modifiche prima di uscire?", vbYesNo + vbQuestion, "Prova chiusura form") = vbNo Then
        Me.Undo
        Cancel = True
        DoCmd.DoMenuItem acFormBar, acEditMenu, acUndo, , acMenuVer70
    End If
    DoCmd.Close acForm, "FormProva"
End Sub
Se clicco sul pulsante si, salva e chiude mentre se clicco sul pulsante no chiude senza salvare modifiche.

Perchè se lo stesso ed identico codice, lo inserisco su un altra form non funge? E mi chiede, inoltre, di definire la variabile "Cancel"?
L'unica differenza è che, se lanciato su una form a Maschera singola funge mentre su una maschera continua, anche se clicco sul pulsante no, mi da quindi errore per l'oggetto non dichiarato. Se lo dichiaro come Integer e clicco su no, mi salva comunque i dati...

8 Risposte

  • Re: Salvare i dati su Form_Close

    Non si fa in quel modo, e che possa funzionare correttamente... molto discutibile, nemmeno voglio sapere dove lo hai copiato, dal momento che è un'accozzaglia di errori tecnico e concettuali.

    Gli eventi che si DEVONO usare per poterne gestire l'annullamento sono di solito quelli chiamati BEFORE[NomeVento].
    Il prefisso [Before] appunto indica PRIMA... questi Eventi espongono il parametro CANCEL che appunto serve per annullare l'evento, parametro che nel CLOSE non esiste, quindi non serve... come non serve mettere il CLOSE nell'evento Close...

    Quindi prova a verificare l'evento UNLOAD che anche se non ha prefisso BEFORE, si verifica prima di chiudere, e guardacaso espone il parametro CANCEL.
    Su Unload verifichi la proprietà DIRTY, in caso sia vera chiedi se vuole salvare..., quindi forzi il Salvataggio, e poi si chiude se no forzi CANCEL=True...

    Tuttavia a mio avviso l'evento giusto sarebbe BeforeUpdate.
  • Re: Salvare i dati su Form_Close

    Ciao Alex, ti ringrazio per la risposta...seguendo il consiglio (non ho inteso se procedere prima con l'Unload e poi con il BeforeUpdate) ho cercato di correggere così ma penso manchi qualcosa
    Private Sub Form_BeforeUpdate(Cancel As Integer)
        If Me.Dirty = True Then
            If MsgBox("Salvare le modifiche?", vbQuestion + vbOKCancel, "Prova chiusura form") = vbOK Then
            'qualsiasi cosa inserisco mi da errore relativo all'BeforeUpdate
            Else
                Cancel = True
                Me.Undo
            End If
        End If
    End Sub
    Se clicco sul no mi da l'avviso "...che è impossibile salvare il record in questo momento"...in realtà è quello che voglio ma senza avviso
    P.S. ho provato a forzare il salvataggio ma dv ho scritto che qualsiasi cosa inserisco mi da errore, mi riferivo proprio al forzare il salvataggio o chiusura maschera
  • Re: Salvare i dati su Form_Close

    Si manca un pezzetto, in quanto l'azione di Update interagisce con l'azione di Close che si invoca premendo la X mentre il Record è in Dirty...
    Quindi in sostanza si viene a creare un Annullamento di una azione(il CLOSE) ma in seguito ad un Condizionamento esterno(l'utente che seleziona NO)...!
    Ne consegue che serve insegnare al Sistema che in questo caso è tutto a posto, e gestito regolarmente, quindi si evita l'errore.

    Ti allego una veloce possibilità di come gestire:
    Option Compare Database
    Option Explicit
    
    Private Const ERR_SAVINGFAILURE = 2169
    
    Private DoNotClose  As Boolean
    
    Private Sub Form_Unload(Cancel As Integer)
        Cancel = DoNotClose
        If DoNotClose Then DoNotClose = False
    End Sub
    
    Private Sub Form_BeforeUpdate(Cancel As Integer)
        Const cProcName = "Form_BeforeUpdate"
    
        On Error GoTo Err_Handler
    
        If Me.Dirty = True Then
            If MsgBox("Salvare le modifiche?", vbQuestion + vbYesNo, "Prova chiusura form") <> vbYes Then
                Cancel = True
                Me.Undo
                DoNotClose = True
            End If
        End If
    Exit_Here:
        Exit Sub
    
    Err_Handler:
        Select Case Err.Number
            Case Else
                MsgBox Err.Number & " in " & Me.Name & vbNewLine & Err.Description, vbCritical, cProcName 
        End Select
    
        Resume Exit_Here
    End Sub
    
    Private Sub Form_Error(DataErr As Integer, Response As Integer)
        Select Case DataErr
            Case Is = ERR_SAVINGFAILURE:        Response = acDataErrContinue
            Case Else:                          Response = acDataErrDisplay
        End Select
    End Sub
  • Re: Salvare i dati su Form_Close

    Ciao Alex, suggerimento superlativo come sempre!

    Però in fase di chiusura della maschera, nel caso in cui vengono apportate modifiche, mi chiede 2 volte se voglio salvare le modifiche. Stessa cosa se voglio passare da un record all'altro (maschera continua). Poichè l'evento legge tutte le possibili modifiche nella form, è possibile lanciare la verifica di salvataggio solo in fase di chiusura maschera?
  • Re: Salvare i dati su Form_Close

    zio Ken ha scritto:


    Ciao Alex, suggerimento superlativo come sempre!

    Però in fase di chiusura della maschera, nel caso in cui vengono apportate modifiche, mi chiede 2 volte se voglio salvare le modifiche. Stessa cosa se voglio passare da un record all'altro (maschera continua). Poichè l'evento legge tutte le possibili modifiche nella form, è possibile lanciare la verifica di salvataggio solo in fase di chiusura maschera?
    Da me chiede SOLO 1 Volta... quindi devi aver introdotto qualche cosa di conflittuale.
    Se sei in maschera continua NON CHIEDE nulla se non fai modifiche, se invece fai modifiche ovviamente si... ad ogni Record in quanto attiva giustamente il BeforeUpdate.

    Detto questo, così come è ora non puoi delegare alla Chiusura alcun controllo.
    Lo stesso metodo che avevi accennato inizialmente ti avrebbe fatto la domanda di Conferma modifiche anche in caso NESSUNA modifica fosse stata apportata... cosa assurda ovviamente.
    Per capire come mai dovresti analizzare la sequenza Eventi...!
    In sostanza, se premi [X] di chiusura dovrebbe accadere questo:
    BeforeUpdate (form) ---> AfterUpdate (form) ----> Unload(Form) ----> Deactivate(Form) ----> Close(Form)
    Il BeforeUpdate si scatena se Dirty=True, ma appena l'evento viene confermato, Dirty=False, di conseguenza non hai più modo di sapere se sono state fatte modifiche...

    Per fare quello che vuoi quindi devi impedire la chiusura non gestita, quindi DISABILITARE/RIMUOVERE il Comando [X] di chiusura standard e mettere nella Form un Button preposto alla chiusura.
    Questo gestirà sia la verifica di Dirty(ed eventuale Question) che la Chiusura di conseguenza...
    Purtroppo devi arginare anche ALT+F4 che ti chiuderebbe tutto... sicchè devi implementare sempre una gestione dell'Evento UNLOAD...
    
    Option Compare Database
    Option Explicit
    
    Private DoNotClose  As Boolean
    
    Private Sub cmdClose_Click()
        If Me.Dirty = True Then
            If MsgBox("Salvare le modifiche?", vbQuestion + vbYesNo, "Prova chiusura form") = vbNo Then
                Me.Undo
            Else
                DoNotClose = False
                DoCmd.RunCommand acCmdSaveRecord
                DoCmd.Close acForm, Me.Name
            End If
        End If
    End Sub
    
    Private Sub Form_Current()
        DoNotClose = False
    End Sub
    
    Private Sub Form_Dirty(Cancel As Integer)
        DoNotClose = True
    End Sub
    
    Private Sub Form_Error(DataErr As Integer, Response As Integer)
        Select Case DataErr
            Case Is = ERR_SAVINGFAILURE:        Response = acDataErrContinue
            Case Else:                          Response = acDataErrDisplay
        End Select
    End Sub
    
    
    Private Sub Form_Unload(Cancel As Integer)
        Cancel = DoNotClose
    End Sub
    
  • Re: Salvare i dati su Form_Close

    Rieccomi, ho implementato il codice come mi hai segnalato ed ho aggiunto quest'implementazione trovata in rete che disabilita quindi la combinazione tasti ALT+F4
    Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Dim intAltDown As Integer
    intAltDown = (Shift And acAltMask) > 0
    
    Select Case KeyCode
      Case vbKeyF4
        If intAltDown Then
          KeyCode = 0
          MsgBox "Alt+F4 è stato disabilitato.", vbExclamation + vbOKOnly, "Combinazione tasti disabilitata"
        End If
    End Select
    End Sub
    Ora succede che, anche se non effettuo modifiche e clicco sul bottone cmdClose mi chiede se voglio salvare le modifiche,come se Dirty venisse forzato sempre a vero mentre se clicco ok si chiude la maschera e salva, se clicco su no mi annulla le modifiche ma non chiude la maschera.
    Tutto il codice nel 3d da te segnalato, penso sia utilissimo per prendere spunto a chiunque affronta questa problematica poichè in rete si trova un po' tutto ma non così approfonditamente!!!
  • Re: Salvare i dati su Form_Close

    NOn so cosa suggerirti... ci sono comportamenti che ti ho segnalato anomali già prima... ed io non ho modo di capire, devi assolutamente dedicarti a DEBUGGARE in autonomia.
  • Re: Salvare i dati su Form_Close

    Okok, seguirò i tuoi preziosissimi consigli!
Devi accedere o registrarti per scrivere nel forum
8 risposte