How to reference a control on Tab Control from the Main Form (1 Viewer)

ThomasDirkse

New member
Local time
Today, 04:10
Joined
Apr 6, 2023
Messages
11
I have the following Test Form:

1681102458489.png


How do I reference the Text Box control Text1 on Page2 of Tab Control TabCtl1 on Form2? I don't know if I am making it more difficult than it is but I tried in many different ways but have been unsuccessful so far. It seems to be quite the 'path' to travel: Form2 > TabCtl1 > Page2 > Text1.

Is there anyone who can help me with this?

Many thanks, Thomas.
 

Attachments

  • 1681101811811.png
    1681101811811.png
    4.7 KB · Views: 52

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 18:10
Joined
May 7, 2009
Messages
19,247
if there is not subform on each tab, you can "directly" refer to it:

Me!Text1

or

[Forms]![yourFormName]!Text1
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 05:10
Joined
Feb 28, 2001
Messages
27,194
Things in the main working area of a tab control are still considered part of the main form. As arnelgp says, use Me.xxxx because the tab control's name is NOT a part of the path. BUT if you have a sub-form, then it is Me.sub-form-control-name.Form.control-name-on-the-subform - again omitting the tab control name from the naming path.

For visibility issues, the tab controls make a difference. For naming issues, it is like they don't even exist.
 

ThomasDirkse

New member
Local time
Today, 04:10
Joined
Apr 6, 2023
Messages
11
Thank you that is really good to know. However, in my case, the Text Box is actually a subform. I thought the subform was interpreted as a control that's why I thought any control would do. The Text Box is in fact a subform. I always like to strip a problem down to its simplest form and remove all the extraneous imformation that usually doesn't affect my question. In this case it, unfortunately, did. I thought if someone can show me the way to a control then I can experiment from that point forward. My apologies about my misleading question.

The actual situation is as follows:

1681142977182.png


The field on subfrmNotesDetails I am trying to read is called NoteText. Would you gents mind having another go at it?

Thanks so much, Thomas.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 06:10
Joined
May 21, 2018
Messages
8,536
In that case you can reference the control as if it was any subform on a form. This is because of how Access treats controls on a tab. They are also added as properties of the mainform.

Code:
me.SubformControlName.Form.ControlName
me.subfrmNotesDetails.Form.NoteText

Do not forget ".Form" which returns the form inside the subform control. Also make sure the sub form control is truly named subFrmNotesDetails. The subform control and the form inside may not have the same name.
 
Last edited:

MajP

You've got your good things, and you've got mine.
Local time
Today, 06:10
Joined
May 21, 2018
Messages
8,536
Now to be more precise, on why you can reference a control on a tab and why it may matter.
You can reference a control on a tab directly, because Access makes it a property of both the tab and also the form. So this is an additive feature.
Things in the main working area of a tab control are still considered part of the main form.

The above statement is not completely correct and it can make a difference. More precisely
Things in the main working area of a tab control are ADDITIONALLY considered part of the main form.
A tab control has a Pages Collection. Each page has a Controls collection. So you can follow the natural hierarchy to reference a control on a page on a tab
Me.tabOne.pages("Page1Name").controls("textboxName")

However, Access did us a favor and doubled it up to make it easier to reference. Pages on tab controls and controls on pages are in addition added to the forms control collection and added as properties of the form. This doubling up seems strange but provides a shorter path to reference the controls. You now can go direct instead of through the pages and control collections.
Me.Page1Name
Me.TextBoxName

So where does this make a difference? The parent of a control on a Page is the Page. The parent of the Page is the tab control. The parent of the tab control on a form is the form.
So although it seems as if the control on a tab is a child of the main form, the parent of the control is not the form. For a control on a tab you have to go back through it heirarchy to reference the form.
dim ParentFrm as form
set ParentFrm = txtBoxOne.Parent.Parent.Parent
 
Last edited:

ThomasDirkse

