Agregando valores a un cuadro combinado (ComboBox).

miércoles, octubre 01, 2008

Después de publicar mi nota sobre autocompletar en Validación de Datos, algunos lectores me señalan que no logran encontrar la propiedad ListFillRange donde tienen que poner la referencia al rango que contiene los valores de la lista desplegable. Esto tanto con el control cuadro combinado como con el control cuadro de lista.

Existen ciertas diferencias entre los controles que agregamos directamente en una hoja de Excel y aquellos que agregamos a un UserForm en el editor de Visual Basic.

Cuando ponemos un control ActiveX directamente en la hoja vemos las propiedades del control activando el modo Diseño y abriendo el cuadro de propiedades (ambos iconos aparecen en la barra de Cuadro de Controles). Todo esto lo hemos mostrado en la nota mencionada.

Cuando creamos un cuadro combinado (ComboBox) o cuadro de lista (ListBox) sobre un Userform tenemos que activar el panel de propiedades del editor de Vb (VBE) para ver las propiedades




La propiedad que define los valores de cuadro o de la lista es RowSource. Para agregar valores al cuadro podemos usar una referencia a un rango en una hoja de Excel o podemos hacerlo usando código Vba.

Para ejemplificar el primer caso supongamos que en rango A1:A12 de la Hoja1 tenemos una lista de los meses del año, que podemos crear fácilmente con el menú Opciones-Listas Personalizadas.
En la propiedad RowSource del control ComboBox1 ponemos la referencia, con la sintaxis apropiada (ver el signo de exclamación entre el nombre de la hoja y la referencia al rango)



Para comprobar si nuestro control ha recibido los valores, seleccionamos el UserForm y apretamos F5. El UserForm aparecerá en la hoja activa (en realidad "sobre" la hoja) y podemos apretar la flecha para ver los valores disponibles



Otra posibilidad es agregar los valores usando programación. También aquí se nos abren dos posibilidades.
Si los valores se encuentran en un rango de una hoja, como en el caso que acabamos de mostrar, podemos usar un código como éste

Sub agregar_valores()

UserForm1.ComboBox1.RowSource = "Hoja1!A1:A12"

UserForm1.Show
End Sub


Al correr esta macro se abre el UserForm y podemos ver que los valores son los del rango.
Otra posibilidad es agregar los valores usando el método Add Item de Vba:

Sub add_val()
With UserForm1.ComboBox1
.RowSource = " "
.AddItem "Enero"
.AddItem "Febrero"
.AddItem "Marzo"
.AddItem "Abril"
.AddItem "Mayo"
.AddItem "Junio"
.AddItem "Julio"
.AddItem "Agosto"
.AddItem "Setiembre"
.AddItem "Octubre"
.AddItem "Noviembre"
.AddItem "Diciembre"
End With

UserForm1.Show
End Sub


En resumen, el manejo de las propiedades de los controles es distinto dependiendo si los hemos creado directamente en la hoja con la barra de Controles o han sido programados con Visual Basic.



Technorati Tags:

38 comments:

Rodrigo,  14 octubre, 2008 16:39  

Hola,

Me ha servido mucho la información de tu blog, lo encuentro muy bueno.

Quisisera aprovechar la oportunidad para plantearte la siguiente consulta:

El punto es que estoy trabajando con una listbox multiselección (control activex)y necesito ingresar en la celda activa más de un valor. El siguiente código no me ha servido:

Private Sub Proveedores_Click()
ActiveCell.Value = Proveedores.Value
End Sub


¿Me podrías guiar un poco?, te lo agradecería enormemente.

Saludos y muchas gracias desde ya.
Rodrigo

Jorge L. Dunkelman 16 octubre, 2008 21:20  

Hola Rodrigo

en una celda no puede haber más de un valor al mismo tiempo, ya sea texto, numérico, error o lógico.

Anónimo,  18 octubre, 2008 00:44  

Hola, tu blog esta muy interesante, me ayuda mucho.

He seguido los pasos que diste, pero me sale un herror, este dice:

error de compilacion
se esperaba fuction o una variable

