sábado, 10 de diciembre de 2011

Asociar a un TextBox el valor seleccionado de un ListBox.

Seguiré hoy con el tema de los últimos días, esto es con Formularios (UserForm) en Excel. Hoy en concreto veremos como asociar a un TextBox el valor seleccionado de un ListBox, es decir, veremos cómo podemos desde un ListBox creado rellenar los TextBox o Cuadros de Texto incluidos en nuestro formulario; además aprenderemos una forma de Cambiar el nombre (propiedad Caption) de nuestras Etiquetas (Labels).
Partiremos del trabajo realizado en la entrada anterior (ListBox con varias columnas y encabezados), donde llegamos a este diseño:

VBA: ListBox con varias columnas y encabezados.


Accedemos al Editor de VB (Alt+F11) y dentro del Editor buscamos nuestro formulario UserForm1, activamos dicho formulario con lo que nos aparecerá el Cuadro de herramientas o controles. En este buscaremos los siguientes controles:
  1. Marco (Frame): con este delimitaremos, y haremos independiente de otros controles, lo que incluyamos en él.
  2. Etiquetas (Labels): no editable, para nombrar los Cuadros de texto que situaremos a su lado.
  3. Cuadro de Texto (TextBox): donde vincularemos los valores seleccionados en el Cuadro de Lista (ListBox).
Bien, en ese orden, primero seleccionaremos el área del marco(Frame), para luego colocar tres etiquetas(Labels) y a su lado respectivamente tres Cuadro de Texto (TextBox), asociando cada uno de éstos a una columna del Cuadro de Lista (ListBox) que tenemos ya creado.
El diseño nos quedaría así:

Asociar a un TextBox el valor seleccionado de un ListBox.


Una vez ha quedado acorde a nuestro control de calidad visual, podemos añadirle la funcionalidad buscada.
En primer lugar, modifcaremos ciertas propiedades de los diferentes controles incluidos en nuestro formulario. En concreto cambiaremos los nombres que se muestran en las tres etiquetas por la cabecera o rótulos de la tabla origen de datos, también asignaremos un nombre definido por nosotros al Marco (O Frame):

Sub UserForm_Initialize()
Dim fila As Single

'le decimos cuántas columnas tendrá
ListBox1.ColumnCount = 3
'que sí que tiene encabezado
ListBox1.ColumnHeads = True
'el origen de datos en nuestra hoja de cálculo
ListBox1.RowSource = "Tabla1"
'renombramos el Marco
Frame1.Caption = "Datos seleccionados:"
'damos nombre a las etiquetas creadas, empleando la cabecera de la Tabla1
fila = ListBox1.ListIndex + 2
With Hoja1.Range(ListBox1.RowSource)
    Label1.Caption = .Cells(fila, 1).Offset(-1, 0).Value
    Label2.Caption = .Cells(fila, 2).Offset(-1, 0).Value
    Label3.Caption = .Cells(fila, 3).Offset(-1, 0).Value
End With
End Sub



Observemos el resultado:


Ya sólo nos queda asignar una funcionalidad a nuestro Cuadro de Lista (ListBox1), y es que pretendemos que cada vez que seleccionemos un elemento de esa Lista, aparezca reflejado en los cuadros de texto, por supuesto, cada valor donde corresponda.
Esto lo conseguiremos con un evento click sobre el ListBox:

Private Sub ListBox1_Click()
fila = ListBox1.ListIndex + 2

    With Hoja1.Range(ListBox1.RowSource)
        TextBox1.Text = .Offset(ListBox1.ListIndex, 0).Resize(1, 1).Value
        TextBox2.Text = .Offset(ListBox1.ListIndex, 1).Resize(1, 1).Value
        TextBox3.Text = .Offset(ListBox1.ListIndex, 2).Resize(1, 1).Value
    End With
End Sub


Y listo, ya esta nuestro formulario operativo, podremos comprobar cómo en cada ocasión que marquemos de entre los elementos del ListBox, los valores de éste se mostrarán en los Cuadros de Texto (TextBox) habilitados.

Asociar a un TextBox el valor seleccionado de un ListBox.


Por último remarcar que, al estar vinculado directamente a los valores de la Hoja de cálculo, cualquier cambio o modificación en alguno de los datos de la Tabla1 se veré reflejado sobre nuestro formulario, incluyendo, por supuesto los nombres de las tres Etiquetas (Labels).

