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

VBA ComboBox en Excel — Rellena una lista desplegable, lee la elección y la trampa de ListIndex = -1

|

VBA ComboBox en Excel — Rellena una lista desplegable, lee la elección y la trampa de ListIndex = -1

TL;DR — Un ComboBox es una lista desplegable: elige un elemento o (por defecto) escribe el tuyo. Rellénalo con ComboBox1.List = Range("A2:A50").Value. Responde dos preguntas a la vez — qué elemento con .ListIndex (base 0, -1 cuando 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 ComboBox es un ListBox plegado en una sola línea, y se lee casi igual
  • Cómo rellenarlo con .List = Range.Value de una vez, o .AddItem para elementos calculados
  • Las dos preguntas que responde: qué fila (.ListIndex) y qué texto (.Value)
  • La propiedad .Style — fmStyleDropDownCombo deja escribir al usuario, fmStyleDropDownList no
  • La trampa número uno: .Value <> "" no es una elección válida; comprueba .ListIndex >= 0
  • Cuándo un ComboBox es el control adecuado y cuándo encaja mejor un ListBox

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