Gracias de ante mano por responder.

Jorge L. Dunkelman 18 octubre, 2008 09:59  

Obviamente tienes un error de sintaxis. ¿Cuál de las dos rutinas estás intentando usar?

Anónimo,  21 octubre, 2008 23:15  

Estimado Jorge, tu blog me ha servido montones para mejorar ciertos procesos que involucran muchos datos y requieren precisión en mi trabajo. Gracias por poner tus conocimientos a nuestra disposición.

El sr. anónimo (igual que yo), está en lo correcto y hay dos errores en la sintaxis del ejemplo: poner "=" después de AddItem, y la propiedad RowSource no lleva punto antes.

Saludos cordiales

Jorge L. Dunkelman 22 octubre, 2008 18:19  

Estimado Anónimo

gracias por llamar mi atención sobre los errores. En realidad hay uno, después de AddItem no va "=" sino directamente el nombre del mes entre comillas. El punto antes de RowSurce es necesario para que Vba no lo interprete como variable.

kromu 28 abril, 2009 16:02  

Se puede dar como nombre de una hoja, una formula o una celda ... por ejemplo =A1 ?
Seguro que hay alguna manera però no consigo encontrar-lo

Jorge L. Dunkelman 28 abril, 2009 18:44  

¿Tal vez te refieres a poner el contenido de la celda o el resultado de fórmula como nombre?
Excel es muy flexible con los nombres de las hojas. Las únicas limitaciones que conozco (o que me acuerdo en este momento) son que las hojas no pueden tener nombres con más de 31 caracteres y que no se puede usar ":" (dos puntos).
Manualmente puedes ingresar toda combinación de caracteres que cumpla con las dos reglas indicadas.
Para cambiar el nombre automáticamente tienes que usar Vba (macro).
Esta orden cambia el nombre de la celda de acuerdo al contenido de la celda A1 de la hoja

ActiveSheet.Name = [A1].Value

A1 puede contener una constante o una fórmula.

Anónimo,  17 julio, 2009 13:43  

Buenos días,

Hace ya días de esta entrada en el blog, pero me ha surgido hoy la duda y no encuentro por ninguna parte la solución. Siendo que para mi este site es toda una biblia (hay respuestas para todo), quisiera saber lo siguiente:

Es posible asignar a un rowsurce el nombre que tengo asignado a un rango?
Quiero decir: Yo tengo un rango que se llama "Existencias" y quiero asignar a un listbox ese rango que lo tengo como variable.
He escrito:

Listbox1.rowsource = existencias

Pero me da error: No coinciden los tipos

Habría posibilidad alguna de hacer esto??

Un saludo

Cristina

Jorge L. Dunkelman 17 julio, 2009 18:55  

Cristina

para que VBa entienda que se trata de un nombre, tenés que usar

Listbox1.rowsource = Range("existencias")

Anónimo,  22 febrero, 2012 00:01  

Muy bueno, gracias me es de mucha ayuda tu blog

José Angel Peñuelas Machado 12 abril, 2012 22:21  

Buen día,

Jorge Muchas Gracias por todas las publicaciones...

En relación a ésto, como puedo hacer si un Segundo ComboBox depende del valor que haya puesto en el primero?.

Algo así como la función indirecto en la validación de datos en excel.

José Angel

Saludos

Jorge L. Dunkelman 15 abril, 2012 14:39  

Tendrías que hacerlo con programación (Vba).

Leonardo Rojas Rapso 23 junio, 2012 16:17  

Disculpen como haría para que una vez creado un combo box con la lista que yo deseo, el resultado de mi elección sea enviado a una celda de excel especifica????

Jorge L. Dunkelman 23 junio, 2012 20:20  

Programando un evento (Vba, macros) o usando el valor de la celda ligada como argumento en una fórmula que combine INDICE y COINCIDIR.

Anónimo,  07 julio, 2012 03:15  

