jueves, 8 de diciembre de 2011

VBA: ListBox con varias columnas y encabezados.

Continuando con algún post anterior en el que veíamos como trabajar con un Formulario (UserForm), explicaré hoy como incluir un ListBox en un formulario con datos extraidos de nuestra hoja de cálculo, pero con varias columnas de datos y respetando la cabecera de rótulos:
Lo más cómodo e importante para emezar a trabajar será convertir nuestro rango de datos en una Tabla de Excel(Ctrl+q para Excel 2007 y Ctrl+t para Escel 2010). Veamos nuestro origen de datos nombrada como Tabla1:

VBA: ListBox con varias columnas y encabezados.


Con nuestra Tabla1 creada, ya podemos irnos al Editor de VBA (Alt+F11) e insertar un UserForm (Formulario), buscaremos en la ventana de controles la opción Cuadro de lista, y lo desplegaremos dentro del Formulario donde deseemos::

VBA: ListBox con varias columnas y encabezados.


Una vez incluido el ListBox en nuestro formulario, deberes configurarlo para que recoja los registros de nuestra Tabla1 de la Hoja de cálculo como elementos del recien creado ListBox1, además deberemos definirlo de tal forma que el encabezado de la Tabla1 aparezca como cabecera de nuestro ListBox1, por supuesto, cada campo deberá aparecer en una columna independiente.
Para ello deberemos trabajar con distintas propiedades de este ListBox, como son:
  • ColumnCount: en el que indicaremos cuantas columnas vamos a crear, para nuestro ejemplo, le asignaremos un valor de tres (una por cada campo 'Producto', 'Unidades' y 'Precio')
  • ColumnHead: donde seleccionaremos True o False dependiendo de si queremos mostrar encabezado o no.
    Ojo, por que en este caso, es importante para evitar posibles fallos, haber definido nuestro origen de datos, en la Hoja de cálculo, como Tabla Lista.
  • RowSource: donde le indicaremos dónde se encuentra el origen de datos, para nosotros será 'Tabla1'.
Estas propiedades del ListBox se pueden definir bien desde la Ventana de propiedades, o bien directamente con código.
Veamos cómo definimos estas propiedades con código VBA, para ello haremos doble click sobre nuestro UserForm y añadiremos el código:

Private Sub UserForm_Initialize()
'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"

End Sub



Con la intrucción Private Sub UserForm_Initialize() conseguimos que el ListBox se cargue cada vez que iniciamos el formulario.
El resultado del Formulario lo podemos ver al ejecutarlo:

VBA: ListBox con varias columnas y encabezados.



Veamos cómo definimos estas mismas propiedades desde la Ventana de propiedades activa para nuestro ListBox1:

VBA: ListBox con varias columnas y encabezados.


Por supuesto el resultado será el mismo que el expuesto en el método anterior:

VBA: ListBox con varias columnas y encabezados.


A partir de nuestro ListBox podremos trabajar bien sobre otros códigos o bien directamente sobre nuestra Hoja de cálculo... pero eso será en posteriores entradas.

