Understanding form event progression (2 Viewers)

riktek

Member
Local time
Today, 12:56
Joined
Dec 15, 2023
Messages
34
This question is either dumb with an obvious answer, or arcane and deeply into the weeds, I'm not certain which, about event progression among forms, subforms, and controls. Of course, I already have made extensive reference to the Access object model and the MS article Order of Events for Databasee Objects but they and my Google-fu have yet to reveal any understanding.

I'm working on optimizing form load times and am parsing event progression for forms and subforms to find ways to defer or avoid execution. I'm encountering undocumented behavior that I expect has a reasonable, if unintuitive, explanation and thought I'd seek clarification here.

The first question, or observation, is that the event progression when opening a form is documented as being:

Open > Load > Activate > Current

but in fact is:

Open > Load > Activate > Current > Deactivate > Activate > Current

Specifically, I'm wondering why Activate and Current reiterate, which may be partly about what triggers the Deactivate event, because nothing documents, describes, or explains this behavior. Obviously, I'd like to avoid re-executing calls from those two event procedures. I can engineer a kluge but does a means exist to interrupt the event progression to avoid reiterating these events?

The second question concerns events of combo boxes on subforms. The specific configuration has the SubForm controls on TabControl pages configured for lazy loading, i.e., SourceObject, LinkMasterFields, and LinkChildFields are conditionally assigned (or cleared) depending on whether the tab page is current / active / visible. I understand that setting any of these three properties causes SubForm.Form to reload. I also observe the same reiteration of Activate and Current.

What's different from the top form / main form case and what I don't understand, is that on each instance of SubForm.Form.Current, the combo box (but not text box) Enter and GotFocus events also are triggered. I'm keenly interested in interrupting this seemingly inexplicable event progression, too, to avoid triggering each of these events altogether. Again, I can engineer a kluge but am wondering why these control events are triggered in the first place because nothing documents, describes, or explains this behavior, and how to avoid that.

Many thanks for any insights.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 14:56
Joined
Feb 28, 2001
Messages
27,332
Where there is a bound sub-form, the "Deactivate>Activate" sequence signifies that between the two events on the main form, some sequence of events occur in the sub-form when there is a parent/child linkage such that the sub-form also has to become current while it synchronizes with that parent/child linkage. During that time, focus is in the child form because that is where the work is being done. Remember that a "parent" form and a "child" form are BOTH just ordinary forms that have to go through whatever events are appropriate for their states. The only difference between a parent form and a child form is that a child form is loaded into a sub-form control on a parent form, but a parent form is loaded directly to a child process and window belonging to your session's parent process. But that child form exists in the FORMS collection, not the SUB-FORMS collection.

When you have a combo box that has a query underneath it (but not when it has a fixed-text list driving it), that query has to be evaluated and for that, the combo needs to momentarily have focus, which is apparently your Enter event that you saw. There probably would be an Exit event, too.

As to your comment to wish to skip execution of events... you can't and probably shouldn't try. MSACCESS.EXE is the MAIN program for which the event routines are subs. Access itself triggers the events in the order that it deems appropriate. It is not Open Source, so we cannot see what it is doing, but we pretty much know that Access linearly follows a sequence of actions that include declaration of events. When Access triggers an event, it is USUALLY because it thinks it needs to OR is not certain that it DOESN'T need to.

For what it is worth, EVERY EVENT in the list of event entry points on a form will execute at its appropriate time even if YOU didn't program something as a custom routine for that event. For instance, the "Load" event WILL load and place the controls on a form whether or not you have a form_Load event. The "Current" event WILL .MoveTo the appropriate bound record and then will distribute data to the appropriate controls via the control sources on the form whether or not you declared a form_Current event. The only difference is that before Access finishes any given event action, it checks for whether it needs to call your event code entry point. That's all the choice you have. Supply or don't supply an event entry point.
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 15:56
Joined
Feb 19, 2002
Messages
43,513
I don't see the same event sequence that you are reporting. In this picture, the form "Event Samples" is showing the events of the form "State" .as they run. The list is sorted descending so the first event to run is #1 and it is on the bottom. In the Form Name column, the pink background highlights the subform events so you can see that the subform is loaded first.
1702683915755.png


