How to requery form opened by another user - vba

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.

Related

Refresh All Subform from Another Form

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

MS Access will occasionally remove checkboxes from my Yes/No fields and replace them with 0 and -1

My new database is built using a variety of queries and tables. These tables and queries have two checkbox fields that are set for "Test" and "Approved". The way that these come into play is that I have buttons on one form called "ApprovalForm" that open up another form called "ViewForm". The goal was that "ViewForm would change its subform's source object every time one of these buttons is clicked. ApprovalForm closes itself first, then ViewForm opens, then Subform.SourceObject is updated to the query specified by whatever button was clicked.
Private Sub View_NonSize_APL_Click()
On Error GoTo View_NonSize_APL_Click_Err
DoCmd.Close acForm, ("ApprovalForm")
DoCmd.OpenForm ("ViewForm")
Forms!ViewForm!View_Subform.SourceObject = "Query.NonSize - APL View"
Forms!ViewForm!View_Subform.Form.Requery
Forms!ViewForm.Form.Requery
Forms.ViewForm.Caption = "NonSize - APL View"
View_NonSize_APL_Click_Exit:
Exit Sub
View_NonSize_APL_Click_Err:
MsgBox Error$
Resume View_NonSize_APL_Click_Exit
End Sub
With the process finished, the final result should be that the fields are populated by the query, which is looking at a table off on the side. The user has no access to the table itself, just that specific select query. However, in rare occasions, the checkboxes will not load correctly, instead displaying as 0s and -1s. What is peculiar about this is that when you click the button on "ViewForm" that leads back to "ApprovalForm" and click the same exact button AGAIN, the checkboxes load correctly.
My guess is that it has something to do with how "ViewForm" loads in, and due to it being a business project, the computer that it is working on is less than optimal. I tried to remedy the situation by using "Requery" and "Refresh" in the code to hopefully reload the process. I have also tried the cumbersome route of having the form close after being loaded and immediately reloading again. (Open the form, load its query, close the form, then open the form again.) That actually proved to ruin the entire process.
Is there anything I can do to counter this problem?

How to launch a Look up form, and return the value from a combo box

Hopefully I can explain what I want to do well enough...here it goes...
I have a data entry form...the user will be entering employeeIDs. Once in normal operation, most people will be entering only their own EmpID, and they should know it, so this won't be a big problem 99% of the time once this DB goes live.
However, I need some temps to enter historical data from paper sheets into the DB. These people will not know anyone else's EmpID. I'd like to set the Student field's OnDblClick event in the subform's datasheet to open a small form with a combo box. The combo box has a list of all Employee Names, and is bound to the EmpID. Once this user enters the name, and selects the person, I have a button they can click to return to the datasheet.
I can use a function to launch the form, no problem there. But how do I return the EmpID to the field in the datasheet that was double clicked?
When user double clicks in the Student field...I want the next form to appear, and then once they type in the name and select the correct person...and then click Found Them!...I need that bound value to return.
I'd love to say I have code to share right now...but the only code I have is to launch the look up form. I'm brain farting on how to pull the value back down.
The way to do this to launch your little dialog form as “acDialog”. This will cause the calling code to WAIT.
And then the “magic” part is when they click on “Found Them” you do NOT close the popup form, but simply set the form’s visible = false. This has the effect of the calling code that popped up this form that halted to continue (the form is kicked out of dialog mode when you do this). So now your calling code continues.
So your code will look like this:
Dim strF As String ' name of popup form
strF = "frmPopUp"
' open form, wait for user selection
DoCmd.OpenForm strF, , , , , acDialog
' if for is NOT open, then assume user hit cancel buttion
' (you should likly have a cancel button on the form - that cancel buttion will
' execute a docmd.close
If CurrentProject.AllForms(strF).IsLoaded = True Then
' grab the value of thee combbo box
strComboBoxValue = Forms(strF)!NameOfComboBox
DoCmd.Close acForm, strF
End If
As noted, the code behind the Found Them button DOES NOT do a close form, but sets forms visible = false (me.Visible = false), and this trick allows the calling code to continue at which point you can examine any value on the form. Remember to then close the form after you grab the value.
It looks like your data table is in a subform so there is a little more work but it does not have to be as complex as the above solution if you don't want it to be. #Andre451 was close but you need the extra step of identifying the form and subform. For the purpose of demonstration let's call the form Attendance and subform Entry then I'll call the second form LookUp. So the code for your double click in the subform field will of course look something like this :
Private Sub Student_DblClick(Cancel As Integer)
DoCmd.OpenForm "LookUp"
End Sub
You really don't need anything else fancy there. For the button on "LookUp" you will put this:
Private Sub Command2_Click()
Forms![Attendance]![Entry].Form![Student] = Forms!Lookup!Student
DoCmd.Close acForm, "LookUp"
End Sub
And that should get you what you want without any overhead or having to leave any ghosts open.

Select next record on datasheet subform from separate form?

I have 2 forms. 1 subform.
The main form, MainFormF, has a subform which is hooked up to a query that takes data from a table and outputs it into a datasheet. Lets call this subform MainSubformF.
The 2nd form is loaded from a button on MainFormF. It has 2 buttons, previous and next. How do I attach these buttons to switch the next/previous record HIGHLIGHTED in the datasheet subform?
As you can see, that is what it looks like highlighted. It turns blue, if you didn't know.
The code I currently use but doesn't switch the selected records at all is this:
Private Sub Command65_Click()
On Error GoTo new_Err
Forms!MainformF!MainSubformF.SetFocus 'sets the focus to MainSubformF
DoCmd.RunCommand acCmdRecordsGoToNew
new_Err:
End Sub
For the button to open up the More Info form, it takes information from a text box (lets name it InfoTxt) with this as it's control source:
=[MainSubformF].[Form]![ProjectID]
I am thinking I can do something with that variable, like add +1 to it so when the button is clicked it adds +1 to the ProjectID? I don't think that will work now that I am typing this out, but I'll keep this here in case I am right... though I am thinking further into it and ProjectID's aren't always +1, as in case a record was deleted it may go 1,2,3,5,6 and if you get to 3 then click next it'll do nothing as it'll go to 4 not 5.
I simply don't have time to write out a complete answer, but Dev Ashish is a well-respected developer in the Access community and he devised a way to determine which records have been selected. My guess is you'll need to bookmark them somehow. Start with this Sub that Dev wrote:
Determine selected records in datasheet view

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.