TL;DR — A
Frameis a container, not decoration. Its labelled border is the least of it: the frame owns the controls inside it. That ownership makes a set of option buttons mutually exclusive as a group — option buttons dropped straight on a form are all one group, so only one can ever be chosen. A frame also has its ownControlssub-collection and its own.Enabledand.Visible, so you can switch a whole section on or off at once.
' Two independent choices need two frames.
' OptionButtons inside fraSize are exclusive among themselves;
' OptionButtons inside fraColour are a separate group.
Private Sub UserForm_Initialize()
fraSize.Caption = "Size"
fraColour.Caption = "Colour"
optSmall.Value = True ' one default per frame
optRed.Value = True
End Sub
A Frame is the one UserForm control you add for the sake of the other controls. On its own it does almost nothing; its purpose is to contain a group, and that container role completes the control family. Reached like everything else through the form's Controls collection, a frame is where the option-button grouping rule actually lives, and it is how you scope and switch a section of a form as a unit. If you have ever put two sets of radio buttons on a form and found that choosing one un-chose the other, this control is the fix.
What you'll learn
- Why a
Frameis a container that owns its controls, not just a border - The rule Frames exist for: making option buttons exclusive per group
- The
GroupNamealternative and when to prefer it - That a frame has its own
Controlssub-collection - Switching a whole section with the frame's
.Enabledand.Visible - The
Parentchain, and why it changes how you reach a control
The mental model: a Frame is a container, not decoration
It is tempting to see a Frame as a cosmetic box with a caption. It is really a parent: the controls you draw inside it belong to it, not to the form. That single relationship — the frame owns its children — is the source of everything useful about it. Move the frame and its children move. Disable the frame and its children grey out. And a group of option buttons inside the frame competes only among themselves. The border you see is just the visible edge of an ownership boundary.
The reason Frames exist: grouping option buttons
This is the headline. OptionButtons (radio buttons) are mutually exclusive within their container. Drop six option buttons straight onto a form and they share one container — the form — so choosing any one clears the other five, even if you meant them as two separate questions:
' WRONG: six option buttons on the bare form = one group.
' Picking optRed clears optSmall. The user cannot choose a size AND a colour.
Put each question in its own frame and each becomes an independent group:
' RIGHT: three size options in fraSize, three colour options in fraColour.
' Now the user picks one size and one colour, independently.
The frame is the group. This is not a nicety — it is the only clean way to have more than one set of
radio buttons on a form. (CheckBoxes are never grouped this way; each is independent, which is exactly
the CheckBox distinction.)
The GroupName alternative and when to prefer it
There is a second way to group option buttons: give them the same GroupName string. Buttons sharing a
GroupName are exclusive even without a frame around them:
optCash.GroupName = "Payment"
optCard.GroupName = "Payment" ' exclusive with optCash, no frame needed
Prefer a Frame when the grouping is also visual — the user should see that the options belong together,
and you want to enable or hide them as a unit. Reach for GroupName when you need exclusivity without a
visible container, or when the layout makes a frame awkward. The frame is the better default because it
makes the grouping obvious to the next person reading the form.
A Frame has its own Controls collection
Because the frame owns its children, it has its own Controls collection — a subset of the form's. That
lets you loop just the controls in one section:
Dim ctl As MSForms.Control
For Each ctl In fraSize.Controls ' only the controls inside fraSize
If TypeOf ctl Is MSForms.OptionButton Then
If ctl.Value Then MsgBox "Size chosen: " & ctl.Caption
End If
Next ctl
This mirrors Me.Controls but scoped to the frame. It is how you read which option
is selected in this group without touching the rest of the form — loop the frame's controls and find the
one option button whose .Value is True.
Switching a whole section with Enabled and Visible
Set the frame's .Enabled or .Visible and every child follows:
fraShipping.Enabled = chkShip.Value ' grey out the whole shipping section
fraAdvanced.Visible = False ' hide advanced options until needed
One line disables or hides an entire section — address, payment, advanced settings — instead of looping its controls. This is the everyday payoff of the container model: the frame is a handle on the group as a unit.
The parent chain: a control's real parent
Ownership changes lineage. A control inside a frame has that frame as its Parent, not the form:
MsgBox optSmall.Parent.Name ' "fraSize", not the form's name
Two consequences catch people. First, a control's .Left and .Top are measured from the frame, not the
form, so moving a control between a frame and the form shifts where it lands. Second, a framed control is
reached through the frame, not as a top-level item of the form's own Controls — so a form-level loop that
expected it at the top level will miss it. When a control seems to be in the wrong place or not found where
you looked, check whether its Parent is a frame.
The judgment call: when a Frame earns its place
A Frame is cheap, but not free — it adds a layer to the parent chain and to how you reach controls. Add one
when it does real work: you have more than one set of option buttons, or a section you want to enable, hide,
or read as a unit. Do not wrap every label and box in a frame for looks; that just deepens the parent
chain and makes form-level Controls loops miss controls you expected to find at the top level. The rule of
thumb: a frame should correspond to a group the user thinks of as one thing — a question with several
answers, a section that turns on together. If it does not group anything, it is just a border, and a plain
label does that job with no side effects.
How ExcelMaster helps
The classic Frame bug is invisible until you test the form: two sets of radio buttons that fight each other because they were never framed, or a control that reports the wrong position because its parent is a frame you forgot about. It looks like a layout problem and is really an ownership problem.
ExcelMaster lets you describe the form in
plain terms — "a size choice and a colour choice, independent" — and it lays out the frames, groups the
option buttons correctly, and wires a section's .Enabled to the checkbox that controls it. You keep the
form and the code, and the groups behave the way the user expects.
Frequently asked questions
What does a Frame do in a VBA UserForm?
A Frame is a container that owns the controls inside it. Beyond the visible labelled border, it groups
those controls so they move, enable, and hide together, and — most importantly — it makes a set of
OptionButtons inside it mutually exclusive as one group. It also exposes its own Controls collection for
looping just that section.
Why are my option buttons all in one group?
Because they share a container. OptionButtons are exclusive within their parent, and buttons dropped
straight on the form all share the form as their parent — so only one can be selected. Put each set inside
its own Frame (or give each set a distinct GroupName) to make them independent groups.
What is the difference between a Frame and GroupName for grouping?
Both make option buttons exclusive. A Frame groups them and shows a visible container you can enable,
hide, or loop as a unit. GroupName groups them by a shared string with no visible box. Use a Frame when
the grouping should be visible or switchable; use GroupName when you need exclusivity without a container.
How do I loop only the controls inside a Frame?
Use the frame's own collection: For Each ctl In fraSize.Controls. It contains only the controls parented
to that frame, so you can find the selected option button in one group without touching the rest of the
form. Test each with TypeOf ctl Is MSForms.OptionButton before reading its .Value.
Why is my control's position or parent wrong inside a Frame?
Because a framed control's Parent is the frame, not the form, and its .Left and .Top are measured from
the frame. If a control lands in an unexpected spot after you move it into or out of a frame, or a
form-level Controls loop does not find it as a top-level item, the frame in its parent chain is the
reason.
Tested in
Tested in: Excel 365 (Windows 11), VBA 7.1 — last verified 2026-09-28.
Related guides: VBA Controls · VBA CheckBox · VBA UserForm · VBA ListBox · VBA ComboBox · VBA TextBox · VBA On Error
