🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA CheckBox in Excel — True/False, the TripleState Null, and Grouping Option Buttons

|

VBA CheckBox in Excel — True/False, the TripleState Null, and Grouping Option Buttons

TL;DR — A CheckBox is a yes/no toggle: read .Value as a Boolean, True or False, with If CheckBox1.Value Then .... Two things surprise people. TripleState = True gives .Value a third state, Null, and then If CheckBox1.Value raises a Type mismatch. And its cousin the OptionButton (a radio button) is exclusive by container: every option button on the same form is one group, so you separate independent groups with a Frame. CheckBox = independent toggles; OptionButton-in-a-Frame = pick exactly one.

' Reading checkboxes is as simple as VBA gets
Private Sub cmdSave_Click()
    If chkEmail.Value Then Range("B1").Value = "Email opt-in"
    If chkSMS.Value Then Range("B2").Value = "SMS opt-in"
End Sub

A CheckBox is a control on a UserForm, and it is the friendliest one to read: its .Value is a plain Boolean. That simplicity is exactly why the two exceptions below catch people out — you stop expecting the control to do anything clever, and then TripleState or an ungrouped radio set bites.

What you'll learn

  • Reading a CheckBox as a Boolean, the simplest control on any form
  • The TripleState trap: a third .Value of Null that makes If CheckBox1.Value fail
  • Why OptionButton groups are decided by their container, not by naming
  • How a Frame (or GroupName) keeps two radio groups from fighting each other
  • The judgment call: CheckBox for independent yes/nos, OptionButton for one-of-many
  • Why you should never fake a radio group out of checkboxes

The mental model: a checkbox is a Boolean you can see

There is almost nothing to a CheckBox. It is a Boolean with a label on it:

CheckBox1.Value       ' True when ticked, False when clear

Read it with an If, write it to toggle the tick, and you are done. This is the cleanest control-to-code mapping on a form, and for a set of independent yes/no options — email opt-in, SMS opt-in, include totals — it is exactly right. Each checkbox stands alone; ticking one has no effect on any other. Hold on to that "independent" idea, because it is the line between a CheckBox and an OptionButton.

The TripleState trap: when .Value can be Null

A CheckBox has a TripleState property. Leave it False (the default) and .Value is only ever True or False. Set it True and the control gains a third state — a greyed, indeterminate tick — whose .Value is Null, not False:

' With TripleState = True, this line can blow up
If CheckBox1.Value Then ...     ' Null in an If raises run-time error 13, Type mismatch

If Null Then is a Type mismatch (run-time error 13), because Null is neither True nor False. So if you turn on TripleState, you must test the three states explicitly:

If IsNull(CheckBox1.Value) Then
    ' indeterminate - neither on nor off
ElseIf CheckBox1.Value Then
    ' ticked
Else
    ' clear
End If

The practical advice: do not enable TripleState unless you genuinely need an indeterminate state. Most forms do not, and every one that leaves it off can read .Value with a plain If.

OptionButton: the same simplicity, one exclusive answer

An OptionButton (a radio button) reads exactly like a CheckBox — .Value is True for the selected one — but its whole point is that only one in a group can be True at a time. Selecting one clears the others. You read a group by finding the one that is on:

Dim shipping As String
If optStandard.Value Then shipping = "Standard"
If optExpress.Value Then shipping = "Express"
If optOvernight.Value Then shipping = "Overnight"

That is the right control when the answer is one of several — shipping speed, a payment method, a size. Where it goes wrong is grouping.

The grouping trap: option buttons are exclusive by container

This is the mistake that produces "selecting one radio deselects a button in a totally unrelated group." OptionButton exclusivity is decided by the container, not by names or intent. Every option button placed directly on the UserForm belongs to one group — so two separate radio questions on the same form fight each other. The fix is to give each set its own container, a Frame:

UserForm
  Frame "Shipping"        <- one exclusive group
    optStandard
    optExpress
    optOvernight
  Frame "Payment"         <- a separate, independent group
    optCard
    optInvoice

Drop each cluster of option buttons inside its own Frame and each Frame becomes an independent group: now the user can pick one shipping speed and one payment method without the two interfering. (Alternatively, set each button's .GroupName property to a shared string; the Frame is the visual and usually the clearer choice.)

The judgment call: CheckBox or OptionButton

The choice is about the shape of the answer, and it is not a matter of taste:

  • Use CheckBox when options are independent and any number may be on — features to enable, columns to include, opt-ins. Several can be ticked at once.
  • Use OptionButton (in a Frame) when the answer is exactly one of a mutually exclusive set — a mode, a speed, a size.

And the anti-pattern to avoid: never fake a radio group with checkboxes by writing code that unticks the others when one is ticked. That is re-implementing, badly, what an OptionButton group already does for free — and it is the kind of hand-rolled state that breaks the moment you add a fourth option. If the answer is one-of-many, use OptionButtons in a Frame.

How ExcelMaster helps

Two failures on this page are quiet and annoying: an If CheckBox1.Value that crashes with Type mismatch because TripleState slipped a Null in, and radio buttons that clear each other across unrelated questions because nobody put them in Frames.

ExcelMaster lets you describe the form in plain words — "three independent opt-in checkboxes, plus a shipping-speed choice and a payment choice" — and it lays out the CheckBoxes, groups the OptionButtons in their own Frames so they do not interfere, and reads each control the right way. You keep the workbook and the code.

Frequently asked questions

How do I read whether a CheckBox is ticked in VBA?

Read its .Value, which is a Boolean: If CheckBox1.Value Then ... runs when the box is ticked. Writing CheckBox1.Value = True ticks it from code. This works cleanly as long as TripleState is False, which is the default.

Why does If CheckBox1.Value give a Type mismatch error?

Because TripleState is turned on, and the checkbox is in its third, indeterminate state where .Value is Null. If Null Then raises run-time error 13, Type mismatch. Either leave TripleState = False so the value is only ever True or False, or test the three states with IsNull(CheckBox1.Value) before the If.

Why do my option buttons deselect each other across different groups?

Because OptionButton exclusivity is set by the container. Every option button placed directly on the UserForm is treated as a single group, so unrelated questions interfere. Put each set of option buttons inside its own Frame (or give each set a distinct .GroupName) to make them independent groups.

What is the difference between a CheckBox and an OptionButton?

A CheckBox is an independent yes/no toggle — any number can be ticked at once. An OptionButton is one choice from a mutually exclusive group — selecting one clears the rest. Use checkboxes for independent options and option buttons (grouped in a Frame) when the user must pick exactly one.

How do I group option buttons in a VBA UserForm?

Put each group of OptionButton controls inside its own Frame control; the Frame defines the group, so buttons in different frames no longer clear each other. If you cannot use frames, set each group's .GroupName property to a shared, distinct string. Either way, the goal is to give each exclusive question its own container.

Tested in

Tested in: Excel 365 (Windows 11), VBA 7.1 — last verified 2026-09-25.

Related guides: VBA ListBox · VBA ComboBox · VBA UserForm · VBA MsgBox · VBA If Then Else