How to cancel navigation away from subform - vba

How do I prevent navigating away from a particular subform when a user clicks on a different navigation tab? One of the subforms is pretty complicated, and I want to allow the user a chance to stop the navigation to be able to save all their hard work before they leave the subform.
I have an Access database with a 2-level navigation form. Basically, it looks like this:
Assuming the user is currently viewing the "Important stuff" form in the Navigation form's subform (as is pictured above), and that they still have an unsaved record or anything that would warrant them not losing, I'd like to warn/prompt them with a message box and allow them to cancel the navigation.
I've already tried using the Unload event of the ImportantStuff form, e.g.
Private Sub Form_Unload(Cancel As Integer)
Dim closeConfirmation As Integer
closeConfirmation = MsgBox("There is unsaved data. Are you sure you want to leave?", vbExclamation + vbYesNo)
If closeConfirmation = vbNo Then
Cancel = True
End If
End Sub
But, although I'm prompted as I'd expect, cancelling (via clicking "No") doesn't stop the navigation, and the Unimportant stuff gets shown to me. If I open the ImportantStuff form directly, i.e. outside of the Navigation form, clicking "No" on the prompt does prevent the ImportantStuff form from closing.
I also tried using the NavigationButton's Exit event, but it correlates with the user's focus exiting the button, like when they interact with the ImportantStuff form, and not when they navigate away from that button.
How can I prevent navigating away from a particular subform?

Related

Endless form not showing after filter applied previously

I am using unbound endless forms to display data from my database.
The data source is set to queries which provide data to show on the form.
All tinkering with the data itself on the form is blocked (entry, adding, deleting, etc.).
The data on the form can, however, be filtered through Access' standard ways (right clicking on the data and selecting the options or through the navigation buttons down the bottom of the form).
I am using another unbound form as a menu. Buttons on the form let the user open the data display forms. The buttons are connected to the forms through an on- click event that triggers a DoCmd.OpenForm ("frmOutput") line of code to display the form.
Recently I've had users report, that opening the endless data display forms from the menu, filtering data on the form and then closing the form without taking the filter out has resulted in the form not being able to be opened again from the menu (clicking the respective button results in no action whatsoever). The bug seems to even save to the application somehow and moving the (frontend) file to another machine still shows the same error of not showing the form.
It seems that the bug appears more often when people use multiple screens, and use the application on their second screen (as per their Windows settings).
Does anybody know what causes the bug or how it can be prevented?
Any pointer in the right direction is much appreciated since I am at a loss where to even start looking for the culprit!
Hard to tell but it sounds like their filter is being saved when form is closed
If you already have an event that opens the form, try to just clear the filter property after it opens. You can do this from all your command buttons by just changing the form name that gets passed to it
Private Sub OpenUnfilteredForm(strFormName as String)
Dim frm As Form
DoCmd.OpenForm (strFormName)
DoEvents
If CurrentProject.AllForms(strFormName).IsLoaded Then
Set frm = Forms(strFormName)
With frm
.Filter = ""
.FilterOn = False
End With
End If
Set frm = Nothing
End Sub

How can I refresh the data on my access Front End?

I built an access Form frontend with a sharepoint list called "teammates" as the back end.
The form is simple, consists of two listboxes that lists all teammates, one box is for absent teammates, the other is for present teammates. I have some buttons and methods that allow to update a teammates status, thus moving them into either the "absent" list box or the "present" box.
I also have a "Refresh" button on the page.
Private Sub btnRefreshForm_Click()
DoCmd.RunCommand acCmdRefreshSharePointList
CurrentDb.TableDefs("teammates").RefreshLink
Me.lsbAbsentTeammates.Requery
Me.lsbPresentTeammates.Requery
Me.Requery
Me.Refresh
End Sub
My issue is this, when I share the FrontEnd with someone else, that person will send some teammates to the absent box, but I cannot see those changes, the Refresh button does not requery the data.
The only way I can see the updated data is if I close the front end and reopen it.
How can I see the updated data without having to close and reopen the application ?

Microsoft Access can't open a form from inside another form with doCmd.OpenForm