New member
Local time
Today, 04:10
Joined
Apr 6, 2023
Messages
11
Now to be more precise, on why you can reference a control on a tab and why it may matter.
You can reference a control on a tab directly, not be cause it is not a property of the tab but because Access has in addition added it as a property of the form. So this is an additive feature.


The above statement is not completely correct and it can make a difference. More precisely

A tab control has a Pages Collection. Each page has a Controls collection. So you can follow the natural hierarchy to reference a control on a page on a tab
Me.tabOne.pages("Page1Name").controls("textboxName")

However, Access did us a favor and doubled it up to make it easier to reference. Pages on tab controls and controls on pages are in addition added to the forms control collection and added as properties of the form. Doing something like this is strange in the VBA object module (I know of no other place where this double tapping is done), but makes it a lot easier to shortcut the naming reference. You now can go direct instead of through the pages and control collections.
Me.Page1Name
Me.TextBoxName

So where does this make a difference? The parent of a control on a Page is the Page. The parent of the Page is the tab control. The parent of the tab control on a form is the form.
So although it seems as if the control on a tab is a child of the main form, the parent of the control is not the form. For a control on a tab you have to go back through it heirarchy to reference the form.
dim ParentFrm as form
set ParentFrm = txtBoxOne.Parent.Parent.Parent
I am SO pleased to know about this. I like working with Tab Controls and this information is gold! So, if I am understanding you correctly, if you're on the main form and want to address the subform (on a Tab Control page) you can do:

me.subfrmNotesDetails.Form.NoteText

But when you need to go 'the other way', i.e. need to reference a control on the main form from the subform you have to take the full hierarchy into account.

If my main form is frmForm2 and it has a control called txtTextBox2, then how do I reference that from the subform subfrmNotesDetails?
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 06:10
Joined
May 21, 2018
Messages
8,536
If from the main you reference a control on a subform on a tab it can be done as if the subform is simply on the form.
Me.subfrmNotesDetails.form.NoteText
However if you called code from the subform to reference a control on the main form
me.Parent.Parent returns Page2
Me.Parent.Parent returns Your Tab Control
Me.Parent.Parent.Parent returns your Form 2

So
Me.Parent.Parent.Parent.SomeControlOnForm2
 

ThomasDirkse

New member
Local time
Today, 04:10
Joined
Apr 6, 2023
Messages
11
If from the main you reference a control on a subform on a tab it can be done as if the subform is simply on the form.
Me.subfrmNotesDetails.form.NoteText
However if you called code from the subform to reference a control on the main form
me.Parent.Parent returns Page2
Me.Parent.Parent returns Your Tab Control
Me.Parent.Parent.Parent returns your Form 2

So
Me.Parent.Parent.Parent.SomeControlOnForm2
I'm going to try that right now.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 06:10
Joined
May 21, 2018
Messages
8,536
I believe this code will return the main form no matter how many subforms and how many tabs the control is nested.
Code:
Public Function GetMainForm(Ctl As Access.Control) As Form
  On Error GoTo errlbl
  Dim CurrentObject As Object
  Set CurrentObject = Ctl
  Do
    Set CurrentObject = CurrentObject.Parent
    If TypeOf CurrentObject Is Form Then
      Set GetMainForm = CurrentObject
    End If
  Loop
  Exit Function
errlbl:
   If Err.Number <> 2452 Then
     MsgBox Err.Number & Err.Description
   End If
  End Function
In other words it keeps calling the parent (form, page, tab) until the object no longer has a parent. That can only be the main form.
 

561414

Active member
Local time
Today, 05:10
Joined
May 28, 2021
Messages
280
Inspecting the Form variable will help you learn how to reference anything from anywhere.
1. You seem to have a parent form with a tab control and a subform control on page 2 of that tab.
2. The requirement is to reference a textbox in the subform from the parent form.

If I add a little Stop in form2's open event like this:

Code:
Private Sub Form_Open(Cancel As Integer)
Stop
End Sub

I see that I get a Me variable in my locals window
1.jpg

If I expand that variable, I can inspect it. The first thing I can see is that I have a node called "Controls". If I expand controls I get this:
2.jpg