As you can see by the second picture, all the form level events have logging code which would add a row to the log table if they executed. Putting the form into design view caused 5 more events to run #10-#14 where you see that the main form gets unloaded and deactivated before the subform is unloaded. Plus, the deactivate event doesn't run for the subform because the subform didn't have the focus.
1702684231252.png


Here is the database along with a couple of videos to explain some of what is going on.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 15:56
Joined
May 21, 2018
Messages
8,609
I'm keenly interested in interrupting this seemingly inexplicable event progression, too, to avoid triggering each of these events altogether.
Very curious how you think you would do that. Have you spoke to Microsoft to see if they will provide you the source code for Access? Or do you have another idea?
 

riktek

Member
Local time
Today, 12:56
Joined
Dec 15, 2023
Messages
34
Where there is a bound sub-form, the "Deactivate>Activate" sequence signifies that between the two events on the main form, some sequence of events occur in the sub-form when there is a parent/child linkage such that the sub-form also has to become current while it synchronizes with that parent/child linkage.
Thanks for the input. More findings, as follows:

The first question actually concerns a bound form with no subform, bound or otherwise. That is, why on a simple form with only combo box and text box controls, do Activate and Current reiterate, seemingly contrary to all documentation?

Otherwise and as stated in the OP, I understand that a form on a subform control has to load, and when it does, but those are beside the point, which is to wonder (a) why Deactivate is firing in the opening sequence because nothing obvious is claiming focus; and (b) why the second Activate triggers because nothing obvious is being done to claim focus from whichever phantom object caused Deactivate to fire in the first place.

I've since learned that the form event reiteration is a consequence of binding the form to the form property of a form wrapper class. The class instance seems to be the phantom recipient of focus, which is what triggers Deactivate.

When you have a combo box that has a query underneath it (but not when it has a fixed-text list driving it), that query has to be evaluated and for that, the combo needs to momentarily have focus, which is apparently your Enter event that you saw. There probably would be an Exit event, too.
Actually, I've since learned that Enter and GotFocus occur only for controls the TabIndex of which is 0. Current is when focus moves to a record, and such controls are the first to receive focus. Q.E.D.

As to your comment to wish to skip execution of events... you can't and probably shouldn't try. MSACCESS.EXE is the MAIN program for which the event routines are subs. Access itself triggers the events in the order that it deems appropriate. It is not Open Source, so we cannot see what it is doing, but we pretty much know that Access linearly follows a sequence of actions that include declaration of events. When Access triggers an event, it is USUALLY because it thinks it needs to OR is not certain that it DOESN'T need to.
As noted, the behavior varies by the form's or control's context, so this isn't apt. The way to avoid triggering the control events is to take the control out of the tab order. The way to avoid form event reiteration is to not bind it to another object. More generally, many events can be canceled.

For what it is worth, EVERY EVENT in the list of event entry points on a form will execute at its appropriate time even if YOU didn't program something as a custom routine for that event. For instance, the "Load" event WILL load and place the controls on a form whether or not you have a form_Load event. The "Current" event WILL .MoveTo the appropriate bound record and then will distribute data to the appropriate controls via the control sources on the form whether or not you declared a form_Current event. The only difference is that before Access finishes any given event action, it checks for whether it needs to call your event code entry point. That's all the choice you have. Supply or don't supply an event entry point.
We all know that event procedures aren't events.

Thanks again.
 

riktek

Member
Local time
Today, 12:56
Joined
Dec 15, 2023
Messages
34
Very curious how you think you would do that. Have you spoke to Microsoft to see if they will provide you the source code for Access? Or do you have another idea?
Simply by avoiding the things that trigger the events, of course.
 

riktek

Member
Local time
Today, 12:56
Joined
Dec 15, 2023
Messages
34
Thanks to all.

I'd respond in detail but the interface rejects my attempt to post my findings on the grounds of being spam-like, whatever that means.

Briefly, I discovered the causes of the event progression and the means of interrupting it in both cases. I'll revert if permitted.
 

Gasman