I'm completely new to MS Access but not to databases. I have a form that is meant to open another form through a button and users are to add records to a target table through said form. The main menu fails to open my secondary form saying "recordset is not updatable". The table that is to receive the records is editable and I can go into it and manually add records so this doesn't seem to be the problem. If I click out of the error through the error handler menu I'm taken to the form that I expected to open, but it is read only-- I can't see it's properties sheet, design view, or even change the view at all. I looked at the VBA code on the main menu and it does use doCmd.OpenForm "myForm", , , , , ,"New"
Any pointers would be really appreciated.
Right click your form and click design view. Add a button, click Cancel and name the button appropriately. Than, right-click the button and click Build Event > Code Builder > OK. Copy/paste the code below into the button click event.
Private Sub Command0_Click()
DoCmd.OpenForm "name_of_your_form"
End Sub
That should be all you need to do. Sometimes I have seen Access do some really weird stuff. If the steps I outlined here don't work, try doing a Compact and Repair to reset everything in your DB, and then add the button.

How to prevent button clicks in a MS Access Form_A when Form_B is correctly displayed modal over Form_A

I realized while I was typing up this question what the problem might be and was then able to solve it. So, I have posted the question and then the answer in case it helps someone else.
I am using MS Access 2016. I have a Form_A that displays a menu of buttons--each button takes the user to a distinct form to perform whatever functions the user needs to perform. For example, one Form_A menu button could be [Add Clients] while another button could be [Add Staff], etc.
When the user first logs into the system, I use VBA code to do a number of "housecleaning" functions. Form_A and the buttons are visible, but I have made a Form_B that is a small dialog that shows the word "Working" with animated "..." while the VBA in Form_A does the housecleaning.
The problem that I cannot solve is that even though I have set Form_B's "Pop Up" property to "Yes" and its "Modal" property to "Yes", the user can still click buttons on the Form_A menu which then execute while Form_B is still doing its housecleaning.
I thought setting Form_B to modal should prevent button clicks on Form_A from getting registered.
More details:
In the Form_Load event, Form_A calls "housekeeping" code that resides in a Module. That module has a Public Sub called "RemakeTables." The RemakeTables code uses DoCmd.OpenForm "Form_B" to display the "Working" dialog.
The RemakeTables code calls several other Public subs. Between each call to the other Public subs, a DoEvents is called which allows for the "Working" dialog to animate the "..." (i.e., cycle between "Working", "Working.", "Working..", and "Working...").
My hunch is that the DoEvents is what is allowing clicks to get registered in Form_A.
How should I be doing this so that clicks cannot be registered while the Form_B "Working" dialog is showing but can still be animated?
As I was typing up the question, it occurred to me that the main problem was that the subs and functions I was calling during "housekeeping" used the DoEvents action to allow the Form_B "Working" dialog to update/animate. However, DoEvents also allows mouse clicks to register.
So, how to prevent the problem?
Include the "housekeeping" calls in the Form_Open event rather than the Form_Load event because the Form_Open event occurs first, before the Form_Load and before the form is displayed, so, there will not be any buttons visible to click if the "housekeeping" code is called in Form_Open.
Hope this helps someone else who might have had a similar problem.

Is There a Way To Simulate the Form Activate from Modal/Pop Up Form

I have a form that opens a modal pop up helper form to collect some data. When this modal pop up form closes, focus returns to the main form. I would like to trigger some activity when focus comes back to my main form.
The event model for the form does not trigger the Form_Activate or Form_GotFocus events when returning from a model popup as per Microsoft documentation.
These forms and all controls are completely unbound.
Is there a trick to knowing in code when focus returns to my form?
If both forms are placed in normal mode, Form_Activate does fire in the primary form when the helper form closes, but this does not meet my needs. I have not been able to find a similar event to trap this. I'm hoping someone has a workaround.
For clarity, the issue I ran into was I had the design time properties in the helper form set to act as a dialog - (pop up and modal as true). When I opened the form responding to the button click event on the main form, I did NOT include the acDialog option.
If you omit the WindowMode=acDialog setting the code operates asynchronously completing the code in the click event handler in full, NOT halting and waiting.
The acDialog option apparently forces the DoCmd.OpenForm command to run synchronously, halting code execution, then returning once the modal form has been closed.
Private Sub btnHelper_Click()
DoCmd.OpenForm "frmHelper", WindowMode:=acDialog
'Do stuff after frmHelper closes
End Sub