Notice how I get 1 tab control item, 2 pages items, 1 subform item as well as other items from the very same Controls node. That's only one example, but if I go to the Form node, and then the Controls node of that, I get the same. If I go to the the Module node and then Parent, then Controls, I get the same. And there are other nodes from where I can get references, there's the Application node, the Parent node, the Properties node, etc. Most notably, at the end of the tree of nodes, I get the contents of these Controls nodes. So I can use any and all of these.

I will open a few nodes and see what references I can come up with:

From Me.Controls:
Me.Controls.Item("TabCtl0").Pages.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value
Me.Controls.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value
Me.Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value

From Me.Form.Controls:
Me.Form.Controls.Item("TabCtl0").Pages.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value
Me.Form.Controls.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value
Me.Form.Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value

From Me.Properties:
Me.Properties.Item("BorderStyle").Parent.Controls.Item("TabCtl0").Pages.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value

From Me:
Me.TabCtl0.Pages.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value

And any time you see .Item("Something") can be replaced with !Something, for example:
Me.Controls.Item("TabCtl0").Pages!page2.Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value

I could go on with other places where the reference can be made, but I hope you get the point. Check the attachment. If I wanted to reference something from outside, like a module, then instead of Me, use Application.Forms("theForm") and inspect it.
 

Attachments

  • Database13.accdb
    368 KB · Views: 75

MajP

You've got your good things, and you've got mine.
Local time
Today, 06:10
Joined
May 21, 2018
Messages
8,536
Although that is good information, remember that the shortcut is there since no one will ever do this
Code:
MsgBox "From tab on me.controls" & vbCrLf & Me.Controls.Item("TabCtl0").Pages.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value
when they can do this
Code:
MsgBox "From tab on me.controls" & vbCrLf & Me.child_form.Form.txtSomeTextbox
 

561414

Active member
Local time
Today, 05:10
Joined
May 28, 2021
Messages
280
Although that is good information, remember that the shortcut is there since no one will ever do this
Nah. Sure-fire all the way, MajP. I use that syntax. It never misses.

Shortcuts are taught wrong. I know it. You know it. Everyone with enough time in this knows it. Shortcuts are the reason these threads exist.
 

ThomasDirkse

New member
Local time
Today, 04:10
Joined
Apr 6, 2023
Messages
11
I believe this code will return the main form no matter how many subforms and how many tabs the control is nested.
Code:
Public Function GetMainForm(Ctl As Access.Control) As Form
  On Error GoTo errlbl
  Dim CurrentObject As Object
  Set CurrentObject = Ctl
  Do
    Set CurrentObject = CurrentObject.Parent
    If TypeOf CurrentObject Is Form Then
      Set GetMainForm = CurrentObject
    End If
  Loop
  Exit Function
errlbl:
   If Err.Number <> 2452 Then
     MsgBox Err.Number & Err.Description
   End If
  End Function
In other words it keeps calling the parent (form, page, tab) until the object no longer has a parent. That can only be the main form.
The like how elegant this method is for finding the main form. Especially if the same form is a subform on different main forms. Thank you for this!

Thanks, Thomas.
 

ThomasDirkse

New member
Local time
Today, 04:10
Joined
Apr 6, 2023
Messages
11
Inspecting the Form variable will help you learn how to reference anything from anywhere.
1. You seem to have a parent form with a tab control and a subform control on page 2 of that tab.
2. The requirement is to reference a textbox in the subform from the parent form.

If I add a little Stop in form2's open event like this:

Code:
Private Sub Form_Open(Cancel As Integer)
Stop
End Sub

I see that I get a Me variable in my locals window
View attachment 107462
If I expand that variable, I can inspect it. The first thing I can see is that I have a node called "Controls". If I expand controls I get this:
View attachment 107463
Notice how I get 1 tab control item, 2 pages items, 1 subform item as well as other items from the very same Controls node. That's only one example, but if I go to the Form node, and then the Controls node of that, I get the same. If I go to the the Module node and then Parent, then Controls, I get the same. And there are other nodes from where I can get references, there's the Application node, the Parent node, the Properties node, etc. Most notably, at the end of the tree of nodes, I get the contents of these Controls nodes. So I can use any and all of these.

