TL;DR — Un
CheckBoxes un interruptor de sí/no: lees.Valuecomo unBoolean,TrueoFalse, conIf CheckBox1.Value Then .... Dos cosas sorprenden.TripleState = Truele da a.Valueun tercer estado,Null, y entoncesIf CheckBox1.Valuelanza un « Type mismatch ». Y su primo elOptionButton(un botón de opción) es exclusivo por contenedor: cada botón de opción del mismo formulario es un grupo, así que separas grupos independientes con unFrame.CheckBox= interruptores independientes;OptionButton-en-un-Frame= elige exactamente uno.
' Leer casillas es lo mas simple que hay en VBA
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
Un CheckBox es un control de un UserForm, y es el más amable de leer: su .Value es un
Boolean corriente. Esa simplicidad es justo por lo que las dos excepciones de abajo pillan a la gente — dejas de
esperar que el control haga nada astuto, y entonces TripleState o un conjunto de botones de opción sin agrupar
te muerde.
Lo que aprenderás
- Leer un
CheckBoxcomo unBoolean, el control más simple de cualquier formulario - La trampa de
TripleState: un tercer.ValuedeNullque hace fallar aIf CheckBox1.Value - Por qué los grupos de
OptionButtonlos decide su contenedor, no el nombre - Cómo un
Frame(oGroupName) impide que dos grupos de radio peleen entre sí - El juicio a hacer:
CheckBoxpara síes/noes independientes,OptionButtonpara uno-de-muchos - Por qué nunca deberías fingir un grupo de radio a base de casillas
El modelo mental: una casilla es un Boolean que puedes ver
No hay casi nada en un CheckBox. Es un Boolean con una etiqueta encima:
CheckBox1.Value ' True cuando esta marcada, False cuando esta vacia
Léelo con un If, escríbelo para conmutar la marca, y ya está. Este es el mapeo control-a-código más limpio de un
formulario, y para un conjunto de opciones de sí/no independientes — alta de correo, alta de SMS, incluir
totales — es exactamente lo correcto. Cada casilla va por su cuenta; marcar una no tiene efecto sobre ninguna
otra. Aférrate a esa idea de «independiente», porque es la línea que separa a un CheckBox de un OptionButton.
La trampa de TripleState: cuando .Value puede ser Null
Un CheckBox tiene una propiedad TripleState. Déjala en False (el valor por defecto) y .Value solo será
alguna vez True o False. Ponla en True y el control gana un tercer estado — una marca gris e
indeterminada — cuyo .Value es Null, no False:
' Con TripleState = True, esta linea puede reventar
If CheckBox1.Value Then ... ' Null en un If lanza el error en tiempo de ejecucion 13, Type mismatch
If Null Then es un « Type mismatch » (error en tiempo de ejecución 13), porque Null no es ni True ni
False. Así que si activas TripleState, debes probar los tres estados explícitamente:
If IsNull(CheckBox1.Value) Then
' indeterminada - ni activada ni desactivada
ElseIf CheckBox1.Value Then
' marcada
Else
' vacia
End If
El consejo práctico: no actives TripleState a menos que de verdad necesites un estado indeterminado. La
mayoría de los formularios no lo necesitan, y todo el que lo deja desactivado puede leer .Value con un If
corriente.
OptionButton: la misma simplicidad, una única respuesta exclusiva
Un OptionButton (un botón de opción) se lee exactamente como un CheckBox — .Value es True para el
seleccionado — pero su razón de ser es que solo uno de un grupo puede ser True a la vez. Seleccionar uno
borra los demás. Lees un grupo encontrando el que está activado:
Dim shipping As String
If optStandard.Value Then shipping = "Standard"
If optExpress.Value Then shipping = "Express"
If optOvernight.Value Then shipping = "Overnight"
Ese es el control adecuado cuando la respuesta es una de varias — velocidad de envío, un método de pago, una talla. Donde se tuerce es al agrupar.
La trampa de la agrupación: los botones de opción son exclusivos por contenedor
Este es el error que produce «seleccionar un radio deselecciona un botón de un grupo totalmente ajeno». La
exclusividad de OptionButton la decide el contenedor, no los nombres ni la intención. Cada botón de opción
colocado directamente sobre el UserForm pertenece a un grupo — así que dos preguntas de radio distintas en
el mismo formulario pelean entre sí. El arreglo es dar a cada conjunto su propio contenedor, un Frame:
UserForm
Frame "Shipping" <- un grupo exclusivo
optStandard
optExpress
optOvernight
Frame "Payment" <- un grupo aparte, independiente
optCard
optInvoice
Suelta cada racimo de botones de opción dentro de su propio Frame y cada Frame se convierte en un grupo
independiente: ahora el usuario puede elegir una velocidad de envío y un método de pago sin que los dos
interfieran. (Como alternativa, pon la propiedad .GroupName de cada botón a una cadena compartida; el Frame
es la opción visual y normalmente la más clara.)
El juicio a hacer: CheckBox o OptionButton
La elección va sobre la forma de la respuesta, y no es cuestión de gustos:
- Usa
CheckBoxcuando las opciones sean independientes y pueda estar activado cualquier número — funciones que habilitar, columnas que incluir, altas. Varias pueden marcarse a la vez. - Usa
OptionButton(dentro de unFrame) cuando la respuesta sea exactamente una de un conjunto mutuamente excluyente — un modo, una velocidad, una talla.
Y el antipatrón a evitar: nunca finjas un grupo de radio con casillas escribiendo código que desmarca las
demás cuando se marca una. Eso es reimplementar, y mal, lo que un grupo de OptionButton ya hace gratis — y es
la clase de estado hecho a mano que se rompe en cuanto añades una cuarta opción. Si la respuesta es
uno-de-muchos, usa OptionButton dentro de un Frame.
Cómo te ayuda ExcelMaster
Dos fallos de esta página son silenciosos y molestos: un If CheckBox1.Value que revienta con « Type mismatch »
porque TripleState coló un Null, y botones de radio que se borran entre sí a través de preguntas ajenas
porque nadie los puso en Frames.
ExcelMaster te deja describir el formulario
con palabras llanas — «tres casillas de alta independientes, más una elección de velocidad de envío y una
elección de pago» — y coloca los CheckBox, agrupa los OptionButton en sus propios Frame para que no
interfieran, y lee cada control de la forma correcta. Tú conservas el libro y el código.
Preguntas frecuentes
¿Cómo leo si una CheckBox está marcada en VBA?
Lee su .Value, que es un Boolean: If CheckBox1.Value Then ... se ejecuta cuando la casilla está marcada.
Escribir CheckBox1.Value = True la marca desde el código. Esto funciona limpiamente mientras TripleState sea
False, que es el valor por defecto.
¿Por qué If CheckBox1.Value da un error « Type mismatch »?
Porque TripleState está activado, y la casilla está en su tercer estado, indeterminado, donde .Value es
Null. If Null Then lanza el error en tiempo de ejecución 13, « Type mismatch ». O bien dejas
TripleState = False para que el valor solo sea alguna vez True o False, o pruebas los tres estados con
IsNull(CheckBox1.Value) antes del If.
¿Por qué mis botones de opción se deseleccionan entre sí en grupos distintos?
Porque la exclusividad de OptionButton la fija el contenedor. Cada botón de opción colocado directamente sobre
el UserForm se trata como un solo grupo, así que preguntas ajenas interfieren. Pon cada conjunto de botones de
opción dentro de su propio Frame (o da a cada conjunto un .GroupName distinto) para convertirlos en grupos
independientes.
¿Cuál es la diferencia entre una CheckBox y un OptionButton?
Una CheckBox es un interruptor de sí/no independiente — cualquier número puede estar marcado a la vez. Un
OptionButton es una única elección de un grupo mutuamente excluyente — seleccionar uno borra el resto. Usa
casillas para opciones independientes y botones de opción (agrupados en un Frame) cuando el usuario deba elegir
exactamente uno.
¿Cómo agrupo botones de opción en un UserForm de VBA?
Pon cada grupo de controles OptionButton dentro de su propio control Frame; el Frame define el grupo, así
que los botones de distintos frames ya no se borran entre sí. Si no puedes usar frames, pon la propiedad
.GroupName de cada grupo a una cadena compartida y distinta. En cualquier caso, el objetivo es dar a cada
pregunta exclusiva su propio contenedor.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 25/09/2026.
Guías relacionadas: VBA ListBox · VBA ComboBox · VBA UserForm · VBA MsgBox · VBA If Then Else