Mi problema es este:
Frm_Vtas.Cbo_Empresa.Clear
Frm_Vtas.Cbo_Empresa.ColumnCount = 2
Frm_Vtas.Cbo_Empresa.MatchEntry = 1
Frm_Vtas.Cbo_Empresa.ColumnHeads = False
Frm_Vtas.Cbo_Empresa.BoundColumn = 1
Frm_Vtas.Cbo_Empresa.ColumnWidths = "210;80"

Frm_Vtas.Cbo_Empresa.ListIndex = -1

Cadena = "Bd_Compania!D2:E" +
Trim(Str(Bd_Compania.Range("b3").Value + 1))

Frm_Vtas.Cbo_Empresa.RowSource = Cadena


Me sales como error: 2No se puede configurar la propiedad recordsource. Valor de propiedad no valido.

Jorge L. Dunkelman 10 julio, 2012 19:46  

RowSource tiene que ser una cadena de texto. Comprobá el valor de Cadena, no me parece que resulte en un texto que represente un rango.

Anónimo,  31 agosto, 2012 21:05  

Hola Jorge.

Quisiera saber como puedo lograr que el rango de entrada de datos del combobox sea dinámico, a partir de información de una hoja.

Gracias

Jorge L. Dunkelman 01 septiembre, 2012 09:28  

Hay varias formas de hacerlo. La más cómoda es usando nombres definidos. Por ejemplo, supongamos que los valores están en un rango que empieza en la celda A1 de la Hoja1. Podemos definir el nombre "rango_dinamico" (o culaquier otro nombre) que se refiera a la fórmula:

=Hoja1!$A$1:INDICE($A:$A,CONTARA($A:$A))

Luego en el cuadro de propiedades del control, en la propiedad ListFillRange ponemos rango_dinamico.

Anónimo,  03 noviembre, 2012 16:46  

Muy buena la ayuda, la otra forma de hacerlo seria seleccionando los datos, suponiendo de A1;A5 y en el cuadro de arriba a la izquierda deberiamos poner un nombre por ejmplo "Productos" y prewsionar Enter, depues en rownsource propiedades del combobox solo deberiamos colocar "Productos"( sin las comillas) y listo.

MErcury Phoenix 05 diciembre, 2012 05:12  

muy buena la info del combobox pero me surge una pregunta y es un detallito que no he podido resolver sé y logre que con un combobox me mostrara los proovedores es mas no tan solo su numero de codigo sino tambien el nombre del proovedor en la seccion ColumnCount, hasta se puede hacer que se vean las encabezados de esas columnas en mi caso son 2 columnas y son A y B seria algo asi columna A=443434 y B=Empresa1, ahora bien cuando se selecciona un registro del combobox queda señalado la primera columna es decir el numero de codigo pero quiero y deseo almacenar en una variable el nombre correspondiente a ese codigo para luego su uso en otra parte que voy a necesitar espero sus prontas respuesta y espero me puedan ayudar de antemano mil gracias

Jorge L. Dunkelman 05 diciembre, 2012 18:33  

Tienes que usar la propiedad BoundColumn del control para determinar de que columna extraer el dato. Por ejemplo, si queremos pasar los valores a las celdas A1 y A2

Private Sub cbAceptar_Click()

'primero determinamos la columna y luego extraemos el valor
With Userform1.ComboBox1
.BoundColumn = 1
Range("A1") = .Value
.BoundColumn = 2
Range("A2") = .Value
End With

Unload Userform1

End Sub

Maxellin 28 diciembre, 2012 00:49  

que tal mis Saludo tengo un pequeño problema excelente el Blog pero quisiera saber como ago para que la lista de valla actualizando al ingresar un nuevo elemento

Jorge L. Dunkelman 02 enero, 2013 18:22  

Usando rangos dinámicos. Puedes ver las notas del blog que tratan sobre el tema pulsando la etiqueta "rangos dinámicos" en la nube de etiquetas (en la parte superior de la plantilla).

Anónimo,  10 enero, 2013 15:38  

como puedo vincular 2 o mas cuadros combinados en visual para excel??

Jorge L. Dunkelman 11 enero, 2013 13:24  

