In a Microsoft Access form, whenever the current record changes, any changes in bound controls are silently saved to the database tables. This is fine, but I don\'t want it to h
Actually, you cannot trap this, Access is working directly upon the table, every change is already being saved when the field looses the focus by moving to another field, record or a button.
Actually imho this is a great advantage compared to Excel
If you really want a behaviour similar to Excel you'd need to work on a copy of the table and some code for updating.
Sean gave an almost correct answer but it leaves gaps.
In general, the FORM's BeforeUpdate
is the most important form event. It is your LAST line of defense and ALWAYS runs prior to a record being saved regardless of what prompted the save (form close, new record, your own save button, clicking into a subform, etc.) Although I occasionally use the control's BeforeUpdate
event just so the user gets the error message sooner, the bulk of the validation code I write runs in the Form_BeforeUpdate
event. This is the event you MUST use if you want to ensure that certain controls are not empty. No control level event will do this reliably for all situations. Primarily because if the control never gets focus, no control level event ever fires. Form_BeforeUpdate
is also the event you would use if your validation involves multiple fields. If you are using any other control or event level event, you are wasting your time. There is always away around your "trap" and your table almost certainly contains invalid data.
Regarding the OP's question. If you want to force people to use your own save button and prompt them if they don't then you need a form level variable as Sean's suggestion implied. The only difference, is that you need to set it to False, in the form's Current event NOT the Open event. You want the flag to be reset for EVERY new record, not just when the form opens. Then you set it to True in your save button click event, just before you force the record to save with DoCmd.RunCommand acCmdSaveRecord
.
Then finally, in the Form_BeforeUpdate
event, you check the value of the variable.
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
this is code I have that checks to see if the form is being closed or saved.
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
I have a Boolean Flag that is set to False on loading, and then when my Save button is used, I set it to true to allow the update to run through.
If the flag is not set, then they are leaving the record (either through going to a different record, or closing the form) so I ask if they actually want to save the changes.
The Cancel = True
aborts the exit of the form or the move to a different record if any changes have been made.
The DoCmd.RunCommand acCmdUndo
undoes any changes so they are not saved.
** you can use exit button with this code**
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
In the Form in the 'On Unload' event add the below code.
DoCmd.RunCommand acCmdUndo
DoCmd.Quit
Records no longer being saved when users close a form in any way.
You have to work with Form_BeforeUpdate
event. Below is an example; however it does create a typical warning message: "You can't save this record at this time. Microsoft Access may have encountered an error while trying to save a record. ..." - depending on your database settings. You can use simple workaround below to avoid displaying of that message.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Cancel = True
'Or even better you can check certain fields here (If Then...)
End Sub
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If DataErr = 2169 Then
Response = True
End If
End Sub