Here is an example of BeforeUpdate event for a form in one of my apps.
Code:
Private Sub Form_BeforeUpdate(Cancel As Integer)
' fChemReg.BeforeUpdate
' Seting error processing
On Error GoTo ExitNow
Dim strCurrCatalogue As String
Dim strCurrChemCode As String
Dim strCurrSiteCode As String
Dim intFound As Integer '3 - Catalogue and ChemCode and SiteCode; 2 - Catalogue and ChemCode, 1 - Catalogue or ChemCode or neither
strCurrCatalogue = Me.cbbCR_Catalogue.Value
strCurrChemCode = Me.cbbCR_ChemCode.Value
strCurrSiteCode = GetGlobal("gbl_SiteCode")
intFound = DCount("SiteCode", "D_ChemSite", "Catalogue = '" & strCurrCatalogue & "' AND ChemCode = '" & strCurrChemCode & "' AND SiteCode = '" & strCurrSiteCode & "'")
If intFound = 0 Then
intFound = DCount("SiteCode", "D_ChemSite", "Catalogue = '" & strCurrCatalogue & "' AND ChemCode = '" & strCurrChemCode & "'")
If intFound = 0 Then
intFound = 1 ' this combimnation of catalogue and chemical code was not found in any of sites
Else
intFound = 2 ' this combimnation of catalogue and chemical code was found at least in one of another sites
End If
Else
intFound = 3 ' this combimnation of catalogue and chemical does exist for this site
End If
If (Nz(Me.cbbCR_Catalogue.Value, "") = "" Or Nz(Me.cbbCR_ChemCode.Value, "") = "") Then
MsgBox "Discard the new record (Esc), or fill both Catalogue and Chemical Code to proceed!"
Cancel = True
ElseIf intFound = 3 And Me.NewRecord = False Then
ElseIf intFound = 3 And Me.NewRecord = True Then
MsgBox "Such chemical is registered for this site! Discard the new record (Esc), or register another chemical!"
Cancel = True
ElseIf intFound = 2 Then
MsgBox "Such chemical was registered elsewhere! It will be linked with your site now!"
CurrentDb.Execute "INSERT INTO D_ChemSite (SiteCode, Catalogue, ChemCode) VALUES ('" & strCurrSiteCode & "', '" & strCurrCatalogue & "', '" & strCurrChemCode & "')"
Else
MsgBox "A new chemical will be registered!"
CurrentDb.Execute "INSERT INTO D_ChemSite (SiteCode, Catalogue, ChemCode) VALUES ('" & strCurrSiteCode & "', '" & strCurrCatalogue & "', '" & strCurrChemCode & "')"
End If
ExitNow:
End Sub
The code row "Cancel = True" stops saving and returns the form to the state it had before saving was attempted. Then user can:
a) make corrections and try to save again;
b) press "Esc". This discards the new record. Record pointer is set to last record in recordset.
All messaging is made in BeforeUpdate event. This is most reasonable, because mostly the checking code is same, and there is no reason to make this twice.
About saving only when button is pressed:
1. Define a global variable, e.g. booSaving, with initial value False;
2. When button is pressed, booSaving is set True, and the command to update the record is given. After that BeforeUpdate event takes over;
3. The 1st step for BeforeUpdate event is to check booSaving. When it is False, then Cancel, otherwise proceed;
4. Whatever is final outcome of BeforeUpdate event, booSaving must be set False finally.