Refresh All Subform from Another Form - vba

I have two main forms. One is the Dashboard and another is Edit.
After Editing, I have a button to reopen the Dashboard.
It can open the dashboard but I want it to refresh the subforms within that Dashboard.

This module will refresh the form you pass it, as well as all subforms. Requery will normally reset the selected item so before we requery we save the current record. If the record doesn't exist after requery it will gracefully go back to the top without error.
Public Sub RefreshForm(ByRef theForm As Form)
On Error GoTo ErrorHandling
Dim thisRecord As Long
thisRecord = theForm.CurrentRecord
Echo False
Dim childForm As Control
For Each childForm In theForm.Controls
If TypeOf childForm Is SubForm Then
childForm.Requery
End If
Next
With theForm
.Requery
.Recordset.Move thisRecord
End With
ErrorHandling:
Echo True
End Sub
To use it you simply drop this wherever you need a refresh:
RefreshForm Me

You shouldn't need to close and reopen anything. Any opened form and the controls on it can be requeried from VBA code running anywhere. It gets a little convoluted with subforms.
To requery a subform control on the current form: [SubformControlName].Requery
To requery the form in a subform control on the current form: [SubformControlName].Form.Requery
To requery a control in a subform on the current form: [SubformControlName].Form.Controls("ControlName").Requery
To do any of the above operations on a different form in the application, prefix with Forms![FormName].
Example: Forms![FormName].[SubformControlName].Form.Controls("ControlName").Requery

Related

How to Open new form and insert ID from first form, Access [duplicate]

*****EDITED
So I have a form titled "NewInvoice". This form edits a table "Invoice" which contains the following; Invoice Number, Customer, Order Date. In this form I have a button which opens a subform titled "InvoiceItem". This edits a table with the same name that contains Invoice Number, Item Code, Dimensions, Etc.
Now currently, my button has an event procedure as follows.
Private Sub CreateInvoiceItem_Click()
DoCmd.OpenForm "InvoiceItem", OpenArgs:="InvoiceNumber"
End Sub
(The reason I am using a button and opening the form in a separate window is because I have cascading combo boxes in the sub form that become broken when I insert the sub form into the parent form)
Now where I am having trouble is setting the Form Load command. What I would like to occur is that the InvoiceNumber which is filled out in the Parent form auto fills in the sub form when the button is clicked.
Private Sub Form_Load()
**** NEEDED CODE****
End Sub
So try fixing the comboboxes as described in comment under question. Also, recommend code to requery the dependent combobox be in its GotFocus event. Keep in mind, cascading combobox with lookup alias will not work nice in continuous or datasheet form.
If you really want to pass value to independent form, the OpenArgs is a good approach.
Probably need to open the form to a new record row.
DoCmd.OpenForm "InvoiceItem", , , , acFormAdd, acDialog, Me!InvoiceNumber
Need code that makes sure the form is on a new record.
Private Sub Form_Load()
If Me.NewRecord Then Me!InvoiceNumber = Me.OpenArgs
End Sub
I find that the best way to do this is to add a Public sub to the form that you're opening and then pass whatever parameters you need to this function when you open the form. So to do what you're looking to do add a function like this to the form that you're opening;
Public Sub SetUpForm(InvoiceNumber as Long)
txtInvoiceNumber.Value = InvoiceNumber
End Sub
Where txtInvoiceNumber is the control on the form that you want to put the value into.
Then from your button;
DoCmd.OpenForm "InvoiceItem"
Forms!InvoiceItem.SetUpForm InvoiceNumber
This will pass your value for the invoice number to the control on the form that you're opening. This also gives you a lot more flexibility to control the process because you can pass more than one parameter to the sub and in the sub you can perform any number of tasks.

How to close a userform when another userform or a blank space is selected in excel VBA?

Whenever people clicks on the Debit Account or Credit Account fields on the userform, another userform with a Treeview will pop-out. However, the user will always have to press cancel in order to close the userform. Is there a way for the userform to automatically close when the Voucher Entry Form userform's area is selected?
If the question is "How to unload a user-form if it is not more the active object?" then the user-form in question must be modeless. Because else it cannot be deactivated without closing it's window. And because it is not possible opening a modeless user-form from a modal userform, the main user-form also must be modeless.
Example:
Do having two user-forms:
First user-form is named "MainForm" and has one button control and the following code applied:
Private Sub CommandButton1_Click()
Load SubForm
SubForm.Show vbModeless
SubForm.Left = Me.Left + 100
SubForm.Top = Me.Top + 100
End Sub
Second user-form is named "SubForm" and can be empty but has following code applied:
Private Sub UserForm_Deactivate()
Unload Me
End Sub
Then following Sub within a default module shows the main form:
Sub test()
MainForm.Show vbModeless
End Sub
Now after MainForm is shown, SubForm can be opened by button click. And if MainForm get the active form again (gets the focus again), the SubForm will unload.

How to requery form opened by another user

