TL;DR — Un
ComboBoxes una lista desplegable: elige un elemento o (por defecto) escribe el tuyo. Rellénalo conComboBox1.List = Range("A2:A50").Value. Responde dos preguntas a la vez — qué elemento con.ListIndex(base 0,-1cuando el texto no está en la lista) y qué texto con.Value. La trampa:.Value <> ""solo demuestra que el cuadro no está vacío, no que el usuario eligiera un elemento real. Si necesitas una elección válida de la lista, comprueba.ListIndex >= 0, o prohíbe escribir con.Style = fmStyleDropDownList.
' Leer una eleccion de ComboBox - exige que venga de la lista
Private Sub cmdOK_Click()
If ComboBox1.ListIndex = -1 Then
MsgBox "Please choose an item from the list."
Exit Sub
End If
MsgBox "You chose " & ComboBox1.Value ' una eleccion real, respaldada por la lista
End Sub
Un ComboBox es un control de un UserForm, y sigue la misma regla que cualquier otro
control: lees la elección a través de una propiedad, no del cuadro en sí. La diferencia con un
ListBox es que un ComboBox muestra una línea y puede aceptar escritura — que es justo
donde vive el error interesante.
Lo que aprenderás
- Por qué un
ComboBoxes unListBoxplegado en una sola línea, y se lee casi igual - Cómo rellenarlo con
.List = Range.Valuede una vez, o.AddItempara elementos calculados - Las dos preguntas que responde: qué fila (
.ListIndex) y qué texto (.Value) - La propiedad
.Style—fmStyleDropDownCombodeja escribir al usuario,fmStyleDropDownListno - La trampa número uno:
.Value <> ""no es una elección válida; comprueba.ListIndex >= 0 - Cuándo un
ComboBoxes el control adecuado y cuándo encaja mejor unListBox
El modelo mental: un ListBox en una línea que además te deja escribir
Un ComboBox es un ListBox plegado en una única línea con una flecha desplegable. Lo
rellenas de la misma forma y lo lees con las mismas dos propiedades — pero, como también puede aceptar texto
libre, siempre responde dos preguntas a la vez:
ComboBox1.ListIndex ' QUE fila esta elegida (base 0, -1 = el texto no esta en la lista)
ComboBox1.Value ' QUE texto hay en el cuadro (un elemento de la lista, O lo que se haya escrito)
Ten esas dos cosas separadas y el control cobra sentido. .Value es lo que dice el cuadro. .ListIndex es si
eso vino de la lista. Cuando el usuario elige del desplegable, ambas coinciden. Cuando el usuario escribe algo
nuevo, .Value contiene el texto escrito y .ListIndex es -1 — la señal de que el texto no es un elemento de
la lista.
Rellenar un ComboBox
Rellenar es idéntico a un ListBox. Asigna una columna entera de golpe, que es el camino rápido:
Private Sub UserForm_Initialize()
ComboBox1.List = Sheet1.Range("A2:A50").Value ' de una vez desde una columna
End Sub
Range.Value es una matriz 2D y .List acepta una, así que una sola línea carga la lista desplegable (mira
VBA Range). Usa .AddItem solo para elementos construidos uno a uno:
Dim i As Long
For i = 1 To 12
ComboBox1.AddItem "Month " & i ' anadir elementos calculados de uno en uno
Next i
Llama a ComboBox1.Clear para vaciarlo antes de rellenarlo de nuevo. Si quieres que el cuadro empiece mostrando
un valor por defecto, pon .ListIndex = 0 tras rellenarlo, o asigna .Value a un elemento conocido.
Style: decide si el usuario puede escribir
Esta es la propiedad que la gente pasa por alto. Un ComboBox tiene un .Style que controla todo su carácter:
ComboBox1.Style = fmStyleDropDownCombo ' por defecto: elegir de la lista O escribir el tuyo
ComboBox1.Style = fmStyleDropDownList ' bloqueado: el usuario SOLO puede elegir un elemento de la lista
fmStyleDropDownCombo es el valor por defecto — el usuario puede escribir cualquier cosa. fmStyleDropDownList
convierte el ComboBox en un selector estricto: escribir solo salta a los elementos coincidentes, y el valor
final siempre es uno de los tuyos. Si tu formulario no debe aceptar texto libre, fija el .Style — no intentes
validarlo a posteriori.
La trampa número uno: un cuadro no vacío no es una elección válida
Aquí está el error que deja pasar datos malos. Con el estilo por defecto, el usuario puede escribir un valor que no está en tu lista. Si tu código solo comprueba que el cuadro no está vacío, acepta encantado la errata:
' MAL - acepta cualquier cosa que el usuario escriba
If ComboBox1.Value <> "" Then ProcessOrder ComboBox1.Value
' BIEN - exige que la eleccion venga de la lista
If ComboBox1.ListIndex >= 0 Then
ProcessOrder ComboBox1.Value
Else
MsgBox "Please choose an item from the list, not free text."
End If
.Value <> "" solo demuestra que algo hay en el cuadro. .ListIndex >= 0 demuestra que el usuario eligió un
elemento real de la lista — porque .ListIndex es -1 siempre que el texto se escribe en lugar de elegirse. La
regla es simple: cuando importa una elección válida de la lista, comprueba .ListIndex, nunca .Value <> "".
Si el texto libre no debe ser posible en absoluto, el arreglo más limpio está aguas arriba — pon
.Style = fmStyleDropDownList y la trampa no puede ocurrir. (También existe una propiedad .MatchRequired que
rechaza un texto que no coincide cuando el cuadro pierde el foco, pero fijar el .Style es la herramienta más
contundente y segura.)
Value frente a Text, y reaccionar a un cambio
Para un ComboBox, .Value y .Text suelen leer la misma cadena. La que usarás es .Value. .Text importa
cuando te interesa lo que se muestra mientras se escribe, antes de que la entrada se confirme. Para reaccionar
en el instante en que el usuario cambia la selección, gestiona el evento Change:
Private Sub ComboBox1_Change()
' se dispara en cada pulsacion y cada eleccion - mantenlo ligero
Label1.Caption = "Current: " & ComboBox1.Value
End Sub
Como Change se dispara en cada pulsación en un ComboBox en el que se puede escribir, mantén ese manejador
barato — no ejecutes una consulta a la base de datos por cada carácter.
¿ComboBox o ListBox? Elige por espacio y multiplicidad
Un ComboBox y un ListBox comparten sus propiedades de relleno y lectura, así que
elige por cómo debe comportarse la elección. Usa un ComboBox cuando la respuesta sea un único valor, el
espacio escasee y una lista desplegable plegada quede más ordenada — o cuando quieras permitir escritura libre.
Usa un ListBox cuando las opciones deban estar visibles de un vistazo o el usuario pueda elegir más de
una; la selección múltiple es una función exclusiva del ListBox. Un ComboBox nunca puede devolver varios
elementos.
Cómo te ayuda ExcelMaster
El fallo silencioso aquí es un ComboBox que acepta cualquier cosa que el usuario escriba porque el código
comprobó .Value <> "" en vez de .ListIndex >= 0 — así que un nombre de producto mal escrito fluye directo a
tus datos.
ExcelMaster te deja describir el control
con palabras llanas — «una lista desplegable de códigos de producto que el usuario debe elegir, sin texto libre»
— y fija el .Style correcto, rellena la lista desde tus datos y lee la elección comprobando .ListIndex para
que solo pasen selecciones reales. Tú conservas el libro y el código.
Preguntas frecuentes
¿Cómo relleno un ComboBox desde un rango en VBA?
Asigna el rango a .List en una sola sentencia: ComboBox1.List = Sheet1.Range("A2:A50").Value. Como
Range.Value es una matriz 2D y .List acepta una, esto carga la columna entera de una vez. Usa .AddItem solo
para elementos que construyes individualmente, y llama a .Clear antes de rellenar un cuadro que ya tiene filas.
¿Cómo obtengo el valor seleccionado de un ComboBox de VBA?
Lee .Value para el texto de la entrada actual y .ListIndex para la fila con base 0 de la que vino.
.ListIndex es -1 cuando el texto se escribió en lugar de elegirse de la lista, así que si exiges una elección
real de la lista, comprueba .ListIndex >= 0 antes de actuar sobre .Value.
¿Cómo impido que el usuario escriba texto libre en un ComboBox?
Pon ComboBox1.Style = fmStyleDropDownList. Eso bloquea el control a solo elementos de la lista — escribir
simplemente salta a las entradas coincidentes y el valor final siempre es uno de los tuyos. El valor por defecto,
fmStyleDropDownCombo, permite escritura libre, que es por lo que validar con .ListIndex >= 0 importa cuando lo
conservas.
¿Qué significa ListIndex = -1 en un ComboBox?
Significa que el texto actual no es uno de los elementos de la lista — o el cuadro está vacío o el usuario
escribió algo que no coincide. Una elección válida del desplegable siempre da un .ListIndex de 0 o mayor, así
que .ListIndex = -1 es tu señal para rechazar la entrada o volver a pedirla.
¿Cuál es la diferencia entre un ComboBox y un ListBox?
Un ComboBox muestra una línea con una lista desplegable, devuelve un único valor y puede permitir escritura
libre; un ListBox muestra varias filas a la vez y puede permitir selecciones múltiples.
Elige un ComboBox para una elección única y compacta, y un ListBox cuando las opciones deban estar visibles o
el usuario elija más de una.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 25/09/2026.
Guías relacionadas: VBA ListBox · VBA CheckBox · VBA UserForm · VBA Range · VBA InputBox