94 comentarios:

  1. tengo en excel 2007 varias ventas y mme pidieron hacer un formulario que solo salga el resultado solo la repuesta que cuando diga con un boton ventas salga solo los resultados de la venta como especie d ereporte con un formulario me llamo fernando mi correo es elmorita@hotmail.com me gustaria que me ayuden soy nuevo en es ta area cree un menu que dice vents asi quiero solo el resultado de las ventas gracias

    ResponderEliminar
    Respuestas
    1. Hola!!
      ¿podrías ser algo más claro en tu exposición???
      Slds

      Eliminar
  2. Una consulta y cual seria el codigo para que visualize el ultimo dato, osea que muestre el encabezado y el ultimo producto?
    Gracias

    ResponderEliminar
    Respuestas
    1. Hola!!
      dificil cuestión, al menos para mí.. el problema con el que me encuentro, no es determinar un rango de lista sólo con un elemento, si no que además del encabezado, necesitas listar sólo el último elemento (o sea, una lista de un único elemento- quizá necesites otro control??).
      Desconozco la posibilidad de incorporar de un rango o matriz discontinua, la primera fila como Header de un ListBox...
      Para listar los últimos elementos de un Origen de tres columnas, que se encuentre, por ejemplo en la fila 8, necesitarías incorporar el siguiente código:
      ListBox1.AddItem Cells(8, 1).Value
      ListBox1.List(0, 1) = Cells(8, 2).Value
      ListBox1.List(0, 2) = Cells(8, 3).Value

      Lo siento, pero no puedo ayudarte, ya que el ListBox sólo reconoce el Header (encabezado) usando la propiedad RowSource, que a su vez exige un rango o tabla.
      Suerte, y si encuentras una solución, no olvides comentarla
      Slds

      Eliminar
  3. podrias poner en elcabezado fuera del listbox

    ResponderEliminar
    Respuestas
    1. Hola,
      podrías añadir tres etiquetas (label), dándoles la propiedad Text a cada uno con el valor del encabezado que corresponda.
      Label1.Text = Range("A1").Value
      Label2.Text = Range("B1").Value
      Label3.Text = Range("C1").Value
      slds

      Eliminar
  4. tengo un formualario con los sigueintes campos
    id
    nombre
    apellido
    sector
    venta

    lo que quiero es que al colocar el id del cliente me traiga el nombre, apellido y sector; en el campo venta es lo unico que agregaria que tipo de venta hizo y a estos datos lo quiero insertar a otra hoja
    Saludos

    ResponderEliminar
    Respuestas
    1. Hola,
      bien, habría que conocer dónde están los datos o la tabla, deberé entender que existe una Tabla con todos esos registros en una hoja de cálculo.
      Supondré tambíen que en un ListBox despliegas sólo el Id, y que es en alguna combinación de varios TextBox donde tendrías que relacionar, en función del Id seleccionado en el ListBox los diferentes campos.
      Para pasar toda esa información a una Hoja de cálculo, deberías aplicar algo del estilo:
      Range("A1").Value = TextBox1.value
      Range("B1").Value= TextBox2.value
      Range("C1").Value= TextBox3.value
      etc

      Saludos

      Eliminar
  5. Quisiera saber cuales son la combinacion de teclas para validar una formula y me muestre el resultado en vez de un cero.

    ResponderEliminar
    Respuestas
    1. Hola, buenos días,
      supongo te refieres a la validación matricial de una fórmula.
      Un fórmula o función matricial debe ser validada presionando, en lugar de Enter solo, Ctrl+Mayusc+Enter
      Un saludo

      Eliminar
  6. Muy interesante, Muchas gracias por compartirlo! sigue así.

    ResponderEliminar
  7. hola,tengo un formulario de excel donde ingreso varios registros y estos a su vez pasan a la hoja1, necesito que 4 de estos registros pasen a la hoja2 al mismo tiempo, como logro esto.
    gracias

    ResponderEliminar
    Respuestas
    1. Hola,
      entiendo que hablas de un UserForm, y que los datos los introduces en algunos TextBox. Puesto que indicas que ya los llevas a la hoja1, para pasarlos a la hoja2 sólo tendrías que añadir una segunda línea de código, igual que la de la hoja1, pero en la hoja2.
      Por ejemplo:
      Sheets("hoja1").Range("A1").value =textbox1.value
      Sheets("hoja2").Range("C1").value =textbox1.value
      igual para el resto de los 4 registros que hablas.
      Slds

      Eliminar
  8. muchas gracias por el aporte, me funciono pero para la primera fila de ambas hojas, como logro que despues de ingresar datos a la primera fila, este pase a la segunda, tercera etc y continuar llenando la base de datos, todo se esta haciendo desde un solo userform
    gracias

    ResponderEliminar
    Respuestas
    1. Hola, supongo seguimos hablando de copiar valores del textbox a las dos hojas...
      Si quieres se copie en la celda inmediata, logicamente ya no te vale una referencia fija, tendrías que añadir una variable, algo de este estilo:
      Sheets("hoja1").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).Value =textbox1.value
      Sheets("hoja2").Cells(Rows.Count, "C").End(xlUp).Offset(1, 0).Value =textbox1.value
      Slds

      Eliminar
  9. Amigo me funciono perfecto..muchas gracias
    Dos favores..
    **quiero que cuando de click en el texbox donde va la fecha me salga el calendario y cuando la seleccione (la fecha), esta pase al texbox y el calendario se oculte, logre que el calendario se mostrara pero cuando selecciono la fecha no ocurre nada
    **La hoja de excel la deje sin lineas de division, como puedo a traves de una variable o código colocarle bordes a las celdas pero que solo ocurra cuando los datos ingresen a la hoja.
    saludos

    ResponderEliminar
    Respuestas
    1. Hola,
      para ocultar el calendario prueba con la propiedad Hide. Y para colocar bordes a la celda, tendrás que usar la propiedad Borders, asociada a la celda donde se ingresen los valores.
      Slds

      Eliminar
  10. Buenos días,
    que pena que no me hice entender, lo que necesito es que al dar click sobre el texbox donde voy a colocar la fecha, me despliegue el calendario, selecciono la fecha y esta quede en el texbox para luego grabar en la base de datos, no he logrado que funcione, estuve leyendo que con el evento enter se puede hacer pero no me funciono o no puse el codigo correcto
    gracias por tu ayuda....
    Herney

    ResponderEliminar
    Respuestas
    1. Hola,
      envíame lo que tengas a
      excelforo@gmail.com
      Slds

      Eliminar
  11. Hola! Tengo una muy buena pregunta...

    Supongamos que mi listbox despliega tres columnas... como puedo obtener el ancho de cada una de las columnas que conforman mi listbox, obtener, no asignar? Alguna sugerencia?

    ResponderEliminar
    Respuestas
    1. Hola Luis,
      pues es cierto que es una buena (y dificil) pregunta.
      Que yo sepa no hay forma.
      La propiedad que define el ancho de las columnas de un listbox viene dado por ColumnWidths, y ésta sólo sirve para asignar el ancho a cada columna, bien en puntos, cm o pulgadas.
      Lo bueno de todo esto es que por defecto, y salvo que previamente hayas definido de alguna manera el ancho de las columnas, Excel da un ancho estándar de 1.33 pulgadas.

      Eso significa, que si tu no has otrogado un ancho distinto tus columnas tienen ese ancho; y sólo si mediante algún control o fórmula has asignado un ancho diferente, podrás conocerlo, no mediante ColumnWidths pero sí mediante el valor del control o de la fórmula.

      Es lo que te puedo decir.
      Slds!!

      Eliminar
  12. Que tal,
    hay una forma para definir los encabezados de columnas de un list box pero mediante codigo sin tomar datos de una tabla?

    ResponderEliminar
    Respuestas
    1. Hola!!
      hasta donde yo sé, sólo se pueden mostrar Encabezados de columna si la RowSource toma un rango de hoja de cálculo. Si es ColumnHeads lo damos como True Excel utiliza la primera fila del rango como encabezados. No se pueden especificar Encabezados de columna cuando el origen de la lista es una matriz VBA.
      Por ejemplo, así no sería posible asignar Encabezado:
      Private Sub ListBox1_Click()
      ListBox1.ColumnHeads = True
      ListBox1.ColumnCount = 2
      ReDim matriz(0 To 3, 1 To 2)
      matriz(0, 1) = "campo"
      matriz(0, 2) = "importe"
      matriz(1, 1) = "1"
      matriz(1, 2) = "uno"
      matriz(2, 1) = "2"
      matriz(2, 2) = "dos"
      matriz(3, 1) = "3"
      matriz(3, 2) = "tres"

      ListBox1.List = matriz
      End Sub

      Lo siento.
      Slds

      Eliminar
  13. Ok, de todas formas gracias por la aclaración.

    Otra pregunta, si quisiera agregar mas datos a una tabla de un listbox, si uso la opción de RowSource se que no puedo usar la opción de .AddItem, entonces tengo que agregar mis datos a la tabla pero en excel para que después vuelva a importar esa misma tabla de nuevo con RowSource. Es cierto mi comentario? eso lo deduje despues de checar mucho en internet.

    Como tengo que modificar la tabla de excel,cómo agrgaría nuevas filas a la tabla que ya tengo hecha con código en VBA?

    Mi tabla consiste en 6 columnas con sus respectivos encabezados, solo quiero ir agregando filas a esa tabla para poder introducir nuevos datos y que pueda importar la tabla completa de nuevo al listbox con RowSource.

    Gracias por tu tiempo. Saludos

    ResponderEliminar
  14. Todo lo anterior que comenté lo estoy realizando con código en excel VBA.

    ResponderEliminar
    Respuestas
    1. Hola!
      si vas a emplear .RowSource empleando una Tabla en la hoja de cálculo como referencia, no tienes por que preocuparte por los neuvos registros, ya que la Tabla tiene la propiedad de añadir los nuevos datos como parte del Nombre (de la Tabla), por tanto automáticamente se incorporan en tu ListBox...
      Lo único asegúrate que sea una Tabla, selecciona el rango en la hoja de cálculo, y conviertelo en Tabla (presionando Ctrl+T, por ejemplo)!!!
      No hace falta nada de código especial para esto.
      Slds

      Eliminar
  15. Hola de nuevo Ismael,
    mi pregunta es: Se puede modificar una tabla de excel mediante codigo en VBA y guardarlo en el mismo archivo? Para ver los datos ya modificados, mejor dicho la tabla ya refrescada, se tiene que cerrar el archivo y despues volver a abrir (No deseo eso ya que mis Forms estan en el mismo archivo? Estoy usando Forms para procesar datos para después agregarlos a una hoja que esta en el mismo archivo donde estan las Forms. De esta manera ya podría refrescar los datos en mi tabla del listbox con la opcion de RowSource.
    Saludos, Carlos

    ResponderEliminar
  16. Me podrías proporcionar un codigo de ejemplo porfavor. Gracias

    ResponderEliminar
    Respuestas
    1. Hola Carlos,
      no hay ningún código concreto para añadir o modificar registros a una Tabla de Excel, basta con añadirlos en las filas contiguas a la Tabla ya existente (ni siquiere requiere Actualizar el fichero), por tanto, para agregar nuevos registros sería suficiente aplicar un
      Range(...).value=NuevoRegistro
      a continuación, en la fila siguiente, de la Tabla...
      No entiendo por qué motivo tendrías que cerrar y volver a abrir tu Libro para actualizar los nuevos datos...

      Para cargar datos en un Listbox, se suele limpiar primero y luedo indicarle los valores de carga:
      ListBox1.Clear
      ListBox1.Rowsource="Tabla1"
      etc, etc...

      Slds

      Eliminar
  17. Hola buenas tardes:
    De favor quiero ver si me pueden ayudar ya que estoy haciendo un list box (que esta dentro de un userform)en el cual, desde una base de datos de escel, quiero que aparezca la información. Por ejemplo: si en mi base de datos en la columna A tengo la fecha, quiero que en el listbox se muestren solo los de cierta fecha que yo requiera (algo asi como filtrar).
    Bueno, espero haberme explicado gracias

    ResponderEliminar
    Respuestas
    1. Hola,
      bueno, he de suponer que si quieres obtener ciertos registros desde la hoja de cálculo, tendrás algún control en el UserForm (un ComboBox, por ejemplo) donde obtener la condición de 'filtro' y desde donde obtener en el ListBox los elementos que lo componen.
      Si es esa la idea, creo que tepuede orientar lo explicado en este post
      excelforo.blogspot.com.es/2012/07/vba-elementos-seleccionados-de-un.html
      la idea a aplicar es la misma, conseguir ciertos registros a partir de una selección, lo que puedes conseguir con un Array.

      Espero te haya orientado.
      Slds

      Eliminar
  18. Hola. Tengo un problema y no entiendo porque ocurre. Seguro tiene una explicación fácil pero estoy atascado

    Tengo un Combobox y quiero tener 3 columnas. Y que la tercera sea la que aparezca en el control como valor.

    Lo añado así

    ComboBox1.AddItem "Column 1"
    Combobox.List(0, 1) = "Column 2"
    Combobox.List(0, 2) = "Column 3"
    ComboBox1.Columncount=3
    ComboBox1.boundcolumn=3

    Y siempre me aparece el valor de la columna 2.
    Si pongo el bound en 2 lo mismo
    En 4 igual
    Es que no hay manera y no lo entiendo.

    gracias

    ResponderEliminar
    Respuestas
    1. Hola Antonio!
      echa un vistazo a esta entrada, creo que te resultará útil para lo que quieres hacer:
      http://excelforo.blogspot.com.es/2013/02/el-ancho-de-las-columnas-en-un-listbox.html

      Slds

      Eliminar
    2. Ok Ya encontré la solución. La propiedad textcolumn es la que aparece en el control. Lo puse a 3 y listo. La boundcolumn es el valor real del control.

      Eliminar
  19. Amigo
    Si tengo cargado un ListBox de varias columnas con datos desde una hoja de Excel y selecciono uno en dicho Listox, ¿Cómo puedo buscar la fila correspondiente en la hoja Excel para modificar un dato(en una determinada columna)?

    ResponderEliminar
    Respuestas
    1. Hola!
      tendrás qeu controlar qué elemento del Listbox has seleccionado, de tal forma que una vez controlado habrá que realizar una búsqueda sobre el rango de Excel con un método .Find o sencillamente un FOR...NEXT que recorra el rango en la hoja de cálculo, hasta que lo encuentre, en cuyo caso lo deje seleccionado.
      Puedes ver una forma de identificar elementos seleccionados de un Listbox en
      http://excelforo.blogspot.com.es/2012/07/vba-elementos-seleccionados-de-un.html
      Espero te oriente
      Slds

      Eliminar
    2. Necesio de su amable asesoria ya tengo el listbox pero pero ahora quiero tener la opcion de imprimir el contenido de ese listbox con algunos datos en el encabezado como la fecha el nombre de la persona entre otros mediante la accion clic de un boton

      Graciassss..

      Eliminar
  20. Como puedo imprimir el contenido del listbox y agregar algunos datos en el encabezado?

    ResponderEliminar
    Respuestas
    1. Hola,
      diría que lo más sencillo para imprimir el contenido de un ListBox sería pasar su contenido a una hoja de cálculo, asociándolo a un botón del UserForm:
      Private Sub CommandButton1_Click()
      'Pasamos los valores de un Listbox a una hoja nueva
      Worksheets.Add
      'recorremos los elementos del ListBox y los pasamos a la hoja nueva
      For i = 0 To ListBox1.ListCount - 1
      Range("A" & Range("A" & Rows.Count).End(xlUp).Row + 1) = ListBox1.List(i, 0)
      Next i

      'Y ahora imprimimos lo volcado
      ActiveWindow.SelectedSheets.PrintOut Copies:=1, Collate:=True
      End Sub

      Espero te pueda servir.
      Slds cordiales

      Eliminar
    2. Hola a todos,

      Tengo una duda con el excel para mac ya que en las propiedades de la listbox no me aparece el RowSourse, la pregunta seria ya que como no puedo utilizar esta propiedad con que código de vba lo remplazaría para que muestre una tabla en la listbox

      Eliminar
    3. Hola Edward,
      sobre la programación VBA en Mac poco o nada puedo decirte, ya que son bastantes las peculiaridades que lo diferencian de la versión para Windows (PC).
      Si no existe la propiedad .RowSource quizá exista .ControlSource o incluso .List y de alguna manera puedas acomodarlo.
      Siento no poder ayudarte... quizá algún lector del blog.
      Suerte y un cordial saludo

      Eliminar
  21. Como defino "tabla 1" para el RowSource

    ResponderEliminar
    Respuestas
    1. Hola, que tal?
      espero te encuentres bien.
      Para crear una Tabla en Excel debes ir a la Ficha Insertar > grupo Tablas > botón Tabla
      Un saludo

      Eliminar
  22. hola, yo quiero que los datos que cargue al listbox que me guarde en una hoja del excel, ayuda por favor

    ResponderEliminar
    Respuestas
    1. Hola,
      echa un vistzao a esta entrada, en ella obtendrás una pista de cómo conseguir llevar el dato seleccionado en el ListBox a una celda de una hoja de cálculo.
      http://excelforo.blogspot.com.es/2012/07/vba-elementos-seleccionados-de-un.html

      Slds

      Eliminar
  23. Es necesario para un listbox tener los datos en la hoja.

    Mi caso es que por una función rfc conecto con un sistema externo a excel y traigo una serie de datos en vba, entonces quiero mostrar un listbox sobre una tabla que he recuperado del otro sistema, sin tener que mostrar esos datos en otra columna. ¿Es posible?

    Muchas gracias

    ResponderEliminar
    Respuestas
    1. Hola, que tal?
      para 'cargar' con datos un ListBox puedes emplear (además de traer datos desde la hoja de cálculo) la propiedad .AddItem:
      ListBox1.AddItem 'variable(i), texto, etc'

      o bien, algo más retorcido, con .List:
      ListBox1.List(1,1) = 'variable(i), texto, etc'

      Espero te sirva
      Slds

      Eliminar
  24. Buenos días

    Como puedo cambiar el formato a hora en el listbox usando esta instricción

    List5.List() = Sheets("PRUEBA").Range("J5:K" & Range("A" & Rows.Count).End(xlUp).Row).Value

    La instrucción me despliega las celdas con valor en el listbox, pero en formato general (0,317777) y yo lo necesito en hora:minuto ("hh:mm")

    Gracias de antemano.

    ResponderEliminar
    Respuestas
    1. Hola Adan,
      puedes emplear una instrucción similar a la de la hoja de cálculo:
      Format(elemento, "hh:mm")

      Saludos

      Eliminar
  25. Buenos Dias sr. Ismael! Tengo una pregunta, necesito que en un textbox se me muestre el contenido de una celda de excel, pero esto segun el resultado o referencia que me da el listbox, por ejemplo: Listbox= C47, en el textbox me muestre el contenido de la celda F47. Espero me haya explicado bien. De ante mano, muchasd gracias

    ResponderEliminar
    Respuestas
    1. Hola,
      supongo de alguna manera tendrás identificada la celda seleccionada con el ListBox (quizá con algún campo auxiliar que marque la fila)...
      Aprovechándote de ese campo podrías rellenar el TextBox.

      Podría ser una manera.. todo dependerá de cómo hayas generado el ListBox.

      Espero haberte dado una idea.
      Saludos

      Eliminar
    2. Este comentario ha sido eliminado por el autor.

      Eliminar
  26. Mmm... La verdad, no entiendo mucho, a ver, le explico... Mi programa consta de 3commandbuttons: Buscar, Limpiar y Salir, 2 textbox: en uno introduzco el nombre del empleado que quiero buscar y en el otro quiero que me lo que le comente anteriormente, el listbox me muestra la ubicacion (la celda) en la que se encuentra el nombre del empleado a buscar. Lo que quiero es que segun la celda en la que se encuentre el nombre (es decir, lo que me muestra el listbox) en el 2do textbox me muestre el contenido de una celda especifica.

    Por ejemplo, si el nombre del empleado esta en el rango de celdas de A4:F200, entonces mostrar la celda F4, sino, si el nombre del empleado esta en el rango de celdas de A210:F500 entonces mostrar la celda F210. Se que tiene que hacerse con un condicional, pero me da error. Que y como tengo que hacer? Espero que me entienda y pueda ayudarme. Muchas Gracias, Saludos!

    ResponderEliminar
    Respuestas
    1. si el listbox muestra tal cual la ubicación en forma de referencia, podrías hacer, asociando al evento click del ListBox:
      Private Sub ListBox1_Click()
      TextBox2.Value = Range(ListBox1.Value).Value
      End Sub
      Repito suponiendo el listbox muestra directamente las referencias a celdas:
      F1
      F2
      F3
      ...
      (por ejemplo)
      Saludos

      Eliminar
  27. buenos dias yo tengo un problema que puse el formulario con el listbox en hoja dos pero los datos estan en hoja1 y solo si me posiciono sobre la hoja1 da resultados tengo entendido que se tiene que posicionar sobre la hoja activa pero de ser asi me pueden modificar si quisieran los que se va guardando me podrian adr una mano con el codigo?



    es el siguiente


    'Activar la celda del registro elegido
    Private Sub ListBox1_Click()
    Range("a2").Activate
    Cuenta = Me.ListBox1.ListCount
    For i = 0 To Cuenta - 1
    If Me.ListBox1.Selected(i) Then
    'MsgBox Me.ListBox1.List(i)
    Valor = Me.ListBox1.List(i)
    Sheets("Hoja1").Range("A2:A5000").Find(What:=Valor, LookAt:=xlWhole, After:=ActiveCell).Activate
    End If
    Next i


    'Fila = Me.ListBox1.ListIndex + 2
    'For i = 1 To 4
    ' Cells(Fila, 1).Activate
    'Next i
    End Sub

    ResponderEliminar
    Respuestas
    1. Hola Hernan,
      si ejecutas la macro (el evento click) desde otra hoja y quieres actuar sobre una hoja diferente, debes añadir qué hoja es sobre la que quieres actuar.
      Por ejemplo:
      sheets("Hoja1").Range("a2").Activate

      espero te oriente
      Saludos

      Eliminar
  28. Buenos días. Si tengo un listbox en userform cargado de una tabla de Excel con varias columnas, como capturo el dato de una celda en específica de la fila seleccionada?
    Gracias

    ResponderEliminar
    Respuestas
    1. Hola Carlos,
      identifica el registro seleccionado en el ListBox y retorna el valor de la columna directamente desde la Tabla de Excel.

      Una idea, con msgBox, sería:
      Private Sub ListBox1_Click()
      Dim I As Long, msg As String
      If ListBox1.ListIndex <> -1 Then
      For I = 0 To ListBox1.ColumnCount - 1
      msg = msg & ListBox1.Column(I) & vbCrLf
      Next I
      End If
      MsgBox msg
      End Sub


      en tu caso si solo quieres el valor de una columna identifica cuál es...
      Espero te oriente
      Saludos

      Eliminar
    2. Hola
      Buen dia,
      Tengo una base de datos muy grande para gestionar un archivo, la búsqueda la realizo a través de un textbox, pero lo que quiero a continuación es que esa búsqueda se vea reflejada no solo en mi hoja de excel, sino que ademas en un listbox que contiene 3 columnas, la idea es que cuando yo busque una empresa, me traiga todas las fechas, cantidad de folios y numero de carpeta de cada cliente (empresa). Use rangos dinámicos iniciando desde el nombre hasta el ultimo documento de cada empresa y así sucesivamente, pero la verdad es que no tengo ni idea de como aplicarlo.

      Agradezco Infinitamente pueda ayudarme....

      Eliminar
    3. Hola Angy,
      la idea podría ser aplicar un recorrido (un loop por ejemplo FOR...NEXT) que recorra la base de datos por el campo Empresa, y con un condicional IF...THEN, cargues el ListBox con un AddItem (por ejem) para aquellos registros que cumplan la condición...
      Saludos

      Eliminar
    4. De ante mano muchas Gracias Ismael....

      Peroaun tengo una duda y es que tendría que fijar celdas dentro de las formulas y no puedo fijar celdas, ya que inserto datos constantemente, no tengo ninguna columna o fila para el definir el nombre de la entidad, si no que en mi columna A tengo nombres y relaciones de documentos...es decir que, Donde finaliza el ultimo documento insertado en la fila siguiente inicia otra entidad.
      Por ello pensaba en los rangos dinámicos, lo que no se, es si es posible aplicarlos dentro de un listbox y cada vez que yo nombre la empresa me arroje los datos que se encuentran dentro de este rango.....no se si es operable como manejo mi base de datos....o si esta mal diseñada...
      Te pido por favor que me ayudes es un trabajo y la verdad no se como manejarlo.

      Eliminar
    5. Hola Angy,
      a priori me atrevería a decir que el diseño de la base de datos no es lo más óptimo...
      Lo ideal suele tener formato de de Tabla (cada fila un registro, guardando la integridad de datos...).
      Si he comprendido bien, en tu caso, siempre y cuando se guarde una estructura constante, esto es debajo de cada nombre de empresa en las mismas posiciones relativas esté dispuesta la misma información, podría servirte lo indicado en el anterior comentario... ya que puedes realizar el mismo loop y cuando encuentres el Nombre de la empresa, retornar al ListBox las celdas, relativas desde ese nombre, según su posición (1 fila abajo + 1 columna a la derecha; o 2 filas abajo + misma columna, etc).

      Saludos

      Eliminar
  29. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  30. soy nuevo con eso del vba, tengo un textbox que realiza búsquedas y los resultados los ingresa al listbox pero necesito filtrar una palabra en especifico pero que me muestre su respectiva fila, no importa que abajo me muestren otras coincidencias pero que pueda localizarla de primero y que también muestre su encabezado, tengo el siguiente código:



    Private Sub Textbox26_Change()
    Application.ScreenUpdating = False
    ListBox1.Clear
    ListBox1.ColumnCount = 3
    ListBox1.ColumnHeads = True

    With Worksheets("PRECIOS").Range("A1:C200")
    Set c = .Find(TextBox26.Text, LookIn:=xlValues)
    If Not c Is Nothing Then
    firstAddress = c.Address

    Do

    ListBox1.AddItem c.Value

    Set c = .FindNext(c)

    Loop While Not c Is Nothing And c.Address <> firstAddress

    End If

    End With
    End Sub

    ResponderEliminar
    Respuestas
    1. Hola Melvin,
      La idea sería cargar una nueva columna o dato en el Listbox que incorpore el número de fila del dato cargado (el buscado).
      Puedes emplear la propiedad column del listbox, echa un vistazo en
      http://excelforo.blogspot.com.es/2015/06/vba-recuperar-un-dato-de-un-elemento.html
      Espero te oriente
      Saludos

      Eliminar
  31. Estimado Ismael, saludos. Tengo un listbox, me muesta el contenido de la hoja1 que tiene 4 columnas A1 num; B1 Nombre; C1 numero Doc y D1 Respuesta. Necesito que al seleccionar una fila o registro del listbox, y luego que hago click en un boton (abrir formulario: este contiene un textbox1) me muestre el contenido de la Celda respectiva que esta en la 4 columna en el textbox1
    Cual seria el código para conseguir que funcione esto? Le expreso mis agradecimientos

    ResponderEliminar
  32. Estimado Ismael estoy trabajando Access con Excel, de la cual tengo una duda.
    Estoy trabajando con 02 tablas cliente (codigo, nombre ) y producto (cod_prod,nombre, precio) y en el formulario de excel tengo un LISTBOX1 que filtro nombres de la tabla cliente y en el LISTBOX2 necesito que se muestre los productos que compró el cliente al hacer clic en el ITEM del LISTBOX1 me puede facilitar un ejemplo?

    ResponderEliminar
    Respuestas
    1. Hola Adriel,
      no recuerdo tener ningún ejemplo que se ajuste a tu propuesta, pero la idea sería tomar el valor recuperado del ListBox1 a través del clic, para recorrer con un loop la tabla de productos y completar el ListBox2 aquellos que coincidan con el valor del LB1 cliqueado, con un IF THEN..por ejemplo.

      Espero haberte dado una idea.
      Saludos

      Eliminar
    2. Este comentario ha sido eliminado por el autor.

      Eliminar
    3. Amigo lo puese es lo siguiente

      If ListaProductos.ListIndex <> -1 Then

      CADENA.PRODUCTOS("SELECT COD_PROD, NOMBRE, PRECIO FROM PRODUCTOS
      .rst.Requery

      Do While Not .rst.EOF()
      Me.ListaProducto.AddItem .rst("cod_prod")
      Me.Listahijos.Lis t(Me.Listahijos.ListCount - 1, 1) = .rst("NOMBRE")
      Me.Listahijos.List(Me.Listahijos.ListCount - 1, 2) = .rst("PRECIO")

      .rst.MoveNext
      Loop
      End If
      Con este codigo consigo mostrar productos al clicar en le item de listbox de clientes, pero la cuestion es no mostrar todos los productos sino cliente x producto alguna ayuda?

      Eliminar
    4. Hola,
      faltaría el check con un IF THEN para cargar el ListBox en caso que el producto fuera uno concreto, debajo del Do While...
      IF .rst("cod_prod")="xxx" THEN

      Saludos

      Eliminar
  33. amigo ,una consulta. al momento de listar en el formulario vba de la hoja 1 me aparecen los datos en la lista de esa hoja que esta bien hasta ahy todo ok. mi pregunta es como hago por ejemplo , si en mi hoja 2 llamado (Productos), y en mi hoja1 llamado detalle, quiero que tenga el boton que llame a la lista productos, es decir que en la hoja 1 me al hacer clic en el boton , me aparesca el listado de la hoja 2 que es productos

    ResponderEliminar
    Respuestas
    1. Hola Pier,
      par areferirte y trabajar 'entre hojas', dentro de tu código al mencionar los rangos origen, añádale la hoja, por ejemplo:
      sheets("Productos").range("A1:A10")

      Saludos

      Eliminar
  34. Hola Ismael, una pregunta y una gran ayuda, estoy trabajando en Excel con vb haciendo un registro de datos, añadiendo comentarios en textbox y combobox y de esos transfiriendo a listbox y a una tabla, con botones commantbutton.
    El ejemplo mas o menos es así:
    Fecha:
    Operador:
    Ciudad:
    Identificación:
    etc, mi pregunta es:
    Una vez que pongo los nueve códigos de la siguiente manera

    Me.ListBox1.ColumnCount = 10
    Me.ListBox1.ColumnWidths = "50 pt; 73 pt; 33 pt; 53 pt; 65 pt; 160 pt; 25 pt; 40 pt; 65 pt; 80 pt"

    Me.ListBox1.AddItem Me.TextBox1.Text 'fecha 1
    Me.ListBox1.List(i, 1) = Me.ComboBox1.Text
    Me.ListBox1.List(i, 2) = Me.ComboBox2.Text
    Me.ListBox1.List(i, 3) = Me.TextBox2.Text
    Me.ListBox1.List(i, 4) = Me.TextBox3.Text
    Me.ListBox1.List(i, 5) = Me.TextBox4.Text
    Me.ListBox1.List(i, 6) = Me.TextBox5.Text
    Me.ListBox1.List(i, 7) = Me.TextBox6.Text
    Me.ListBox1.List(i, 8) = Me.TextBox7.Text
    Me.ListBox1.List(i, 9) = Me.ComboBox3.Text

    Hasta el paso número nueve funciona correctamente y añado el paso código para el dato de ingreso diez

    Me.ListBox1.List(i, 10) = Me.ComboBox4.Text

    Me resalta un error.

    Por favor necesito tu ayuda y mil gracias.

    ResponderEliminar
    Respuestas
    1. Hola,
      parece ya tienes incorporados los 10 elementos a las 10 columnas.
      Por otra parte, el conteo de los item empieza en 0 (de 0 a 9)

      Si necesitas incluir otro valor tendrás que incrementar el número de columnas del ListBox.

      Saludos

      Eliminar
  35. Como puedo añadir ese código para el dato número diez en adelante ya que me resalta ese error indicándome que no es valido.

    ResponderEliminar
  36. También esta con un Dim i As Long al comienzo del ingreso de los códigos para dicho programa.

    ResponderEliminar
  37. Hola Ismael, tengo tambien ese problema en el formilario tengo 17 textbox, al tratar de ingresarlos, da solo hasta 10, aumente a el número de columnas, a 17 pero marca error. Asi como dice Rolando Gomez Chaveze. Lo dividi en 3 listbox, pero ahora la problematica que tengo es al momento de borrar, por si hay algun error de captura, no me queda el codigo para eliminar, los 3 listbox si selecciono, podrias apoyarnos.

    ResponderEliminar
    Respuestas
    1. Hola,
      la clave es indicar cuál es el número de columnas
      Me.ListBox1.ColumnCount = 17
      y luego empezar a identificar el valor desde 0 a 16

      Me.ListBox1.List(i, 0) =...
      Me.ListBox1.List(i, 16) =...

      Con eso debería funcionar

      Espero os sirva.
      Saludos

      Eliminar
  38. Hola Ismael, mi problema es como llenar un ListBox con los datos de una tabla de access directamente, sin utilizar una tabla. lo hago de esta manera pero solo me carga la primera columna, los otros campos no.

    Rs.Open "SELECT * FROM Cliente", miConexion, adOpenKeyset, adLockOptimistic, adCmdText

    Do While Not Rs.EOF
    Me.ListBox1.AddItem
    Me.ListBox1.List(i, 0) = Rs.Fields(0).Value
    Me.ListBox1.List(i, 1) = Rs.Fields(1).Value
    Me.ListBox1.List(i, 2) = Rs.Fields(2).Value
    i = i + 1
    Rs.MoveNext
    Loop

    Rs.Close
    Set Rs = Nothing

    ResponderEliminar
    Respuestas
    1. Hola José,
      ¿has indicado el número de columnas de tu ListBox.. fíjate en el comentario anterior o en el código del ejemplo en el post.

      Me.ListBox1.ColumnCount = 3

      Saludos

      Eliminar
  39. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  40. Hola Ismael. Necesito ayuda con una macro. El problema es el siguiente, necesito mostrar en un listbox los datos filtrados de una tabla la cual contiene 30 columnas. El filtrado de datos funciona bien, el problema es cuando trato de mostrar el resultado del filtro en el listbox ya que solo me muestra 10 columnas y necesito que se vean las 30.

    Aquí te muestro el código:
    Private Sub CargarListbox1()
    Dim cell As Range
    Dim Rng As Range
    ListBox1.ColumnCount = 30
    With ThisWorkbook.Sheets("BD Compras")
    Set Rng = .Range("A8", .Range("A9").End(xlDown)).SpecialCells(xlCellTypeVisible)
    End With

    ListBox1.Clear
    For Each cell In Rng.Cells
    With Me.ListBox1
    .AddItem cell.Value
    .List(.ListCount - 1, 1) = cell.Offset(0, 1).Value
    .List(.ListCount - 1, 2) = cell.Offset(0, 2).Value
    .List(.ListCount - 1, 3) = cell.Offset(0, 3).Value
    .List(.ListCount - 1, 4) = cell.Offset(0, 4).Value
    .List(.ListCount - 1, 5) = cell.Offset(0, 5).Value
    .List(.ListCount - 1, 6) = cell.Offset(0, 6).Value
    .List(.ListCount - 1, 7) = cell.Offset(0, 7).Value
    .List(.ListCount - 1, 8) = cell.Offset(0, 8).Value
    .List(.ListCount - 1, 9) = cell.Offset(0, 9).Value

    De aqui para abajo me arroja el error... "No se puedeconfigurar la propiedad list. Valor de propiedad no valido.

    '.List(.ListCount - 1, 10) = cell.Offset(0, 10).Value
    '.List(.ListCount - 1, 11) = cell.Offset(0, 11).Value
    '.List(.ListCount - 1, 12) = cell.Offset(0, 12).Value
    '.List(.ListCount - 1, 13) = cell.Offset(0, 13).Value
    '.List(.ListCount - 1, 14) = cell.Offset(0, 14).Value
    '.List(.ListCount - 1, 15) = cell.Offset(0, 15).Value
    '.List(.ListCount - 1, 16) = cell.Offset(0, 16).Value
    '.List(.ListCount - 1, 16) = cell.Offset(0, 17).Value
    '.List(.ListCount - 1, 18) = cell.Offset(0, 18).Value
    '.List(.ListCount - 1, 19) = cell.Offset(0, 19).Value
    '.List(.ListCount - 1, 20) = cell.Offset(0, 20).Value
    '.List(.ListCount - 1, 21) = cell.Offset(0, 21).Value
    '.List(.ListCount - 1, 22) = cell.Offset(0, 22).Value
    '.List(.ListCount - 1, 23) = cell.Offset(0, 23).Value
    '.List(.ListCount - 1, 24) = cell.Offset(0, 24).Value
    '.List(.ListCount - 1, 25) = cell.Offset(0, 25).Value
    '.List(.ListCount - 1, 26) = cell.Offset(0, 26).Value
    '.List(.ListCount - 1, 27) = cell.Offset(0, 27).Value
    '.List(.ListCount - 1, 28) = cell.Offset(0, 28).Value
    '.List(.ListCount - 1, 29) = cell.Offset(0, 29).Value
    '.List(.ListCount - 1, 30) = cell.Offset(0, 30).Value
    End With
    Next cell
    End Sub

    ResponderEliminar
    Respuestas
    1. Hola,
      el problema es que existe un límite de 10 columnas para los ListBox sin límite superior, en especial cuando usamos AddItem para cargarlos de datos.
      Se podría intentar con .RowSource
      o bien, lo recomendado, emplear matrices/arrays para realizar la carga.
      Subiré un ejemplo en el blog con una explicación

      Saludos

      Eliminar
  41. Hola Estimado, agradezco tu ayuda con lo sgte, estoy creando un formulario donde incorporo datos a una planilla, tengo textos y tambien numeros y otros deben ser calculos hechos con los mismos datos ingresados...
    se trata del registros de facturas, por lo que se debe calcular el IVA a partir de una base y un total con la suma de los anteriores campos...
    y tengo problemas para hacer las operaciones y que se muestren de inmediato en la medida que ingreso los montos...al parecer mi problema es el tipo de campo que le asigno al textbox....

    mi codigo es el sgte:

    Private Sub btn_Guardar_Click()

    Dim fila As Integer

    For fila = 8 To 1000
    If Hoja1.Cells(fila, 1) = "" Then
    Hoja1.Cells(fila, 1) = ComboBox1.Text
    Hoja1.Cells(fila, 2) = TextBox2.Text
    Hoja1.Cells(fila, 3) = TextBox3.Text
    Hoja1.Cells(fila, 4) = TextBox4.Text
    Hoja1.Cells(fila, 5) = TextBox5.Text
    Hoja1.Cells(fila, 6) = TextBox6.Text
    Hoja1.Cells(fila, 7) = TextBox7.Text
    Hoja1.Cells(fila, 8) = TextBox8.Text
    Hoja1.Cells(fila, 9) = TextBox9.Text
    Hoja1.Cells(fila, 10) = TextBox10.Text
    Hoja1.Cells(fila, 11) = TextBox11.Text
    Hoja1.Cells(fila, 12) = ComboBox2.Text

    MsgBox "Documento ha sido ingresado"

    TextBox2.Text = ""
    TextBox3.Text = ""
    TextBox4.Text = ""
    TextBox5.Text = ""
    TextBox6.Text = ""
    TextBox7.Text = ""
    TextBox8.Text = ""
    TextBox9.Text = ""
    TextBox10.Text = ""
    TextBox11.Text = ""

    Exit Sub
    End If
    Next
    End Sub

    Private Sub ComboBox2_Change()

    End Sub

    Private Sub TextBox8_Change()
    TextBox9.Text = TextBox8.Text * 0.19
    TextBox11.Text = TextBox8.Text + TextBox9.Text + TextBox10.Text

    End Sub

    favor indicame que hago mal ya que el total que resulta en el ultimo campo aparece como si hubiera concatenado en vez de sumado, ademas se cae la rutina diciendo que tengo problemas en la sgte linea de codigo:

    TextBox9.Text = TextBox8.Text * 0.19

    agradezco de antemano tu ayuda.
    saludos
    Aldo.

    ResponderEliminar
    Respuestas
    1. Hola,
      prueba empleando la propiedad .Value del textbox (en lugar de .text).. y si aún falla, emplea la función VAL, por ejemplo:
      Hoja1.Cells(fila, 2) = VAL(TextBox2.value)

      Slds

      Eliminar
  42. Hola! soy un novato en esto y quería preguntarte como hago que el listBox me muestre solo la columna 3 y 5. Muchas gracias!

    ResponderEliminar
    Respuestas
    1. Hola!,
      habría que confirmarlo, pero entiendo empleando la propiedad Column del ListBox:
      ListBox1.Column(0) = range("C1").Value
      ListBox1.Column(1) = range("E1").Value

      obviamente con un recorrido por las filas con datos...

      Otra opción, quizá más simple, sea cargar la tabla completa, y luego NO mostrar las columnas no deseadas, gestionando la propiedad ColumnWidth: 0;0;100;0;100;0;0
      en el miniejemplo anterior cargamos una tabla de seis campos, pero forzamos un ancho de columna Cero para aquellos que no interesan...

      Slds

      Eliminar
  43. Tengo una tabla de datos y quiero mostrar los campos Columna A1:A10 y desde F1:J10 en el mismo RowSource

    ResponderEliminar
    Respuestas
    1. Hola Jhonny
      como estás?, un placer saludarte igualmente.

      Lo que se suele hacer es traer todos los datos A1:J10 y luego jugar con loa nachos de las columnas, dejando ancho cero sobre la propiedad ColumnWidth en las que no quieras ver, en tu caso, la 2,3,4 y 5

      Saludos

      Eliminar