Filtro / listbox de VBA en Excel
ludivine
-
amine69500 Mensajes publicados 471 Estado Miembro -
amine69500 Mensajes publicados 471 Estado Miembro -
Bonjour,
Como principiante en VBA Excel, estoy encontrando bastantes problemas a pesar de numerosas búsquedas en Internet.
Quisiera mostrar el contenido SIN DUPLICADOS de una columna en un menú desplegable en un formulario, sabiendo que los valores a mostrar comienzan solo en la fila 3 (lo he conseguido, pero los duplicados siguen ahí).
También me gustaría crear un código para quitar los filtros de todas las columnas excepto la columna 1 de mi hoja. (sin tener que hacer 1 línea de código para cada columna).
¿Alguien puede ayudarme? Es difícil avanzar a tientas... jaja
Gracias de antemano
Ludivine
Como principiante en VBA Excel, estoy encontrando bastantes problemas a pesar de numerosas búsquedas en Internet.
Quisiera mostrar el contenido SIN DUPLICADOS de una columna en un menú desplegable en un formulario, sabiendo que los valores a mostrar comienzan solo en la fila 3 (lo he conseguido, pero los duplicados siguen ahí).
También me gustaría crear un código para quitar los filtros de todas las columnas excepto la columna 1 de mi hoja. (sin tener que hacer 1 línea de código para cada columna).
¿Alguien puede ayudarme? Es difícil avanzar a tientas... jaja
Gracias de antemano
Ludivine
Configuración: windows/excel97 y + /vb 6
15 respuestas
Essa prueba esta macro, que se ejecuta al abrir tu libro. Crea la lista ordenada sin duplicados en una hoja especial que llamo Param (no es necesario crear la hoja, se hace automáticamente si no existe) y le asigna un nombre. Todo se recalcula cada vez que se abre el libro. El nombre del rango es PlageListBox (puedes cambiar todo lo que quieras...).
Y en las propiedades de tu ListBox, puedes poner el nombre de este rango en RowSource.
Y en las propiedades de tu ListBox, puedes poner el nombre de este rango en RowSource.
Sub PrepaListe() Dim Lig_Deb As Long Dim DerLig As Long Dim Col As String Dim Feuille As String Dim CelluleCourante As Range Dim CelluleSuivante As Range Dim FF As Worksheet ' PARÁMETROS A ADAPTAR '---------------------------------------------------------------------------- Lig_Deb = 3 ' n° de la primera línea de datos filtrados Col = "A" ' columna de datos filtrados Feuille = "Feuil1" ' nombre de la hoja de datos '---------------------------------------------------------------------------- Application.ScreenUpdating = False On Error Resume Next Worksheets("Param").Activate If Err.Number = 9 Then Worksheets.Add ActiveSheet.Name = "Param" End If On Error GoTo 0 Sheets("Param").Cells.ClearContents Set FF = Sheets(Feuille) DerLig = FF.Cells(65536, Col).End(xlUp).Row FF.Range(Col & Lig_Deb & ":" & Col & DerLig).Copy Cells(1, 1).Select ActiveSheet.Paste Selection.Sort Key1:=Range("A1"), _ Order1:=xlAscending, _ Header:=xlNo Application.CutCopyMode = False Set CelluleCourante = Range("A1") Do While Not IsEmpty(CelluleCourante) Set CelluleSuivante = CelluleCourante.Offset(1, 0) If CelluleSuivante.Value = CelluleCourante.Value Then CelluleCourante.EntireRow.Delete End If Set CelluleCourante = CelluleSuivante Loop On Error Resume Next ActiveWorkbook.Names("PlageListBox").Delete On Error GoTo 0 DerLig = Range("A65536").End(xlUp).Row ActiveWorkbook.Names.Add Name:="PlageListBox", _ RefersToR1C1:="=Param!R1C1:R" & DerLig & "C1" Application.ScreenUpdating = True End Sub
Bonjour,
he diseñado una zona de lista a través de Excel "datos/validación" en la columna A. Y de la misma manera, una segunda zona de lista en la columna B. Sin embargo, mi jefe me pide que al seleccionar un valor de la columna A, la columna B solo muestre los datos correspondientes a ese valor en la columna B.
Ejemplo:
zona de lista columna A: "a;b;c;d;e"
zona de lista columna B: "aa;ab;ac;ad;af;ba;bb;bc;bd..."
el deseo:
cuando seleccionamos en la columna A: el valor "a"
entonces la zona de lista de la columna B solo muestra los valores que comienzan con a: {aa;ab;ac;ad;af}
y no la lista total ya que tengo 12000 valores y el usuario realmente se pierde.
Gracias de antemano por su colaboración.
he diseñado una zona de lista a través de Excel "datos/validación" en la columna A. Y de la misma manera, una segunda zona de lista en la columna B. Sin embargo, mi jefe me pide que al seleccionar un valor de la columna A, la columna B solo muestre los datos correspondientes a ese valor en la columna B.
Ejemplo:
zona de lista columna A: "a;b;c;d;e"
zona de lista columna B: "aa;ab;ac;ad;af;ba;bb;bc;bd..."
el deseo:
cuando seleccionamos en la columna A: el valor "a"
entonces la zona de lista de la columna B solo muestra los valores que comienzan con a: {aa;ab;ac;ad;af}
y no la lista total ya que tengo 12000 valores y el usuario realmente se pierde.
Gracias de antemano por su colaboración.
Re, ludivine,
OK. Prueba esto, colócalo en la macro Initialize de tu UserForm. Adapta los parámetros:
- Lig: número de la primera línea de datos
- Col: columna de los datos
- ListBox1: reemplaza eventualmente por el nombre de tu ListBox.
OK. Prueba esto, colócalo en la macro Initialize de tu UserForm. Adapta los parámetros:
- Lig: número de la primera línea de datos
- Col: columna de los datos
- ListBox1: reemplaza eventualmente por el nombre de tu ListBox.
Private Sub UserForm_Initialize() Dim Lig As Long Dim Col As String Dim ValeurCourante As String Dim ValeurPrécédente As String Lig = 3 Col = "A" ValeurPrécédente = "" ValeurCourante = Cells(Lig, Col).Value Do While ValeurCourante <> "" If ValeurCourante <> ValeurPrécédente Then ListBox1.AddItem ValeurCourante End If Lig = Lig + 1 ValeurPrécédente = ValeurCourante ValeurCourante = Cells(Lig, Col).Value Loop End SubPara los filtros, ¿lo que te di no funciona? ¿Eso elimina todos los filtros y reinstala el de la columna "A"?
Hola Ludivine,
Para eliminar duplicados en la columna "A" a partir de la fila 3:
EntireRow elimina toda la fila. Quitarlo para eliminar solo la celda.
Para los filtros:
Para eliminar duplicados en la columna "A" a partir de la fila 3:
Dim CelluleCourante As Range Dim CelluleSuivante As Range Set CelluleCourante = Range("A3") Do While Not IsEmpty(CelluleCourante) Set CelluleSuivante = CelluleCourante.Offset(1, 0) If CelluleSuivante.Value = CelluleCourante.Value Then CelluleCourante.EntireRow.Delete End If Set CelluleCourante = CelluleSuivante Loop Si no quieres destruir tus duplicados, sino solo no mostrarlos, puedes inspirarte en esto, o trabajar en otra columna provisional en la que habrás copiado los datos. EntireRow elimina toda la fila. Quitarlo para eliminar solo la celda.
Para los filtros:
ActiveSheet.AutoFilterMode = False Columns("A:A").AutoFilter
Hola Armojax,
Gracias por tu respuesta, sin embargo, quizás no me expresé bien:
de hecho, tengo una hoja con una base de datos
el objetivo es acceder a los datos a través de formularios (para simplificar la búsqueda)
la listbox en el formulario es para filtrar la columna A, mostrando así la lista de valores de la columna A sin duplicados (para la visualización...), ellos seleccionan y eso devuelve el valor en el filtro automático
en el otro procedimiento (filtros), hice:
Selection.AutoFilter Field:=2
Selection.AutoFilter Field:=3
Selection.AutoFilter Field:=4
...
para no tocar el filtro de mi columna A que debe permanecer filtrada, mientras conservo la posibilidad de acceder a los filtros de la hoja...
funciona, por supuesto, pero debe haber una forma más corta, jaja
??
Ludivine
Gracias por tu respuesta, sin embargo, quizás no me expresé bien:
de hecho, tengo una hoja con una base de datos
el objetivo es acceder a los datos a través de formularios (para simplificar la búsqueda)
la listbox en el formulario es para filtrar la columna A, mostrando así la lista de valores de la columna A sin duplicados (para la visualización...), ellos seleccionan y eso devuelve el valor en el filtro automático
en el otro procedimiento (filtros), hice:
Selection.AutoFilter Field:=2
Selection.AutoFilter Field:=3
Selection.AutoFilter Field:=4
...
para no tocar el filtro de mi columna A que debe permanecer filtrada, mientras conservo la posibilidad de acceder a los filtros de la hoja...
funciona, por supuesto, pero debe haber una forma más corta, jaja
??
Ludivine
Hola,
No funciona, sniff ... ¡duro para un viernes!
Seguro que me he olvidado de algo, pero no entiendo nada de la primera parte de tu código, así que si tengo que adaptarlo, no va a ser fácil.
Bueno, para la listbox, originalmente, tenía bien la lista de mis datos ... solo que al haber dado el nombre de l
No funciona, sniff ... ¡duro para un viernes!
Seguro que me he olvidado de algo, pero no entiendo nada de la primera parte de tu código, así que si tengo que adaptarlo, no va a ser fácil.
Bueno, para la listbox, originalmente, tenía bien la lista de mis datos ... solo que al haber dado el nombre de l
¡No hagas sniff, Ludivine...!
A continuación un ejemplo:
https://www.cjoint.com/?izkDwEfevP
Al abrir el libro, el Listbox se muestra automáticamente.
Mira el código del UserForm...
A continuación un ejemplo:
https://www.cjoint.com/?izkDwEfevP
Al abrir el libro, el Listbox se muestra automáticamente.
Mira el código del UserForm...
ok, No puede funcionar en mi caso, los duplicados no necesariamente están uno al lado del otro, a menos que se haga un ordenamiento al abrir...
para los filtros, (no he podido terminar todo a esta hora), he anotado bien tu código para más tarde, pero te explico:
los usuarios seleccionan un valor de mi listbox (el que causa problemas) y el valor se envía al filtro de la col A, no quiero que tengan control sobre este filtro, pero sí sobre los otros...
entonces, si reinicio el filtro, el valor ya no estará, a menos que se pueda reintegrar...
No olvides que soy principiante, ¡pero de verdad, de verdad!
para los filtros, (no he podido terminar todo a esta hora), he anotado bien tu código para más tarde, pero te explico:
los usuarios seleccionan un valor de mi listbox (el que causa problemas) y el valor se envía al filtro de la col A, no quiero que tengan control sobre este filtro, pero sí sobre los otros...
entonces, si reinicio el filtro, el valor ya no estará, a menos que se pueda reintegrar...
No olvides que soy principiante, ¡pero de verdad, de verdad!
Lo siento, Ludivine, pero mi FreeBox estuvo fuera de servicio durante 3 horas. Bueno, 3 horas en 2 años no es una catástrofe, pero...
Así que te coloco un nuevo archivo aquí:
https://www.cjoint.com/?izrcMmdFXA
Veo un poco mejor lo que quieres hacer.
El formulario no se abre al inicio. Puedes hacer <CTRL+MAYÚS+M>.
Podrás configurar la macro Initialize según tus propias necesidades. Utilizo la columna "Z" para copiar los datos de la columna "A" y ordenarlos para alimentar el ListBox.
Cuando hacemos clic en la lista, filtramos los datos correspondientes. En el comando he puesto el parámetro VisibleDropDown en False, lo que oculta la pequeña "flecha hacia abajo" del filtro. Puedes ponerlo en True (o quitarlo, es el valor predeterminado) si quieres.
A seguir, sin duda...
Así que te coloco un nuevo archivo aquí:
https://www.cjoint.com/?izrcMmdFXA
Veo un poco mejor lo que quieres hacer.
El formulario no se abre al inicio. Puedes hacer <CTRL+MAYÚS+M>.
Podrás configurar la macro Initialize según tus propias necesidades. Utilizo la columna "Z" para copiar los datos de la columna "A" y ordenarlos para alimentar el ListBox.
Cuando hacemos clic en la lista, filtramos los datos correspondientes. En el comando he puesto el parámetro VisibleDropDown en False, lo que oculta la pequeña "flecha hacia abajo" del filtro. Puedes ponerlo en True (o quitarlo, es el valor predeterminado) si quieres.
A seguir, sin duda...
Bonjour, he visto tus intervenciones sobre un problema que se asemeja al mío.
He creado un programa que hace el acumulado de salidas de productos; tengo varios tipos de productos.
Cada vez que salgo productos, completo cuadros de texto (fecha, cantidad, nombre del cliente, fecha de factura, número de albarán, destino, tipo de vehículo, matrícula). Una vez introducida esta información, se registra automáticamente en una hoja de Excel.
Mi problema es que quiero crear otro userform2 controlado por un botón en el userform1.
En mi userform2 quiero tener 3 listbox: el listbox1 muestra los encabezados de la hoja donde se registran los datos, el listbox2 muestra los datos filtrados de cada columna (por ejemplo, si selecciono el nombre del cliente en el listbox1, que el listbox2 muestre todos los clientes sin duplicados y si selecciono un cliente en el listbox2, todos los movimientos que ha realizado se muestren en el listbox3 en forma de tabla con todos los detalles; gracias de antemano.
He creado un programa que hace el acumulado de salidas de productos; tengo varios tipos de productos.
Cada vez que salgo productos, completo cuadros de texto (fecha, cantidad, nombre del cliente, fecha de factura, número de albarán, destino, tipo de vehículo, matrícula). Una vez introducida esta información, se registra automáticamente en una hoja de Excel.
Mi problema es que quiero crear otro userform2 controlado por un botón en el userform1.
En mi userform2 quiero tener 3 listbox: el listbox1 muestra los encabezados de la hoja donde se registran los datos, el listbox2 muestra los datos filtrados de cada columna (por ejemplo, si selecciono el nombre del cliente en el listbox1, que el listbox2 muestre todos los clientes sin duplicados y si selecciono un cliente en el listbox2, todos los movimientos que ha realizado se muestren en el listbox3 en forma de tabla con todos los detalles; gracias de antemano.
Hola
parecía que funcionaba en algún momento... pero ahora no entiendo nada
he insertado un nuevo formulario, según la respuesta, el formulario con la listbox en cuestión debe mostrarse, pero me da un error de ejecución '13', tengo la impresión de que no le gusta la inicialización...
¿estás seguro de que no hay forma de completar más simplemente (sin inicialización) la propiedad rowsource de la listbox con un parámetro adicional para mostrar solo una vez los mismos valores (parámetro que no conozco por supuesto...)
??
parecía que funcionaba en algún momento... pero ahora no entiendo nada
he insertado un nuevo formulario, según la respuesta, el formulario con la listbox en cuestión debe mostrarse, pero me da un error de ejecución '13', tengo la impresión de que no le gusta la inicialización...
¿estás seguro de que no hay forma de completar más simplemente (sin inicialización) la propiedad rowsource de la listbox con un parámetro adicional para mostrar solo una vez los mismos valores (parámetro que no conozco por supuesto...)
??
A priori, el error de VBA "13" es Incompatibilidad de tipo. Quizás texto que se usaría como numérico, por ejemplo, o algo así...?
Si tus datos son estables mientras usas tus macros, efectivamente podemos preparar la lista de la ListBox al abrir el libro, en lugar de en el Initialize del formulario. En este caso, necesitas ordenar tus datos y construir un rango donde se eliminen los duplicados. Luego, efectivamente utilizas la propiedad RowSource para referirte a este rango.
Si tus datos son estables mientras usas tus macros, efectivamente podemos preparar la lista de la ListBox al abrir el libro, en lugar de en el Initialize del formulario. En este caso, necesitas ordenar tus datos y construir un rango donde se eliminen los duplicados. Luego, efectivamente utilizas la propiedad RowSource para referirte a este rango.
En ese momento, creo que voy a crear un rango de datos con valores únicos, que será la fuente de alimentación para mi columna de datos
y alimentar mi listbox con el nombre del rango
me parece más sencillo (salvo que haya una nueva entrada para quien haga las modificaciones en la base de datos, aunque…), ¿qué opinas?
y alimentar mi listbox con el nombre del rango
me parece más sencillo (salvo que haya una nueva entrada para quien haga las modificaciones en la base de datos, aunque…), ¿qué opinas?
¡Hola Armojax!
Gracias por tu respuesta, sin embargo no lo he probado.
De hecho, hice lo que describí en mi último mensaje.
Creé mi lista exhaustiva (valores únicos) en una hoja oculta / Validación de datos en la columna de datos (valores múltiples)
lo que me permite finalmente controlar la entrada (los valores son siempre los mismos (aunque tengo 1 pequeño botón más para agregar 1 valor si es necesario con visualización en la hoja oculta...), es más seguro para el futuro de los eventos...
Además, mi listbox en el formulario está vinculado al rango nombrado de mi hoja oculta, así que todo está bien y sin duplicados. ¡Espero solo que usar la validación de datos no haga que todo se bloquee... (ya me ha pasado en otro archivo hace un tiempo...snif)
Gracias de nuevo, en otras circunstancias no dudaré en usar tu código
Que tengas un buen día
Ludivine
Gracias por tu respuesta, sin embargo no lo he probado.
De hecho, hice lo que describí en mi último mensaje.
Creé mi lista exhaustiva (valores únicos) en una hoja oculta / Validación de datos en la columna de datos (valores múltiples)
lo que me permite finalmente controlar la entrada (los valores son siempre los mismos (aunque tengo 1 pequeño botón más para agregar 1 valor si es necesario con visualización en la hoja oculta...), es más seguro para el futuro de los eventos...
Además, mi listbox en el formulario está vinculado al rango nombrado de mi hoja oculta, así que todo está bien y sin duplicados. ¡Espero solo que usar la validación de datos no haga que todo se bloquee... (ya me ha pasado en otro archivo hace un tiempo...snif)
Gracias de nuevo, en otras circunstancias no dudaré en usar tu código
Que tengas un buen día
Ludivine
¡Ah sí, solo una última preguntita!
¿Cómo puedo mostrar una flecha para desplegar mi listbox como una lista desplegable? (¿Soy clara?...)
Por ahora, tengo dos flechitas arriba y abajo a la derecha de mi listbox, y los valores solo se muestran dentro. Pero quisiera tener solo una flecha hacia abajo y al hacer clic, que toda la lista se muestre...
¿Cómo puedo mostrar una flecha para desplegar mi listbox como una lista desplegable? (¿Soy clara?...)
Por ahora, tengo dos flechitas arriba y abajo a la derecha de mi listbox, y los valores solo se muestran dentro. Pero quisiera tener solo una flecha hacia abajo y al hacer clic, que toda la lista se muestre...
En lugar de un ListBox, puedes utilizar un ComboBox. Muchas propiedades son idénticas, y no debería ser complicado de transponer. Tendrás una lista desplegable, y podrás determinar el número de elementos visibles de un golpe con la propiedad ListRows.
Y para responder a tu item n° 13 arriba: la macro que he proporcionado hace aproximadamente lo que has implementado: recalcula automáticamente, en una hoja separada, un rango que puedes pasar a RowSource. Puedes ejecutarla cada vez que abras el libro si cambia todo el tiempo, o solo cuando sea el momento...
Y para responder a tu item n° 13 arriba: la macro que he proporcionado hace aproximadamente lo que has implementado: recalcula automáticamente, en una hoja separada, un rango que puedes pasar a RowSource. Puedes ejecutarla cada vez que abras el libro si cambia todo el tiempo, o solo cuando sea el momento...