I have a parent form that I click a button which launches a second form for further user input, once those values are input I then need to return the values to the parent form. How do I return values from the second form to the first form?
This is my current code:
'Form 1 - Main Form called frmFirstSet
Private Sub cmdDoStep1_Click()
'Declare Variables
Dim OrderNumber As String
'Get the OrderNumber
OrderNumber = Me.[frmDLZC].Form!OrderNumber
'Open the second form for data Capture
DoCmd.OpenForm "frmInputValues", acNormal
'Return variables from frmInputValues
Debug.Print green
Debug.Print red
Debug.Print orange
End Sub
'Form 2 - Secondary Form launched for data capture
Private Sub cmdReturnToStep1_Click()
Dim green As String, red As String, orange As String
'Ensure all values have been input
If IsNull(Me!txtgreen) Then
MsgBox "Please Input the Value for green", vbOKOnly
Me.txtgreen.SetFocus
Exit Sub
Else
green = Me.txtgreen
End If
If IsNull(Me!txtred) Then
MsgBox "Please Input the Value for red", vbOKOnly
Me.txtred.SetFocus
Exit Sub
Else
red = Me.txtred
End If
If IsNull(Me!txtorange) Then
MsgBox "Please Input the Value for orange", vbOKOnly
Me.txtorange.SetFocus
Exit Sub
Else
orange = Me.txtorange
End If
'How to return these variables to the original form
End Sub
There are a lot of ways to pass values from one form to another. I prefer to read value directly from the form. I create a public function, which returns required information. Something like this:
Public Function DialogInputBox(strHeader As String, Optional strValueLabel As String) As String
On Error Resume Next
' make sure that hidden window closed
DoCmd.Close acForm, "frm_InputDialog"
On Error GoTo ErrorHandler
' open the form in dialog mode
DoCmd.OpenForm "frm_InputDialog", WindowMode:=acDialog, OpenArgs:="Header=" & strHeader & "|ValueLabel=" & strValueLabel
' when control returns here, the form is still open, but not visible
DialogInputBox = Nz(Forms("frm_InputDialog").txtValue, "")
' close the form
DoCmd.Close acForm, "frm_InputDialog"
ExitHere:
Exit Function
ErrorHandler:
MsgBox "Error " & Err.Number & " (" & Err.Description & "), vbExclamation + vbMsgBoxHelpButton"
Resume ExitHere
End Function
The dialog form accepts arguments thru OpenArgs parameter and when user clicks Ok or Cancel buttons, we hide the dialog form instead of closing:
Private Sub cmdConfirm_Click()
If Len(Nz(Me.txtValue, "")) = 0 Then
MsgBox "Please enter value", vbExclamation, GetDBName()
Me.txtValue.SetFocus
Exit Sub
End If
' return execution control to the public called function
Me.Visible = False
End Sub
I we need to return few values, use function parameters by reference.
Related
On the Form_beforeupdate() event of my form "Alias" I have this...
If IsNull(Me.txtFName) And IsNull(Me.txtLName) Then
MsgBox "You must enter a contact!", vbokayonly, "Contact"
Cancel = True
End If
Anytime this cancels a runCommand code such as...
DoCmd.RunCommand acCmdSaveRecord
a dialog appears telling me that it was canceled. Is there a way to suppress those dialogs?
You can add an error handler to trap and ignore error 2501, which is triggered when the form's Before Update event cancels DoCmd.RunCommand acCmdSaveRecord
The following example is from my form which has a command button to save the current record. It suppresses that "RunCommand action was canceled" message as I think you wish.
Since your form's code apparently calls DoCmd.RunCommand acCmdSaveRecord from multiple locations, replace each of those calls with SaveRecord as I did in cmdSave_Click().
Option Compare Database
Option Explicit ' <-- NEVER troubleshoot VBA code without this!!!
Private Sub cmdSave_Click()
'DoCmd.RunCommand acCmdSaveRecord
SaveRecord
End Sub
Private Sub SaveRecord()
Dim strMsg As String
On Error GoTo ErrorHandler
DoCmd.RunCommand acCmdSaveRecord
ExitHere:
Exit Sub
ErrorHandler:
Select Case Err.Number
Case 2501 ' The RunCommand action was canceled.
' do nothing --> just ignore the error
Case Else
' notify user about any other error
strMsg = "Error " & Err.Number & " (" & Err.Description _
& ") in procedure SaveRecord"
MsgBox strMsg
End Select
Resume ExitHere
End Sub
Private Sub Form_BeforeUpdate(Cancel As Integer)
If IsNull(Me.txtBlock_start.Value) Then
MsgBox "You must enter a start time!", vbOKOnly, "Start Time"
Cancel = True
End If
End Sub
I ended up doing this on a 'Save and Open the Receipts form' button.
Private Sub btnSaveOpenReceipts_Click()
'''''SaveRecord'''''
If (Me.Dirty) Then
SaveRecord
End If
'''''OpenReciepts'''''
If (Me.Dirty) Then 'unsure it saved
Exit Sub
Else
'blah blah blah
End If
End Sub
I have put the VBA in Unload Form Event in ms access 2010
Private Sub Form_Unload(Cancel As Integer)
Dim strMsg As String
Dim iResponse As Integer
' Specify the message to display.
strMsg = "Do you wish to save the changes?" & Chr(10)
strMsg = strMsg & "Click Yes to Save or No to Discard changes."
' Display the message box.
iResponse = MsgBox(strMsg, vbQuestion + vbYesNoCancel, "Save Record?")
' Check the user's response.
If iResponse = vbYes Then
' Undo the change.
DoCmd.RunCommand acCmdSave
End If
If iResponse = vbNo Then
' Undo the change.
DoCmd.RunCommand acCmdUndo
End If
If iResponse = vbCancel Then
' Undo the change
Cancel = True
End If
End Sub
If data is changed then the above code is working fine, then yes to save & close, No to undo & close and cancel to cancel event and remain on the form
but when the data is unchanged then Yes button is working fine, but NO button do not close the form
Where I m mistaking ?
Your question is too vague because you simply state "NO button do not close the form."
You can do:
DoCmd.Close
See here:
Private Sub cmdCloseForm_Click()
On Error GoTo Err_cmdCloseForm_Click
DoCmd.RunCommand acCmdUndo 'OR Me.Undo - test which works best for your situation
DoCmd.Close
Exit_cmdCloseForm_Click:
Exit Sub
Err_cmdCloseForm_Click:
MsgBox Err.Description
Resume Exit_cmdCloseForm_Click
End Sub
On Me.Undo from Allen Browne:
Me.Undo cancels the edits in a specific form, so that it is no longer dirty.
Once the form is no longer dirty, no further undo is possible, because it
has reached the desired state. However, Me. represents the form that is in focus, so your form must have focus to perform the Me.Undo command.
I have an Access form with a textbox that is meant to allow for repeatedly typing a number, hitting enter, and letting a script do stuff. For speed, the field should keep the focus after DoStuff() is done.
However, while I'm sure that DoStuff() is run, the focus always goes to the next field in the tab order. It's like Me.MyFld.SetFocus is being ignored.
How do I keep the focus on this field after DoStuff() is done?
Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyReturn Then
DoStuff
Me.MyFld.SetFocus
End If
End Sub
If you look at the order of events for a keypress that would change focus, you can see that it always follows this pattern:
KeyDown → BeforeUpdate → AfterUpdate → Exit → LostFocus
You can re-set the focus anywhere in there and it will still keep following the pattern. So we need to tell it to stop following the pattern. Replace your Me.MyFld.SetFocus with DoCmd.CancelEvent and it should fix your problem. Basically, this just kicks you out of the above pattern, so the Exit and LostFocus events never fire...
A workaround is moving the focus to another control and then back to the first control. Like this:
Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyReturn Then
DoStuff
Me.anotherControl.SetFocus
Me.MyFld.SetFocus
End If
End Sub
click on access options
select Advanced
select Don't move from Move after enter
click ok
It will work 100%
Try removing the whole line for variable_name.SetFocus and simply add:
Cancel = True
Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyReturn Then
DoStuff
Cancel = True
End If
End Sub
Another solution to the problem that I use in Excel.
Let there exist UserForm1 with the TextBox1 and CommandButton1 controls.
Code in the form module:
Option Explicit
Private Sub CommandButton1_Click()
Unload Me
End Sub
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = vbKeyReturn Then
'Call DoStuff
Application.OnTime Now, "'Control_SetFocus """ & Me.Name & """, """ & Me.ActiveControl.Name & """ '"
' The concatenation returns a string: 'Control_SetFocus "UserForm1", "TextBox1"'
End If
End Sub
And code in the standard module:
Option Explicit
Sub Control_SetFocus(FormName As String, ControlName As String)
Dim oUserForm As Object
Set oUserForm = GetFormByName(FormName)
If Not oUserForm Is Nothing Then
oUserForm.Controls(ControlName).SetFocus
End If
End Sub
Function GetFormByName(FormName As String) As Object
Dim oUserForm As Object
On Error GoTo ErrHandle
For Each oUserForm In VBA.UserForms
If StrComp(oUserForm.Name, FormName, vbTextCompare) = 0 Then
Exit For
End If
Next oUserForm
If oUserForm Is Nothing Then
Set oUserForm = UserForms.Add(FormName)
End If
Set GetFormByName = oUserForm
Exit Function
ErrHandle:
Select Case Err.Number
Case 424:
MsgBox "Userform " & FormName & " not exists.", vbExclamation, "Get userform by name"
Case Else:
MsgBox Err.Number & ": " & Err.Description, vbCritical, "Get userform by name"
End Select
End Function
Artik
An easy solution that works in Excel is to set the KeyCode to 0. If DoStuff steals the focus then you should also set the focus back:
Private Sub MyFld_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyReturn Then
DoStuff
KeyCode = 0
Me.MyFld.SetFocus
End If
End Sub
Is it at all possible to detect an insert operation performed by a subform while still in the parent form?
To clarify: I have a series of forms for data entry, they each have a button for adding an entry to the appropriate table (using the data provided in the form). I am attempting to set each of them in turn to a subform in a 'wizard' parent form that will cycle through all the data entry forms.
My problem arises when it comes to switching between forms, as it became clear that the AfterInsert event in this parent form was not detecting the insert triggered by the form contained in the subform. I know I could move the trigger for the insert to a button in the parent form; however, to my knowledge, this would require setting the code for the click event for each of the buttons in the data entry forms as public so that they may be called from the parent form's code. I am leery to do this and was thus hoping for other options.
Create a public procedure in the parent form.
Public Sub Listener(ByVal pMsg As String)
MsgBox pMsg
End Sub
Then, in each of your subforms, call that procedure from After Insert.
Private Sub Form_AfterInsert()
Dim strMsg As String
strMsg = Me.Name & " inserted row."
Call Me.Parent.Listener(strMsg)
End Sub
If the subform may also be used stand-alone (without a parent), Me.Parent will throw error #2452, "The expression you entered has an invalid reference to the Parent property." You can create a separate function to check whether the current form has a parent, and base your code on the function's return value.
Private Sub Form_Open(Cancel As Integer)
Dim strPrompt As String
If HaveParentForm(Me) = True Then
strPrompt = "I am a subform to '" & _
Me.Parent.Name & "'."
Else
strPrompt = "I am a top level form."
End If
MsgBox strPrompt
End Sub
The function ...
Public Function HaveParentForm(ByRef frm As Form) As Boolean
Dim blnReturn As Boolean
Dim strMsg As String
On Error GoTo ErrorHandler
blnReturn = (Len(frm.Parent.Name) > 0)
ExitHere:
HaveParentForm = blnReturn
On Error GoTo 0
Exit Function
ErrorHandler:
Select Case Err.Number
Case 2452 ' The expression you entered has an invalid '
' reference to the Parent property. '
Case Else
strMsg = "Error " & Err.Number & " (" & Err.Description _
& ") in procedure HaveParentForm"
MsgBox strMsg
End Select
blnReturn = False
GoTo ExitHere
End Function
Can someone please help me on this find specific record Edit through MS access Forms
I have Frmfind form where I have one filed "ticket#" is a input text box
another filed was button "find"
When I enter ticket# which is primary key for my table. I need get the the specific ticket# record should be opened in FormEdit mode using VBA code...
So I have another form "frmEdit" of specific record which has to be called from frmfind -> specific input..
note: Ticket# is column in my table whcih it is primary to have the ticket#.
Code:
Option Compare Database
Private Sub find_Click()
If IsNull(Me.Text79) Or Me.Text79 = "" Then
MsgBox "You must enter a Ticket #", vbOKOnly, "Required Data"
Me.Text79.SetFocus
Exit Sub
End If
If [Ticket#] = Me.Text79.Value Then
MsgBox "Record found"
DoCmd.Close
DoCmd.OpenForm "frmEdit"
Else
MsgBox "not matching record"
Me.Text79.SetFocus
End If
End Sub
Private Sub Form_Open(cancel As Integer)
'On open set focus to text box
Me.Text79.SetFocus
End Sub
You can use this code:
Private Sub Command112_Click()
Me.txtSeach.SetFocus
On Error Resume Next
DoCmd.OpenForm "frmEdit", , , "TicketNumber = '" & Nz(Me.text79, "") & "'"
End Sub
Note in above if TicketNumber is in fact a number column and not text, then remove the single quotes and use this:
DoCmd.OpenForm "aa", , , "TicketNumber = " & Nz(Me.text79, "")
Then for your message, just place that code in the forms on-open event that has a cancel:
eg:
Private Sub Form_Open(Cancel As Integer)
If IsNull(Me!TicketNumberID) Then
MsgBox "Please enter a valid Ticket #", vbOKOnly, "Required Data"
Cancel = True
End If
End Sub
The above assumes your search column is ticket number.
You can also use dlookup(), or even dcount(). I think above is less code, but:
Dim strWhere As String
strWhere = "TicketNumber = " & Me.text79
If DCount("*", "tblBookings", strWhere) > 0 Then
code for Record found goes here
Else
code reocrd not found code here
End If
So either way should suffice here.