> ## Content Index
> Fetch the complete content index at: https://nolongerset.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Get Form By Control
- URL: https://nolongerset.com/get-form-by-control/
- Published: 2021-05-15T03:43:44.000Z
- Updated: 2026-05-08T13:04:41.000Z
- Description: Let's use recursion and the TypeOf...Is expression to get the first form parent of any control on our form.
- Author: Mike Wolfe
- Tags: Code Library, #FormFunctions, #Import 2026-05-20 02:59

In my article, [Using WithEvents to Encapsulate Event Handling Code](https://nolongerset.com/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:

```vba
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:

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2021/05/image-42.png)

### 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](https://nolongerset.com/recursion-demystified-creating-subfolders/) and [TypeOf...Is expressions](https://nolongerset.com/typeof-vs-typename/)–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.

```vba
'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:

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2021/05/image-43.png)

### 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.