I will open a few nodes and see what references I can come up with:

From Me.Controls:
Me.Controls.Item("TabCtl0").Pages.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value
Me.Controls.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value
Me.Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value

From Me.Form.Controls:
Me.Form.Controls.Item("TabCtl0").Pages.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value
Me.Form.Controls.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value
Me.Form.Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value

From Me.Properties:
Me.Properties.Item("BorderStyle").Parent.Controls.Item("TabCtl0").Pages.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value

From Me:
Me.TabCtl0.Pages.Item("page2").Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value

And any time you see .Item("Something") can be replaced with !Something, for example:
Me.Controls.Item("TabCtl0").Pages!page2.Controls.Item("child_form").Controls.Item("txtSomeTextbox").Value

I could go on with other places where the reference can be made, but I hope you get the point. Check the attachment. If I wanted to reference something from outside, like a module, then instead of Me, use Application.Forms("theForm") and inspect it.
This is fantastic. I didn't know you can do this with the Locals window. Thank you for taking the time and effort to explain this. To have a fail-safe approach to referencing, to me, is of great value. I've downloaded your database and I'm going to see if I can learn to find my way around the Locals window.

Between you and MajP I have learned the most from any forum yet! I deeply appreciate the effort. Thanks again, Thomas.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 06:10
Joined
May 21, 2018
Messages
8,536
Nah. Sure-fire all the way, MajP. I use that syntax. It never misses.
Not suggesting it is somehow wrong since I used it to explain the dilemma with the parent property, but I have never seen anyone beside you actually reference a control on a tab through the tab control and pages collection when you can go direct.
Shortcuts are taught wrong. I know it. You know it. Everyone with enough time in this knows it. Shortcuts are the reason these threads exist.
No idea what that means, and do not really think the reason these threads exists has something to do with shortcuts. In this case it is definitely not "taught wrong." The Access developers purposely made these controls direct properties of the form, for the purpose of making it easier to reference them.
 

561414

Active member
Local time
Today, 05:10
Joined
May 28, 2021
Messages
280
Not suggesting it is somehow wrong since I used it to explain the dilemma with the parent property, but I have never seen anyone beside you actually reference a control on a tab through the tab control and pages collection when you can go direct.

No idea what that means, and do not really think the reason these threads exists has something to do with shortcuts. In this case it is definitely not "taught wrong." The Access developers purposely made these controls direct properties of the form, for the purpose of making it easier to reference them.
Inspecting the Form object will help you clear any doubts about Parent references. Several members of the Form class inherit Parent. In the example I provided, I'm using Parent to reference the same textbox from the BorderStyle property, an exercise to demonstrate that even a property can be used to reach the control. Information that is easy to understand through inspection.

Since inspection is never mentioned in threads about referencing controls, developers may get the wrong idea that there's only one way to do things, especially when they're presented with the link in post #6, when the information has always been in plain sight, not even hidden, because developers see it all the time while trying to debug the reference (if their locals window is visible). The syntax I'm using is THE exercise we should all be presented with when trying to reference something. The syntax is long, but it's consistent and you can use shortcuts if you want, like I mentioned. However, posts #2, #3, #5, #6, #7, #10 and #14 are using shortcuts, especially the link in post #6, which combines default members, bang and dot notation. How could new developers not get confused with this amount of variation?
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 18:10
Joined
May 7, 2009
Messages
19,247
How could new developers not get confused with this amount of variation?
well without any reading material about msa, he will be at lost.
a solid foundation is necessary before going deep in programming.
you don't practice anything that you are in mastery of it.

it is always true, read the manual first before operating.

post#2 is shortcut, because reference to a control in a form can have many
notation and i prefer the shorter one.

also post#2 is intended to answer post#1, a Textbox (not a subform) inside the tab control.
 

Users who are viewing this thread

Top Bottom