Get Form By Control

Let's use recursion and the TypeOf...Is expression to get the first form parent of any control on our form.

Get Form By Control

In my article, Using WithEvents to Encapsulate Event Handling Code, I took a bit of a shortcut to find the form object from a text box control.  In that situation, we were dealing with text boxes in the detail section of a continuous form.  And in almost all cases, the parent of such a text box control will be the form itself.

However, I did offer the following caveat in that article:

(* NOTE: There are some corner cases where the control's parent is something other than the containing form object, but we're going to set those aside to keep this article focused on the task at hand.)

Let's properly handle those corner cases now.

Control Parents

Every control in Access has a Parent property.  Different types of controls can have different types of parents.  

Let's consider a highly contrived example:

  • Create a form named MyForm
  • Add a tab control named MyTabCtl
  • On Page1 of the tab control, add an option group named MyOptionGroup
  • Inside the option group, add an option named MyOption
  • Rename the option's label to MyLabel

Now, let's write a routine to show the ancestry of the innermost control, MyLabel:

Sub ShowParents()
    Dim Lbl As Label
    Set Lbl = Form_MyForm.MyLabel
    
    Debug.Print Lbl.Parent.Name
    Debug.Print Lbl.Parent.Parent.Name
    Debug.Print Lbl.Parent.Parent.Parent.Name
    Debug.Print Lbl.Parent.Parent.Parent.Parent.Name
    Debug.Print Lbl.Parent.Parent.Parent.Parent.Parent.Name
End Sub

Here's the output if we run the routine in the Immediate Window:

Finding the Form

As the above code shows, it's naive and dangerous to assume that the parent of any given control is the form.  However, being able to reliably return the enclosing form of an arbitrary control could prove handy.  And with a couple neat tricks–namely, recursion and TypeOf...Is expressions–it's not even all that hard.  Heck, if you're a weirdo like me, you might even say it's fun.

The Code: GetFormByCtl()

The code is simple and straightforward.  We check to see if the parent of the passed control is a form object.  If it is, we return it.  If not, we check that control's parent.  Et cetera, et cetera, until we reach the form object.

'Returns the first form parent of the given control
Function GetFormByCtl(Ctl As Control) As Form
    If TypeOf Ctl.Parent Is Form Then
        Set GetFormByCtl = Ctl.Parent
    Else
        'Recursively call the function until we reach the form
        Set GetFormByCtl = GetFormByCtl(Ctl.Parent)
    End If
End Function

Sample usage

Here's the function in action:

Caveat emptor!

This particular function will return the first ancestor form object.  In other words, if the control you pass to the function is on a subform, then the function will return the subform and not the top-level form.

What if you want the top-level form?  I'll cover that in another article.

All original code samples by Mike Wolfe are licensed under CC BY 4.0