Enthusiastic Amateur
Local time
Today, 20:56
Joined
Sep 21, 2011
Messages
14,472
Thanks to all.

I'd respond in detail but the interface rejects my attempt to post my findings on the grounds of being spam-like, whatever that means.

Briefly, I discovered the causes of the event progression and the means of interrupting it in both cases. I'll revert if permitted.
You have to have a certain number of posts before you can post links. This is to hinder spammers.
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 15:56
Joined
Feb 19, 2002
Messages
43,513
That is, why on a simple form with only combo box and text box controls, do Activate and Current reiterate, seemingly contrary to all documentation?
Your own code is causing the problem. It is triggering the strange order of events.

Events are "hooks" the Microsoft Access developers added to THEIR own proprietary code that actually automates forms. These "hooks" are placed at points where they think the developer may want to insert his own code in an Event procedure. So, for the times when you have code that you want to execute each time the form moves focus to a new record, MS has provided the form's Current event. If you want to validate a form's data before a record gets saved, they gave you the Form's BeforeUpdate event. If you want to control who can update a form, you can spend a lot of time locking down controls OR you can trap an attempt to update by putting code in the on Dirty event. Check the users credentials and if he is not authorized to update/add you can undo his typing and cancel the event which prevents the change from being saved. Use the Before Delete Confirm to stop deletes. Every "hook" is intentional and meant to be used for specific reasons. You seem to be attempting to interfere with MS's proprietary code by wrapping a form - which is itself a class - into a class of your own making because you think you can change the way a form works by doing this but you don't get to add new types of events because you can't change the MS code.

Maybe, it is time to understand how Access works before you set out to bend it to your will. Access is a RAD (Rapid Application Development) tool. It is designed to do a lot of the background processing so you don't have to write the code to do it yourself. Bound forms are the crown jewel of Access. If you are not using bound forms the way MS intended them to be used, you are missing the whole point of Access and will always be unhappy with it.

Again, I can engineer a kluge but am wondering why these control events are triggered in the first place because nothing documents, describes, or explains this behavior, and how to avoid that.
You already engineered the kluge. You wrapped a form in a class so you could change how it operated.
 

riktek

Member
Local time
Today, 12:56
Joined
Dec 15, 2023
Messages
34
You have to have a certain number of posts before you can post links. This is to hinder spammers.
Thanks. I wasn't posting links, actually. I think the problem was excessive quoted text from the posting I was replying to.
 

riktek

Member
Local time
Today, 12:56
Joined
Dec 15, 2023
Messages
34
Your own code is causing the problem. It is triggering the strange order of events.
Thanks. I know.
Events are "hooks" the Microsoft Access developers added to THEIR own proprietary code that actually automates forms.
Thanks. I know what an event is.
Maybe, it is time to understand how Access works
Thanks, I understand how Access works.
Access is a RAD (Rapid Application Development) tool.
Thanks. I know.
You already engineered the kluge. You wrapped a form in a class so you could change how it operated.
Correct. That's why we write code.
 

riktek

Member
Local time
Today, 12:56
Joined
Dec 15, 2023
Messages
34
Thanks to all for the input.

I've since learned that the form event reiteration is a consequence of binding the form to the form property of an instance of a form wrapper class. That would seem to move focus to the class instance sufficiently to trigger the Deactivate event. So, the means to interrupt the event progression is simply to not bind the form to another object. Q.E.D. This behavior is curious because it is not described in the Form.Deactivate Event documentation but it is illuminating of how the underlying Access code evaluates focus, which is to say it has no relationship with the GUI..

I also have learned that the progression to control events occurs only for controls the TabIndex of which is 0. Form.Current occurs when focus moves to a record and such controls are the first to receive focus. So, the means to interrupt the event progression for a particular control is simply to change its position in the tab order. Q.E.D.
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 15:56
Joined
Feb 19, 2002
Messages
43,513
This behavior is curious because it is not described in the Form.Deactivate Event documentation
That's because they don't want us to know. There is very little regarding how Access works internally that is available to us. They tell us how to use events because that is the only part of the application where we can insert code to modify default behavior.
 

Users who are viewing this thread

Top Bottom