How to reference a sub-subform in a navigation form from outside form

daryll

Registered User.
Local time
Today, 05:46
Joined
Jan 2, 2018
Messages
49
What is the appropriate path to reference a sub-subform in a navigation form from outside form. This path work if you are in the navigation form, but not on outside form.

Code:
Forms![Nav Form Attachment]![NavigationSubform].Form.[Pool eFile Attachment].visible=True
 
the BUILDER will provide you with the correct path.
(use a query to paste the path in)

yours looks correct.
 
I'm not familiar regarding "the BUILDER or use a query to paste the path". Kindly explain further.
 
@Pat Hartman
Code:
Forms!yournavformname!thesubformcontrolname.Form!y
This example you've given me would not work. As i've tried interchanging "! and ." prior posting here. I was googling with regards to this but all examples are referred inside the navigation form like my code posted above.
 
What is the appropriate path to reference a sub-subform in a navigation form from outside form. This path work if you are in the navigation form, but not on outside form.

Code:
Forms![Nav Form Attachment]![NavigationSubform].Form.[Pool eFile Attachment].visible=True

That reference is in the context of the Application and refers via the Forms Collection. If it works inside the form it should work outside the form.

If a multilevel reference throws an error I usually beak it down and try it piece by piece from the Immediate Window using the Name property which all these objects have.

Code:
? Forms![Nav Form Attachment].Name
 
? Forms![Nav Form Attachment]![NavigationSubform].Name
 
? Forms![Nav Form Attachment]![NavigationSubform].Form.[Pool eFile Attachment].Name

First one that breaks is where to start looking for the problem.

BTW I strongly recommend you discontinue using spaces in object names.
 
@Galaxiom
That would be a great hint. I'll try your suggestion
 
Now I spotted the problem. Just to share my experience, which is i know some people may find it obtuse. Anyway.

My navigation form has a two tabs and this form is designed to pop-up once the user click on a control (i.e. textbox) which I set the on click event on it. I noticed that when you refer a subform which belongs to the first tab it doesn't throw any error. Which means that the path I posted above is valid. For the sake of clarity this is the path of the subform.
Code:
Forms![Nav Form Attachment]![NavigationSubform].Form.[Pool eFile Detail].visible=True
However, when you refer a subform that belong to the second tab using the same pattern i.e
Code:
Forms![Nav Form Attachment]![NavigationSubform].Form.[Pool eFile Attachment].visible=True
it throws an error "can't find field |1 referred to your expression" but if you navigate to the second tab without closing the Navigation Form and again clicking on the control (i.e textbox) which is on the main form then that path is valid.

So my question now, how can I make the path on which the form will not throw any error?
 
Last edited:
I gave you the answer:
That means that you CANNOT reference a form that is not loaded. Period!!! If tab1 is active, NOTHING on any other tab can be referenced.

I didn't get your point clearly nor paying attention to it. May be I was too carried to receive an answer seeing a code directly. And beside, this is my first project with MS Access.

Your warning was right I really didn't expect it behaved that way. Anyhow, now you've explained it directly it really gave me a clear insight. Thanks @Pat Hartman

One more thing, by using docmd.browseto prior to initiating the subform path will it solve the issue?
 
Last edited:
You might be able to solve the problem by making your form a tabbed form. That way, both forms will be loaded into the nav subform control and therefore both can be referenced..

Did you mean a subnavigation form of the current nav form? Or may be not.
 
This trick solve the issue.

In order to not let the form throw an error, first execute the docmd.browseto (browse to second tab) prior to
Code:
Forms![Nav Form Attachment]![NavigationSubform].Form.[Pool eFile Attachment].visible=True
.
 
The Navigation form is a special purpose form and it works differently than you might expect. The nav form uses a SINGLE subform control. As you click navigation buttons, a different form gets loaded into the control. That means that ONLY the currently active subform is ever available. But, you would address it as you would address ANY subform.

Forms!yournavformname!thesubformcontrolname.Form!yoursubofrmfieldname

"thesubformcontrolname" is static. It is ALWAYS the Name property of the subform control REGARDLESS of what form got loaded into the subform.
Hi Pat - im very sorry to reply to an old thread but I am super stuck - actually just signed up to as you a question on this.

Basically I have a Main Navigation form (Top Bar) =. frmNavigation
Then under each man control I have a another Nav form called for example navIR
Then in that tab I have say 5/6 navigation tabs and these refer to direct forms I have build and some have subform and sub form controls in them.

Been really really struggling with completing action and passing details among these.

Here is an example of one I desperately need help on

frmNavigation - frmNavIR - frmSnaphot - (subform here)

When I try to update fields on frmSnapshot after I click on a record on the subform it doesn't recognise that frmSnapshot is open. I have tried doing all levels and single levels. Everything.

Any suggestions?
 
maybe a demo db will demonstrate what you mean.
 
maybe a demo db will demonstrate what you mean.
Unfortunately I cannot upload the tool - my work environment is extremely strict so im on the forum on my personal PC

I actually found that what Pat suggested works but not with 2 layers of navigation forms. So I have made the painful decision to rebuild my navigation to use 1 level but both Left vertical and top horizontal. Then it seems to work.

Too many layers/subforms I think - lost sooo many hours ... thanks anyway.

One positive is I finally signed up. Hopefully I can help others
 
@Pat Hartman - thanks for your comments. Yeah 2 layers of Navigation forms seems to just be a bad idea.

For me I rate UI more then most access users, in fact in my case management have refused to allow us use access for new tools, however when I show them my UI they didn't even realise it was access so gave the go ahead when the can see that it doesn't have to be an ugly blocky UI.... of course this take considerable time and effort and I wish access had better tools for managing forms but you got to work with what you got.

