I have this BeforeUpdate code to check if certain fields are filled out. These fields are required and must be filled or the record shouldn't save. If other fields have been filled without the ID and Staff field, then the message box prompts pop up (These are required fields, etc.).
Private Sub Form_BeforeUpdate(Cancel As Integer)
If Nz([ID], "") = "" Then
MsgBox "The ID field is required.", vbExclamation, "Required Field"
Cancel = True
End If
If Nz([Staff], "") = "" Then
MsgBox "Staff field is required.", vbExclamation, "Required Field"
Cancel = True
Me.[Staff].SetFocus
End Sub
I have a 'Close Form' button as follows:
Private Sub CmdCloseForm_Click()
DoCmd.Close , ""
End Sub
When this button is clicked, I get the warning that the fields aren't filled, but then the form closes. I want a Yes/No message box asking the user to see if they would still like to close the form or not. I've made a Yes/No messagebox in the BeforeUpdate sub. However it doesn't stop the sub CmdCloseForm.
Is there a way to create a messagebox to confirm if the user wants to exit the form?
For example:
If MsgBox("Would you like to close the form still? Changes won't be saved.", vbYesNo + vbQuestion, "Warning") = vbNo Then
Exit Sub
End If
If I put the above Msgbox into the CmdCloseForm function, it prompts the user before letting them know that they're missing the ID/Staff fields.
I came about this solution by Mr. Craig Dolphin and it worked for me.
The way he approached is to have a generic validation function that is saved in a general purpose module (ie not in a form module).
Public Function validateform(myform As Form) As Boolean
'returns true if all required fields have data, or false if not.
'It will also create a popup message explaining which fields need data
Dim boolresponse As Boolean
Dim strError As Variant
Dim ctl As Control
boolresponse = True
strError = Null
With myform
For Each ctl In .Controls
With ctl
If .Tag = "required" Then
If .Value & "" = "" Then
boolresponse = False
strError = (strError + ", ") & .Name
End If
End If
End With
Next ctl
End With
If strError & "" <> "" Then MsgBox "The following information must be entered first: "
& strError, vbInformation
validateform = boolresponse
End Function
Then, for any fields that are absolutely required, you just set the Tag property of the control to 'required'
You can then, for example, call the function from the onclick event of the 'save' button or 'close' button.
Private Sub Command5_Click()
On Error GoTo Err_Command5_Click
If Me.PrimaryID & "" <> "" Then
If validateform(Me) Then DoCmd.Close
Else
DoCmd.Close
End If
Exit_Command5_Click:
Exit Sub
Err_Command5_Click:
MsgBox Err.Description
Resume Exit_Command5_Click
End Sub
this essentially checks to see if the auto pk field has a value indicating that the record has been created. If it has, then it validates the required fields. If not, it closes without checking. If the record has been created, it validates the form and only closes if all the required fields are filled in. If more data is required, then it pops up a message reminding the user which fields to fill in.
The nice part of this is that you can set conditional requirements using the vba to set the tag property of certain controls to required if another field is updated to a value that you want to trigger an additional requirement. Of course, if you do that then you also need to initialize those tag value in the on_current event for when you switch records.
Many thanks to Mr. Craig Dolphin
Since you want to show consecutive pop-ups, cancel the auto-update altogether and validate on Close.
If validation is successful save the record, if not notify the user.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Cancel = True 'cancel auto-update
End Sub
'Validate and either Save or Close
Private Sub CmdCloseForm_Click()
If Me.Dirty Then
If IsFormValidated Then
DoCmd.RunCommand acCmdSaveRecord
Else
If MsgBox("Would you like to close the form still? Changes won't be saved.", vbYesNo + vbQuestion, "Warning") = vbNo Then Exit Sub
End If
End If
DoCmd.Close acForm, Me.Name, acSavePrompt
End Sub
'Validation
Private Function IsFormValidated() As Boolean
IsFormValidated = True 'assume all is in order
If Nz([ID], "") = "" Then
MsgBox "The ID field is required.", vbExclamation, "Required Field"
IsFormValidated = False
End If
If Nz([Staff], "") = "" Then
MsgBox "Staff field is required.", vbExclamation, "Required Field"
Me.[Staff].SetFocus
IsFormValidated = False
End If
End Function
Related
I have a form where users can edit multiple different pieces of data. This form is based on data pulled from several underlying tables and placed into a temporary table. When a user makes a change and hits the "save" button, any changes made in the form get updated/appended to the underlying data tables and everything in the temp table gets dumped. This all works great.
My problem is with the native close button on the form. If a user makes a change, forgets to hit save, and instead just closes the form, nothing gets saved. I think it's because I need to run my update and append queries (which is what happens with my save button) but I'm unsure how to incorporate them in so they run with the native close button. When I try to add them to the Form_Close event, I get an error message that something in the BeforeUpdate event is preventing Access from saving the data. I know I could remove the close button from the form, but if possible, I would rather leave it in.
Form_BeforeUpdate
txtOld = Nz(Me.Document.OldValue, "")
If Not (Me.NewRecord) Then
If MsgBox("Changes have been made to this record. Save changes?", vbYesNo, "") = vbNo Then
DoCmd.RunCommand acCmdUndo
End If
End If
cmdSave_Click
On Error GoTo Error_Handler
DoCmd.RunCommand acCmdSaveRecord
'check to see if new book field has changed and run append query if it has
If txtOld <> Me.Document.Value Then
DoCmd.OpenQuery "qryUpdateNewBookList"
End If
'This update query should run every time
DoCmd.OpenQuery "qryEditUpdate"
DoCmd.Close acForm, Me.Name, acSaveNo
Form_Close
DoCmd.RunSQL ("DELETE tblEditTbl.* FROM tblEditTbl")
One quick tips. You can use below code to through a message that data is not saved.
Private Sub cmdClose_Click()
If Me.Dirty = True Then
MsgBox "Data is not saved. Save data first then try to close", vbExclamation
Exit Sub
Else
MsgBox "Data saved successfully."
DoCmd.Close
End If
End Sub
Edit: If you want to check it before update then you have to use a variable to check if data is saved or not. Declare a variable at top of form code module like
Option Compare Database
Private blnSaveRecord As Boolean
Use below codes to Save button.
Private Sub cmdSave_Click()
blnSaveRecord = True
DoCmd.RunCommand acCmdSaveRecord
blnSaveRecord = False
End Sub
And finally write below codes to Form_BeforeUpdate event.
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim strMsg As String
If Not blnSaveRecord Then
Cancel = True
strMsg = "Please save the record.," & _
vbNewLine & "or press ESC from keyboard to cancel the operation."
MsgBox strMsg, vbInformation, "Save Record"
End If
End Sub
I solved my problem. Harun24HR got me thinking in the right direction. In addition to my existing code, I needed to use the Form_Unload event and create two public boolean variables to check if the save button had been clicked and if any edits had been made in the form.
Form_Unload
If Not SaveClicked And IsDirty Then
MsgBox "Data is not saved. Save data first and then try to close.", vbExclamation
Cancel = True
End If
I want a msg box to appear if certain fields are empty on close.
Private Sub Close_Click()
If IsNull(Me.startDate) Then
MsgBox “You are in Phase 1”
End If
End Sub
I want the pop up to appear when user clicks the exit x. I tried OnClose. Right now the code is attached to and works via a button.
I’d like the code to be executed when the user closes the form.
Edit New Code:
Private Sub Exit_Click ()
If IsNull(Me.startDate) Or IsNull(Me.stepOneA) Or IsNull(Me.stepOneB) Then
MsgBox “You are in Step I”
DoCmd.Close
ElseIf IsNull(Me.stepTwoA) or IsNull(Me.stepTwoB) or IsNull(stepTwoC)
MsgBox “You are in Step II”
DoCmd.Close
Else
DoCmd.Close
EndIf
End Sub
You can use the UnLoad event for this:
Private Sub Form_Unload(Cancel As Integer)
Cancel = IsNull(Me.startDate)
If Cancel = True Then
MsgBox "You are in Phase 1."
End If
End Sub
I am working with Access Database VBA.
I have noticed if a user has filled a few of the text boxes in and then clicks the windows close button, the form logs that into the records.
I am wondering what is the best way to prevent the form from entering the uncompleted record on close?
There were a few sites pointing to placing a code in the beforeupdate function.
This is what I have tried.
Private Sub frmRecLog_BeforeUpdate(Cancel As Integer)
DoCmd.SetWarnings False
Me.Undo
Cancel = True
Exit Sub
End Sub
This code does not work at all for me.. I tried my best, haha.
Anything helps.
So, what you need is to insert a command button Save. If user do not hit on Save then it will not save any records. They will get a warning that data is not saved. You need declare a private boolean variable and write codes to save and warning. So full code will be like below.
Option Compare Database
Option Explicit
Private blnSaveRecord As Boolean
Private Sub cmdSave_Click()
blnSaveRecord = True
DoCmd.RunCommand (acCmdSaveRecord)
blnSaveRecord = False
End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim strMsg As String
If Not blnSaveRecord Then
Cancel = True
strMsg = "Please save the record.," & _
vbNewLine & "or press ESC from keyboard to cancel the operation."
Call MsgBox(strMsg, vbInformation, "Save Record")
'Me.Undo 'You can set undo option here if you do not want to press ESC.
End If
End Sub
In my userform I want to MsgBox if TextBox not contain Numbers or empty.
This is my code but in another case when the TextBox = "" Empty the MsgBox appear to me, so the issue with me is the empty TextBox.
Private Sub TB1_Change()
If TypeName(Me.TB1) = "TextBox" Then
With Me.ActiveControl
L12.Caption = Val(TB1.Text) * Val(TB2.Text)
If Not IsNumeric(.Value) And .Value <> vbNullString Then
MsgBox "Sorry, only numbers allowed"
.Value = vbNullString
End If
End With
End If
End Sub
Use the Key Press event for this purpose.
Private Sub TB1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If Not IsNumeric(Chr(KeyAscii)) Then KeyAscii = 0
End Sub
This procedure will just ignore anything you enter if it isn't a number, but you can modify both the condition and the output. For example, you might allow a decimal point to be entered, or you might wish to show a message box - perhaps only on the second try.
You may use the AfterUpdate event handler instead of the Change event, might also want to use the Exit event and cancel the exit if the user enters an invalid value:
Option Explicit
Private Sub TB1_AfterUpdate()
'Check whether the value is numeric or empty:
If Not IsValNumeric(Me.TB1.Value) Then
MsgBox "Sorry, only numbers allowed"
Me.TB1.Value = vbNullString
Else:
'Do something...
MsgBox val(TB1.Text) * val(TB2.Text)
End If
End Sub
Private Sub TB1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
'Prevents the user from EXIT the TextBox if value is not numeric/empty
Cancel = Not IsNumeric(Me.TB1.Value)
End Sub
Private Function IsValNumeric(val$) As Boolean
Dim ret As Boolean
'check for numeric value only and allow empty value as a zero value
ret = IsNumeric(val) Or Len(val) = 0
IsValNumeric = ret
End Function
You can wait until the user finishes their input and then test the field.
For usability, the message box should be replaced with a caption and an icon/picture like this "A number must be entered here."
These would be displayed next to the text box when the input is incorrect. Then hidden when the input is corrected. The submission of the form can be blocked until all the errors have been corrected.
This allows the user to enter the request data and then fix any input errors. This is better than stopping them every time they make a mistake.
The event is changed from Change to Exit.
Private Sub TB1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If TypeName(Me.TB1) = "TextBox" Then
With Me.ActiveControl
L12.Caption = Val(TB1.Text) * Val(TB2.Text)
If Not IsNumeric(.Value) Or .Value = vbNullString Then
MsgBox "Sorry, only numbers allowed"
.Value = vbNullString
End If
End With
End If
End Sub
The vbNullString test has also been updated.
Since you are trying to allow only "Numeric" and "Blank" then the code below would deliver your needs.
Private Sub TB1_Change()
if IsNumeric(Me.TB1.Value) = True or Me.TB1.Value = vbNullString then
'Good data, nothing to MSG
Else
MsgBox "Your input data is not valid"
Endif
End Sub
I know this is probably a stupid question, but you know what they say. I have VBA in an Access Database with commands for On Click. Essentially it is a form with a combo box and timestamp for user login. Once the button is clicked a data entry form will load dependent upon which name is selected from the Combo Box. I would like for the Login Form to close once the data entry form has opened. The problem is that no matter where I put the DoCmd.Close the stupid form won't CLOSE!
In case it matters this form is set to open automatically when a user opens the database.
Below is the VBA for the Event Procedure associated with the button.
Option Compare Database
Private Sub TimeInButton_Click()
Dim strLoginForm As String
If Me.AgentCombo = "Amber" Then
strForm = "frmCustomersAmber"
ElseIf Me.AgentCombo = "Amanda" Then
strForm = "frmCustomersAmanda"
ElseIf Me.AgentCombo = "Brett" Then
strForm = "frmCustomersBrett"
ElseIf Me.AgentCombo = "Marcus" Then
strForm = "frmCustomersMarcus"
ElseIf Me.AgentCombo = "Terrah" Then
strForm = "frmCustomersTerrah"
End If
'------------------------------------------------------------
' TimeInButton_Click
'
'------------------------------------------------------------
On Error GoTo TimeInButton_Click_Err
On Error Resume Next
DoCmd.GoToRecord , "", acNewRec
If (MacroError <> 0) Then
Beep
MsgBox MacroError.Description, vbOKOnly, ""
End If
DoCmd.OpenForm strForm
TimeInButton_Click_Exit:
Exit Sub
TimeInButton_Click_Err:
MsgBox Error$
Resume TimeInButton_Click_Exit
End Sub
DoCmd.Close takes optional arguments that will make it much more reliable. For example,
DoCmd.Close acForm, "MyFormName"