AllControlsLoaded event? (1 Viewer)

davidcie

New member
Local time
Today, 16:51
Joined
Dec 30, 2018
Messages
12
I have a bit of a convoluted design which I will try to explain as best as I can so bear with me.

There is a full-screen form whose source is set to "Orders" (let's call it frmOrders). On it there's a few controls with order details and (1) a small continuous subform that displays a (filterable) list of all orders (frmList), and (2) a second subform that displays products that were part of this order (frmProducts).

We "solved" navigation using the following code:

Code:
' Code for frmList
Private Sub Form_Current()
    If UtilUi.ParentIsLoaded(Me) Then
        Call Me.Parent.ShowOrder(Me!OrderId)
    End If
End Sub

' Code for frmOrders
Public Sub ShowOrder(intOrderId As Integer)
    DoCmd.SearchForRecord acDataForm, Me.Name, , "[OrderId] = " & intOrderId
    Call subProducts.Form.ShowProductsFor(intOrderId)
End Sub

Private Sub Form_Load()
    Call ShowOrder(subList.Form.SelectedOrder)
End Sub

' Code for frmProducts
Public Sub ShowProductsFor(intOrderId As Integer)
    ' Do some magic stuff here
End Sub

' Code in UtilUi
Public Function ParentIsLoaded(frm As Form) As Boolean
    Dim obj As Object, rtn As Boolean
    rtn = False
    On Error Resume Next
    Set obj = frm.Parent
    If Err.Number = 0 Then
        rtn = True
    End If
    Set obj = Nothing
    On Error GoTo 0
    ParentIsLoaded = rtn
End Function

Trouble is that it seems the order in which controls are loaded/initialized/constructed is not guaranteed. E.g. frmList's OnCurrent event would fire before its hosting parent form was loaded and calling Me.Parent.ShowOrder would fail with an error - hence we added a utility function to check if parent is loaded and query frmList for currently selected record in frmOrders's OnLoad event.

Then it worked for a while... until Access decided to load the frmList subform before loading the frmProducts subform seemingly for no reason at all. Now it's the subProducts.Form.ShowProductsFor call that is failing. We can bypass this by doing checks similar to ParentIsLoaded and then sprinkling some magic calls querying for currently selected order in frmProducts's OnLoad but... this seems a little backwards and doesn't feel sustainable in the long run.

(As a side note, we do realise we could link up Orders and Products using master/child fields but we need to do some ADO processing upon selection and from our testing the master/child linkage comes with the significant caveat of not having any event fire for child whenever its recordset is forced to change by master - thus preventing our ADO processing from knowing when to run.)

After this lengthy introduction: do you know of any event, any mechanism that we could employ to simply withold any processing until all subforms and controls are loaded, and then do what we have to do when they are? Are there any rules that govern subform/control initialization that we could reference to know in what order they would be loaded (= ready to interact with)? We have not been able to find anything useful in MS documentation. Have also had a look at these forums, but came back empty handed. How do you handle such intertwined "on-open" subform communication?

Wil be most grateful for any pointers or thoughts you might have that relate to this, one would think relatively common, use case.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 07:51
Joined
Oct 29, 2018
Messages
21,478
Hi. You probably have seen this already but just in case not, here it is. Hope it helps...
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 10:51
Joined
May 21, 2018
Messages
8,542
The most important as that link pointed out is that forms load from the inside out. Subforms first then main. So you should be doing your calls from the main.
Working with subforms
When you open a form that contains a subform, the subform and its records are loaded before the main form. Thus, the events for the subform and its controls (such as Open, Current, Enter, and GotFocus) occur before the events for the form. However, the Activate event does not occur for subforms. Therefore, opening a main form triggers an Activate event only for the main form.

Similarly, when you close a form that contains a subform, the subform and its records are unloaded after the form. The Deactivate event does not occur for subforms. Therefore, closing a main form triggers a Deactivate event only for the main form. The events for the controls, form, and subform occur in the following order:

Events for the subform's controls (such as Exit and LostFocus)

Events for the form's controls (including the subform control)

Events for the form (such as Deactivate and Close)

Events for the subform

Note: Because the events for a subform occur after the main form is closed, certain events, such as canceling the closing of the main form from an event in the subform, will not occur. You may need to move these types of validation tests to an event on the main form.

I would attack this one of two ways
1) I think the cleanest would be to trap all my subform events in the main form. Set a reference to the subforms using With Events. If necessary you may need to add some custom events in the subs. If it is that complicated you could consider making a class module and trap all events there as well.

2) You could load the main form with out any source objects in your containers. Then load the containers in order.
 

davidcie

New member
Local time
Today, 16:51
Joined
Dec 30, 2018
Messages
12
@theDBguy I have indeed, the trouble with the document is does not go into great detail on more complex arrangements.

@MajP thank you for your useful thoughts. In particular I like the idea of loading subforms in a manual, controlled manner once the main form is up and running by setting source objects. "With Events" also sounds cool but from a technical, "neat-solution!" point of view :)
 

Users who are viewing this thread

Top Bottom