Thanks
 
@RobDuggan
You can make references to any open form, regardless of its embedded depth inside a form or subform without any guesswork by using the locals window. If you want to find out how to use that method, let me know.

For now here's a test you can perform right now:
1. Open the form you want to reference in design mode
2. Go to properties pane
3. Other tab
4. Make sure Has Module is Yes
5. Go to the VBA window and see what name it has in the explorer, for example, if you had named this form "frmMyName", it will appear as "Form_frmMyName" there.
6. Now just go to the code where you want to reference this form and directly use "Form_frmMyName". For example, if you wanted the value of a textbox named "txtMyTextbox" inside "frmMyName", then do this: MsgBox Form_frmMyName.txtMyTextbox
7. Done.

Now, of course, an experienced developer can skip steps 1 to 5 and simply add "Form_" as a prefix to their references, as they will know whether their form includes a module.
 
what if Form_FormName is open both as subform and single form?
or Form_FormName is a multiple subform as in the case of "Calendar Appointment/Schedule")?
 
In those cases, Form_FormName would be one of the instances. If you have that kind of instancing, then use other methods to have the applicable level of control. For your examples:

Case 1a: you use a variation of Forms("ParentForm").Form.Controls("SubformControlName").Form for a simple Form/Subform
Case 1b: you use Forms("FormName").
Case 2: you use a variation of Forms("ParentForm").Form.Controls("SubformControlName").Form.

However, let's say you had nested forms like main > sf1 > sf2 > sf3 > sf4 > sf5 or similar, and in sf5 you had your case 2, well, use the code name of the form that sf5 is holding, if it's called "Form5", then you can use things like
Form_Form5("SubformControlName").Form
or
Form_Form5.Controls("SubformControlName").Form
or
Form_Form5.Form.Controls("SubformControlName").Form
or
Form_Form5.Form.Controls.Item("SubformControlName").Form
or
Form_Form5!SubformControlName.Form
or other variations

Instead of
Forms("ParentForm").Form.Controls("sf1").Form.Controls("sf2").Form.Controls("sf3").Form.Controls("sf4").Form.Controls("sf5").Form.Controls("SubformControlName").Form
Which needs some line breaks to be readable, or even this, which is also hard to read.
Forms!ParentForm.Form!sf1.Form!sf2.Form!sf3.Form!sf4.Form!sf5.Form!SubformControlName.Form


For single instance, which is the most common scenario ever, this method is fine. I invite anyone to test it and stop suffering with this.
 
Last edited:
I would be interested in that, please.
Sure, my method basically requires the locals window open, the immediate window open, a procedure to test and the Stop command. If you need to reference a form from a module, for example, then make a procedure, declare a form variable, set it to the form you want and add the Stop command at the end.

Code:
Sub test()
    Dim f As Form
    Set f = Forms("TestForm")
    Stop
End Sub

Open the form, run the Sub and you should see the variable you declared in the Locals window with a plus sign to the left.

1706214755306.png


Now click the plus sign to the left and you'll see the form's properties and the objects embedded within it. The Locals window is handy enough to tell you the name of the member, its value and its type. How do you test these? I recommend the immediate window. Do this, for example: ?f.Width

1706213876540.png


If you use the question mark notation, you'll get the value of the member as presented in the Locals window. You will notice that some values appear between angle brackets, if you attempt to access those members, you'll get the error between said angle brackets. I hope that you can anticipate why this tool is such a time saver.

I recommend that you familiarize yourself with the fact that the form variable has an embedded reference to its controls, both at the bottom of the tree and within the Controls member. Another thing, since we declared the f variable as form, we will not have intellisense for its members, if we want intellisense for that, declare the f variable as its code name, like Form_FormName.

Now, referencing other forms should not be difficult with this preamble. Let's say we want to reference a control inside a subform from a module using the test() routine from above.

Open the form and run the routine from the module.
Expand the Controls member, write the following in the immediate window: ?f.Controls (do not Enter yet)
Now look at the contents of that member.

1706213966441.png


You'll see item1, item2, ... etc. Not very helpful. Now look at the Type column, you'll see a Subform type there, that's your item. Expand that and check its Name property. Now that you have the name of that control, you can now add it to the question mark notation from before, because now we have the control name we're looking for in order to use the Controls member: ?f.Controls.Item("SubformControlName") or ?f.Controls("SubformControlName") (do not enter yet)

Now that you have a reference, you can verify it by seeing if a property like .Name returns something. In fact, keep looking inside the Subform control members, the locals window has a lot of things you can use to verify your reference, I like .SourceObject, because it returns the name of the form that the subform control is holding, so I do this ?f.Controls("SubformControlName").SourceObject (Enter now). What did it return? If you keep looking around the Locals window in its Type column, you will notice the .Form property is of type Form_FormName. Expand that, repeat the same, expand controls and find the control type you want, check its name, write it down, verify. ?f.Controls("SubformControlName").Form.Controls("SomeTextbox").

If I didn't lose you, this is meant to make you look at ALL your options at once, the Locals window has the answers you're looking for, just inspect it and see the wealth of undocumented data it presents you under the hood. To summarize:
1. Expand form variable .Form
2. Expand Controls member .Form.Controls("______")
3. Locate the control using the Type column
4. Get its name and set it .Form.Controls("ControlName")
5. Verify with the immediate window .Form.Controls("ControlName").Name or .Form.Controls("ControlName").SourceObject
6. Repeat if you have a nested subform

If you want to do the inspection from a form, then use some event, like Load. The rest is the same. Always keep the Locals window open, there is a lot of stuff to still talk about it, like the other members of the form object. This does not apply only to forms, but to any other object.
 

Users who are viewing this thread

Back
Top Bottom