this may seem like an odd question, but I am wanting to requery a form that is opened by another user. Basically I have two different main menus, that pertain to the role of the employee. On these main forms I display a menu with the counts of clients in each status. I then have a main form that holds the clients data. After I update the status field I am requery both forms. Now this requerys the menu that is open on the current user that changed the status, but it doesn't requery the other menu that is opened by the other user unless they close the menu and reopen. Is this possible to requery another subform of another user's form.
Here is my code below:
Private Sub status_ID_AfterUpdate()
On Error GoTo Problems
DoCmd.RunCommand acCmdSaveRecord
Forms!frmNursesMenu!frmStatusCount_Nurses.Form.Requery
Forms!frmNursesMenu!frmStatusCount_Nurses.Form.Repaint
Forms!frmNursesMenu.Requery
Forms!frmNursesMenu.Repaint
Forms!frmAdminMenu!frmStatusCount.Form.Requery
Forms!frmAdminMenu!frmStatusCount.Form.Repaint
Forms!frmAdminMenu.Requery
Forms!frmAdminMenu.Repaint
Exit Sub
Problems:
Err.Clear
Resume Next
End Sub
You will need to use the form's timer event to requery the form every so often or look to see if the form needs a requery.
If your tables include a column with the time of the last edit then you could use that to see if the form needs a requery.

can docmd.gotorecord,,acnew open in new window?

I have a form which is bound to a table, and lets a user scroll through existing records in the table and make changes. I'm now trying to build a button which allows the user to insert a new record. So far I have a button with some basic vba:
Private Sub btnNew_Click()
DoCmd.GoToRecord , , acNewRec
End Sub
This opens a new record in the same form and has no way of assuring a user that the record has been saved. What i would really like is for the this to open a new 'pop up'form with a save button on
how would i do this?
Go to the design view of the Form, add a button name it saveBtn. Under its properties, set the visibility as No. Now in the Form Current method, check if the form has the new record, if so make the button visible.
Private Sub Form_Current()
Me.saveBtn.Visible = Me.NewRecord
End Sub
Using this method, the current form could be used for navigation and editing and when it sits on a new record a Save button will be available where in you could add the code to run a Save command or close the Form, which by default will save the record.

Save record in subform

I have a main form with a tab control containing multiple subforms. I need to be sure that the data in a subform is saved when the user switches tabs. The problem is that DoCmd.RunCommand acCmdSaveRecord seems only applies to the current form so it doesn't save the data in the subform.
I have tried different events on the subform such as deactivate, OnLostFocus etc but they don't fire until another field somewhere else gets the focus.
The ideal solution would seem to be to put something on the OnChange event of the tab control to be sure that all the data is saved. That is my question, how to do I save the record in a subform?
In Access, the default is to save, so unless you have done something pretty complicated to prevent this, moving the focus from a subform will automatically save the record. You can test this by adding a record, moving from the subform, and then checking the table.
You don't have to do anything at all, as the subform is saved as soon as it loses focus (when the tab control changes).
But as an exercise, I've outlined the code you'd write if you needed to.
You can save any form by setting it's .Dirty property to False. For something like this that's going to run a lot, I think I'd write a sub to walk through the subforms, check if any are dirty, and save the dirty ones. Something like this:
Public Sub SaveSubFormsOnTab()
Dim pge As Control
Dim ctl As Control
For Each pge In Me!ctlTab.Pages
Debug.Print pge.Name
For Each ctl In pge.Controls
If ctl.ControlType = acSubform Then
If ctl.Form.Dirty Then
ctl.Form.Dirty = False
End If
Debug.Print ctl.Name
End If
Next ctl
Next pge
Set ctl = Nothing
Set pge = Nothing
End Sub
Now, that's actually quite inefficient in cases where you have lots of controls on your tab control that aren't subforms. If your tab has nothing but subforms, it will be fairly efficient. In either case, it's much more efficient to use a custom collection populated in the form's OnLoad event, and then you'd walk that collection that includes nothing but your tab control's subforms, and save any that are dirty.
Either of these is preferable to using the OnChange event of the tab, because each time you add a tab page with a subform or change the name of a subform control, you'd have to alter the OnChange event.
I was having a similar issue where I needed various code to run in the subform and values in the main form - that were based on values in the subform - to be recalculated. Here is what finally worked:
This is an example with a main form named 'frmCustomers' containing a subform 'sfmTransaction', which in turn has a subform called 'sfmOrderLine'. The forms have a button 'cmdSave' that is only visible when the user clicks the 'cmdEdit' button (the purpose of which is to lock all the controls until the user clicks the edit button, and then to re-lock them when he clicks save):
On the main form ('frmCustomer') go the subform's exit event, and add 'me.recalc' twice, like this:
Private Sub sfmTransaction_Exit(Cancel As Integer)
If (Not Form_sfmTransaction.NewRecord And Form_sfmTransaction.cmdSave.Visible) Or (Not Form_sfmOrderLine.NewRecord And Form_sfmOrderLine.cmdSave.Visible) Then
'To save subforms
Me.Recalc
Me.Recalc
End If
End Sub
In the subform ('sfmTransaction') go the subform's subform's exit event, and add 'me.recalc' twice, like this:
Private Sub sfmOrderLine_Exit(Cancel As Integer)
If Not Form_sfmOrderLine.NewRecord And Form_sfmOrderLine.cmdSave.Visible Then
'To save subform
Me.Recalc
Me.Recalc
End If
End Sub
Hope this helps.
Setting the dirty property to false may force Access to save the data to the database, but it bypasses the before_update event. This means that if you've used this event for validation or other purposes, you can now have bad data in your database.