18 comentarios:

  1. Hola, Quisiera saber como hacer al contrario
    Elegir en un textbox y ubicarlo en un listbox

    ResponderEliminar
    Respuestas
    1. Hola Oscar,
      el tema es que un TextBox es un cuadro de texto donde escribir algo, no parece que tenga mucho sentido 'elegir' un elemento de un textbox, ya que en estos no es posible desplegar nada.
      Si te refieres a escribir algo en el textbox y luego añadirlo como elemento de un ListBox, tendrías que emplear la propiedad additem del listbox sobre el textbox.value.
      Slds

      Eliminar
  2. Hola, tengo una duda relacionado con los listbox.
    Tengo un listbox con una serie de números, entre ellos números decimales. Quiero copiar uno de los item (por ejemplo el item(2) que es 27,56) a un label.
    Cuando lo copio mediante la orden Label.Caption = Val(List3.List(1)) me sale en el label el valor 27 y no los decimales. ¿cómo puedo hacer para que aparezcan decimales?

    Gracias!

    ResponderEliminar
    Respuestas
    1. Hola Pedro,
      prueba con .Formula en lugar de .Value
      Label.Caption = Val(List3.List(1).Formula)
      si fallara, prueba con
      Label.Caption = Replace(Val(List3.List(1).value), ",", ".")

      Slds cordiales

      Eliminar
  3. me marca erro en la parte
    With Hoja1.Range(ListBox1.RowSource)
    en la palabra Range

    ResponderEliminar
    Respuestas
    1. Hola Noemi,
      un placer saludarte igualmente.
      Asegúrate que tus controles en el UserForm se llaman de igual forma (ListBox1), y que tienes una 'Hoja1' (fíjate en el codename de la hoja.. no en el nombre visble)
      Saludos

      Eliminar
    2. ok, entonces el nombre que tiene la etiqueta de la hoja no es el que se utiliza??
      Saludos

      Eliminar
    3. Las hojas pueden ser llamadas de varias formas, en particular utilizando el nombre de la 'etiqueta' (propiedad Name) o su nombre de código (propiedad codename).
      http://excelforo.blogspot.com.es/2013/08/vba-la-propiedad-codename-de-las-hojas.html

      Quizá tu problema sea ese.. estás intercambiando nombres.

      Verifica también el nombre del control (del ListBox)
      Saludos

      Eliminar
  4. Hola, espero que estén bien. Tampoco me funciona la hoja está bien referenciada y el texbox bien nombrado, cuando coloco la flecha sobre el with muestra el nombre de la tabla fuente del listbox, pero saca error de "se requiere objeto" gracias

    ResponderEliminar
    Respuestas
    1. Hola Carlos,
      supongo te refieres al código de este mismo post...
      Asegúrate que el CodeName de tu hoja corresponde con el de tu código.. en mi ejemplo, es 'Hoja1'.. quizá en tu caso se distinto o simplemente no exista..
      Saludos

      Eliminar
  5. Buenos dias, he estado tratando de trabajar con listas muy grandes, la validacion no me sirve porque no es predictiva y toca elegir uno por uno los datos, y el combobox tampoco porque tengo muchas lineas diferentes y tendria que insertar un combobox por cada linea donde quiero insertar un nombre.

    Navegando me consegui este ejemplo que podria solucionar todo pero no se como hacerlo pues no se explica muy bien y no tengo mucho conocmiento en VBA, en el ejemplo usan un textbox y un listbox, el textbox esta asociado a una lista ya creada y cuando se va escribiendo algo en el textbox me muestra en el listbox todas las opciones que hay en la lista, nada mas se elige cual es la que necesito y se inserta en cualquier celda donde esta ubicado en ese momento, es muy facil porque con uno solo que inserte me sirve para cuantos datos diferentes quiera incluir, solo cambiando de celda al momento de hacer la eleccion, te dejo el link para descargar el ejemplo a ver si me puedes ayudar sobre como crearlo, saludos y gracias http://www.mediafire.com/download/jmg5ginjnqn/ListaDesplegableConAutoAjuste.xls

    ResponderEliminar
    Respuestas
    1. Hola,
      la técnica de esto es emplear la herramienta de Filtro avanzado sobre la columna A (Nombres) de la Hoja de 'DAtos'.. el ListBox muestra el resultado obtenido de ese filtro.. esto es, se apoya en un Filtro para mostrar los valores resultantes que coinciden con lo escrito en el TextBox.

      Está asociado a un evento DoubleClick y Change de ambos controles...

      Lo que no sé es cómo puede serte útil si tienes que completar listas muy grandes de datos.. tendrías que replicar esos controles tantas veces como registros tuvieras...
      ?
      Saludos

      Eliminar
    2. Si me sirve porque con uno solo puedo introducir los elementos en cuantas celdas diferentes quiera, ya lo pude aplicar a mi hoja, pero el problema que tengo ahor es que el listbox se reduce de tamaño cada vez que le doy a un valor o que borro lo que escribi en el textbox para hacer una nueva busqueda, es normal que reduzca tamaño? como se arregla? en el ejmplo que use no pasa eso.

      Saludos...

      Eliminar
  6. Estoy intentando vaciar una base de datos desde datos capturados con un useform con textbox y listbox lo que no encuentro es como pasar esa seleccion del listbox a la base de datos en la respectiva posicion de la columna que le corresponde...

    ResponderEliminar
    Respuestas
    1. Hola Edwin,
      podrías emplear el método .Find en VBA para localizar el dato sobre tu hoja de cálculo, y una vez localizada ir rellenando celda a celda los elementos del ListBox.
      Saludos

      Eliminar
    2. decidi cambiar un poco la forma de captura y como era solo para elegir uno de dos item agreue un boton de opcion.... Ahora tengo otro problemita, prepare este codigo y corre bien al menos esta parte que es para buscar en una tabla partiendo de un valor en untextboxt y me los muestra en el mismo userfome en otrostextbox pero uno de esos textbox que carga quiero que lo muestre cuando aparecen el dato buscado con formato porcentul 0,00% y no se como, este es el codigo:
      Private Sub buscar_Click()


      Sheets("PROVEEDORES").Select
      Range("A:A").Select

      If buscar1 = "" Then
      MsgBox "Capturar datos"
      buscar1.SetFocus
      Exit Sub
      End If
      encontrado = False
      If IsNumeric(buscar1) Then
      valt1 = Val(buscar1.Value)
      Else
      valt1 = buscar1
      End If
      For i = 1 To Range("A" & Rows.Count).End(xlUp).Row
      If Cells(i, "A") = valt1 Then
      TextBox1 = Cells(i, "A")
      TextBox2 = Cells(i, "B")
      TextBox3 = Cells(i, "C")
      encontrado = True
      Exit For
      End If
      Next
      If encontrado = False Then
      MsgBox "Proveedor no Encontrado"
      End If
      End Sub

      Eliminar
    3. Hola,
      puedes aplicar la función format donde quieres conseguir ese formato porcentual:
      format(range("A1"),"0.00%")

      Saludos

      Eliminar