TL;DR — Un
Framees un contenedor, no decoración. Su borde con etiqueta es lo de menos: el frame es dueño de los controles que hay dentro. Esa propiedad hace que un conjunto de botones de opción sea mutuamente excluyente como grupo — los botones de opción soltados directamente sobre un formulario forman todos un único grupo, así que solo se puede elegir uno. Un frame también tiene su propia subcolecciónControlsy sus propios.Enabledy.Visible, así que puedes activar o desactivar toda una sección de una vez.
' Dos elecciones independientes necesitan dos frames.
' Los OptionButtons dentro de fraSize son exclusivos entre si;
' Los OptionButtons dentro de fraColour son un grupo aparte.
Private Sub UserForm_Initialize()
fraSize.Caption = "Size"
fraColour.Caption = "Colour"
optSmall.Value = True ' un valor por defecto por frame
optRed.Value = True
End Sub
Un Frame es el único control de UserForm que añades por el bien de los otros controles. Por sí solo casi no hace nada; su propósito es contener un grupo, y ese papel de contenedor completa la familia de controles. Al que llegas como todo lo demás a través de la colección Controls del formulario, un frame es donde vive de verdad la regla de agrupación de botones de opción, y es cómo acotas y activas una sección del formulario como una unidad. Si alguna vez pusiste dos conjuntos de botones de radio en un formulario y descubriste que elegir uno deselecciona el otro, este control es el arreglo.
Lo que aprenderás
- Por qué un
Framees un contenedor que es dueño de sus controles, no solo un borde - La regla para la que existen los Frames: hacer que los botones de opción sean exclusivos por grupo
- La alternativa
GroupNamey cuándo preferirla - Que un frame tiene su propia subcolección
Controls - Activar toda una sección con
.Enabledy.Visibledel frame - La cadena
Parent, y por qué cambia cómo llegas a un control
El modelo mental: un Frame es un contenedor, no decoración
Es tentador ver un Frame como una caja cosmética con una etiqueta. En realidad es un padre: los controles que dibujas dentro le pertenecen a él, no al formulario. Esa única relación — el frame es dueño de sus hijos — es el origen de todo lo útil que tiene. Mueve el frame y sus hijos se mueven. Desactiva el frame y sus hijos se ven en gris. Y un grupo de botones de opción dentro del frame compite solo entre ellos. El borde que ves es solo el filo visible de una frontera de propiedad.
La razón de ser de los Frames: agrupar botones de opción
Este es el titular. Los OptionButtons (botones de radio) son mutuamente excluyentes dentro de su contenedor. Suelta seis botones de opción directamente sobre un formulario y comparten un contenedor — el formulario — así que elegir cualquiera borra los otros cinco, aunque los pensaras como dos preguntas separadas:
' MAL: seis botones de opcion en el formulario desnudo = un grupo.
' Elegir optRed borra optSmall. El usuario no puede elegir una talla Y un color.
Pon cada pregunta en su propio frame y cada una se convierte en un grupo independiente:
' BIEN: tres opciones de talla en fraSize, tres opciones de color en fraColour.
' Ahora el usuario elige una talla y un color, independientemente.
El frame es el grupo. Esto no es un detalle bonito — es la única forma limpia de tener más de un
conjunto de botones de radio en un formulario. (Los CheckBoxes nunca se agrupan así; cada uno es
independiente, que es exactamente la distinción de CheckBox.)
La alternativa GroupName y cuándo preferirla
Hay una segunda forma de agrupar botones de opción: darles la misma cadena GroupName. Los botones
que comparten un GroupName son excluyentes incluso sin un frame alrededor:
optCash.GroupName = "Payment"
optCard.GroupName = "Payment" ' excluyente con optCash, no hace falta frame
Prefiere un Frame cuando la agrupación también sea visual — el usuario debería ver que las
opciones van juntas, y quieres activarlas u ocultarlas como unidad. Recurre a GroupName cuando
necesites exclusividad sin un contenedor visible, o cuando el diseño hace incómodo un frame. El
frame es la opción por defecto mejor porque hace obvia la agrupación para la siguiente persona que
lea el formulario.
Un Frame tiene su propia colección Controls
Como el frame es dueño de sus hijos, tiene su propia colección Controls — un subconjunto de la
del formulario. Eso te deja recorrer solo los controles de una sección:
Dim ctl As MSForms.Control
For Each ctl In fraSize.Controls ' solo los controles dentro de fraSize
If TypeOf ctl Is MSForms.OptionButton Then
If ctl.Value Then MsgBox "Size chosen: " & ctl.Caption
End If
Next ctl
Esto refleja Me.Controls pero acotado al frame. Es cómo lees qué opción
está seleccionada en este grupo sin tocar el resto del formulario — recorre los controles del
frame y encuentra el único botón de opción cuyo .Value sea True.
Activar toda una sección con Enabled y Visible
Fija el .Enabled o el .Visible del frame y cada hijo lo sigue:
fraShipping.Enabled = chkShip.Value ' pone en gris toda la seccion de envio
fraAdvanced.Visible = False ' oculta las opciones avanzadas hasta que se necesiten
Una línea desactiva u oculta una sección entera — dirección, pago, ajustes avanzados — en lugar de recorrer sus controles. Este es el beneficio del día a día del modelo de contenedor: el frame es un asa sobre el grupo como unidad.
La cadena Parent: el verdadero padre de un control
La propiedad cambia el linaje. Un control dentro de un frame tiene ese frame como su Parent, no
el formulario:
MsgBox optSmall.Parent.Name ' "fraSize", no el nombre del formulario
Dos consecuencias pillan a la gente. Primero, el .Left y el .Top de un control se miden desde
el frame, no desde el formulario, así que mover un control entre un frame y el formulario cambia
dónde cae. Segundo, un control dentro de un frame se alcanza a través del frame, no como elemento de
primer nivel de la propia Controls del formulario — así que un bucle a nivel de formulario que lo
esperaba en el nivel superior lo pasará por alto. Cuando un control parece estar en el lugar
equivocado o no se encuentra donde lo buscaste, comprueba si su Parent es un frame.
El juicio a hacer: cuándo un Frame se gana su sitio
Un Frame es barato, pero no gratis — añade una capa a la cadena de padres y a cómo llegas a los
controles. Añade uno cuando hace un trabajo real: tienes más de un conjunto de botones de opción, o
una sección que quieres activar, ocultar o leer como unidad. No envuelvas cada etiqueta y cuadro
en un frame por estética; eso solo profundiza la cadena de padres y hace que los bucles Controls a
nivel de formulario pasen por alto controles que esperabas encontrar en el nivel superior. La regla
general: un frame debería corresponder a un grupo que el usuario piensa como una sola cosa — una
pregunta con varias respuestas, una sección que se activa junta. Si no agrupa nada, es solo un
borde, y una simple etiqueta hace ese trabajo sin efectos secundarios.
Cómo te ayuda ExcelMaster
El bug clásico de Frame es invisible hasta que pruebas el formulario: dos conjuntos de botones de radio que pelean entre sí porque nunca se enmarcaron, o un control que informa la posición equivocada porque su padre es un frame que olvidaste. Parece un problema de diseño y en realidad es un problema de propiedad.
ExcelMaster te deja describir el
formulario en términos llanos — "una elección de talla y una elección de color, independientes" — y
coloca los frames, agrupa los botones de opción correctamente, y conecta el .Enabled de una
sección a la casilla que la controla. Tú conservas el formulario y el código, y los grupos se
comportan como el usuario espera.
Preguntas frecuentes
¿Qué hace un Frame en un UserForm de VBA?
Un Frame es un contenedor que es dueño de los controles que hay dentro. Más allá del borde
visible con etiqueta, agrupa esos controles para que se muevan, activen y oculten juntos, y — lo más
importante — hace que un conjunto de OptionButtons dentro de él sea mutuamente excluyente como un
solo grupo. También expone su propia colección Controls para recorrer solo esa sección.
¿Por qué mis botones de opción están todos en un mismo grupo?
Porque comparten un contenedor. Los OptionButtons son excluyentes dentro de su padre, y los
botones soltados directamente sobre el formulario comparten todos el formulario como padre — así
que solo se puede seleccionar uno. Pon cada conjunto dentro de su propio Frame (o dale a cada
conjunto un GroupName distinto) para convertirlos en grupos independientes.
¿Cuál es la diferencia entre un Frame y GroupName para agrupar?
Ambos hacen que los botones de opción sean excluyentes. Un Frame los agrupa y muestra un
contenedor visible que puedes activar, ocultar o recorrer como unidad. GroupName los agrupa
mediante una cadena compartida sin caja visible. Usa un Frame cuando la agrupación deba ser
visible o conmutable; usa GroupName cuando necesites exclusividad sin contenedor.
¿Cómo recorro solo los controles dentro de un Frame?
Usa la propia colección del frame: For Each ctl In fraSize.Controls. Contiene solo los controles
cuyo padre es ese frame, así que puedes encontrar el botón de opción seleccionado en un grupo sin
tocar el resto del formulario. Comprueba cada uno con TypeOf ctl Is MSForms.OptionButton antes de
leer su .Value.
¿Por qué la posición o el padre de mi control están mal dentro de un Frame?
Porque el Parent de un control dentro de un frame es el frame, no el formulario, y su .Left y
su .Top se miden desde el frame. Si un control cae en un sitio inesperado después de moverlo
dentro o fuera de un frame, o un bucle Controls a nivel de formulario no lo encuentra como
elemento de primer nivel, el frame en su cadena de padres es la razón.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 28/09/2026.
Guías relacionadas: VBA Controls · VBA CheckBox · VBA UserForm · VBA ListBox · VBA ComboBox · VBA TextBox · VBA On Error