Supongo que te refieres a que los valores de un cuadro dependan del valor elegido en el primero. Suponiendo que en un cuadro se elige el país y en el segundoo queremos que aparezcan las ciudades del país elegido, podrías crear nombres definidos (el nombre "argentina" se refiere al rango donde están las ciudades de la Argentina, etc.) y usar estos nombres en el código para definir el Row Source del segundo cuadro combinado.

Anónimo,  12 marzo, 2013 21:46  

Buen dia Jorge!

en base a una consulta anterior (como puedo hacer si un Segundo ComboBox depende del valor que haya puesto en el primero?), me podrias ayudar un poco mas?

Gracias.

Richard 15 mayo, 2013 20:07  

Buen dia Jorge, mi problema es el siguiente:
Dim strSql as string

strSql = "Select campo1, campo2 from tabla"
combo.ColumnCount = 2
combo.Rowsource = strSql

Me arroja el error: No se puede configurar la propiedad Rowsource. Valor de propiedad no valido.

Aclaro que la conexion no la puse aqui por brevedad, pero la consulta arroja datos correctamente. Que me falta? toca ejecutar la cadena antes de asignarla al combo?

Jorge Dunkelman 16 mayo, 2013 07:16  

La propiedad RowSource usa texto o un cadena de texto que representa la dirección de una rango. Las técnicas para agregar los valores son las que muestro en la nota.

Richard 18 mayo, 2013 02:09  

...aahhh y olvide aclararlo, los resultados de la consulta en el combo, pero con los nombres de columna, habilitando la propiedad ColumnHeads a true........ es posible hacerlo?

Jorge Dunkelman 18 mayo, 2013 16:14  

Usando un loop (rizo) para definir los items de la combo. Para ver los detalles de la técnica te sugiero que consultes en algunos de los muchos foros de Vba que hat, como VbaExpress por ejemplo.

Ruben,  23 julio, 2013 15:45  

Hola Jorge.
Tengo un problema, he realizado una hoja excel con varios cuadros combinados para hacer un formulario. Funcionan bien y se pueden escoger los datos, pero cuando guardas y vuelves a abrir no mantiene los campos elegidos.

Jorge Dunkelman 23 julio, 2013 16:34  

Eso pasa si estás usando el control de la colección Formularios y no tienes definida la celda ligada.

Anónimo,  24 julio, 2013 09:41  

Gracias Jorge! Solucionado. Te debo unas cañas.

Fdo: Rubén

Anónimo,  18 octubre, 2013 01:27  

buenas tardes jorge

yo tengo la siguiente condicion en un formulario

Private Sub UserForm_INITIALIZE()
ComboBox2.RowSource = "Hoja1 !LISTA"
End Sub

lo que hace es traerme una lista de un rango de celdas de una hoja de excel denominadas como LISTA. Sin embargo esta lista puede cambiar de tamaño en el excel. es decir, al ejecutar otra macro me añade un elemento a la lista pero en el combobox no me ajusta el tamaño de la lista y me deja el ultimo elemeto por fuera. en este caso me toca salirme del formulario y volverlo a inicializar para que me los muestre completos en el combo. mi pregunta es si sabe alguna forma de que el tamaño de la lista del combobox se este ajustando automaticamente a medida que el cambie la cantidad de items del excel.

agradezco su ayuda.

Jorge Dunkelman 19 octubre, 2013 20:55  

Hola,

la propiedad RowSource está definida por un texto que representa un rango. Es decir, en tu caso, el texto "Hoja1!Lista" representa el rango al que se refiere el nombre definido LISTA.
Todo lo que hay que hacer es definir este nombre en forma dinámica, de manera que cuando se agreguen o quiten valores de la lista, esto se reflejen en el evento Initialize.
Por ejemplo, si los valores de LISTA están en la columna A a partir de la celda A1, esta fórmula define el rango dinámicamente

=Hoja1!$A$1:INDICE(Hoja1!$A:$A,CONTARA(Hoja1!$A:$A))

Publicar un comentario

Seguidores

Google+ Followers

Google+ Badge

Términos Legales

  © Blogger template On The Road by Ourblogtemplates.com 2009

Back to TOP