jueves, 3 de marzo de 2016

VBA: Elementos filtrados en un UserForm.

Veremos en esta ocasión un clásico, cómo obtener dentro de un ListBox, los elementos de una lista de nuestra hoja decálculo, que cumplan una condición.

Partiremos de nuestras lista en la hoja de cálculo:

VBA: Elementos filtrados en un UserForm.



Diseñamos un Formulario con los siguientes controles importantes:
1- Un TextBox: llamado 'txtFiltro1'
2- Un ListBox: llamado 'ListFiltrados'. Con una propiedad especial:.ListStyle= 1-fmListStyleOption (conseguiremos un efecto diferente, con un botón de selección en el ListBox para cada elemento).
3- Un botón de Cerrar (CommandButtom): llamado 'CmdCerrar'
4- unas etiquetas descriptivas...

El aspecto sería:

VBA: Elementos filtrados en un UserForm.



El objetivo consiste en rellenar el TextBox con un Año, y tras salir (evento _Exit) de ese control, completar el ListBox con los registros que coincidan con el año indicado...
Adicionalmente, al seleccionar uno de esos elementos filtrados en el ListBox se marcarán en la hoja de cálculo.


Así añadiremos nuestro código en la ventana del Formulario:

Private Sub UserForm_Initialize()
'Rellenamos las Etiquetas con las celdas A1:A4
For i = 1 To 4
    Me.Controls("Label" & i) = Cells(1, i).Value
Next i

'configuramos el ListBox para cuatro columnas
'y un mismo ancho por columna de 60 puntos
With ListFiltrados
    .ColumnCount = 4
    .ColumnWidths = "60 pt;60 pt;60 pt;60 pt"
End With
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub CmdCerrar_Click()
'Cerrar formulario
Unload Me
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub txtFiltro1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
'Ejecutamos el filtro al salir del TextBox

'en caso de no haber añadido ningún año salimos del procedimiento
If Me.txtFiltro1.Value = "" Then Exit Sub
'limpiamos el ListBox de filtros anteriores
Me.ListFiltrados.Clear

'recorremos cada fila de la hoja con datos
For i = 2 To 16
    'en caso de coincidencia con el Año
    If Cells(i, "C").Value = CInt(Me.txtFiltro1.Value) Then
        'añadimos el registro
        Me.ListFiltrados.AddItem Cells(i, "A")
        Me.ListFiltrados.List(Me.ListFiltrados.ListCount - 1, 1) = Cells(i, "B").Value
        Me.ListFiltrados.List(Me.ListFiltrados.ListCount - 1, 2) = Cells(i, "C").Value
        Me.ListFiltrados.List(Me.ListFiltrados.ListCount - 1, 3) = Cells(i, "D").Value
    End If
Next i
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub ListFiltrados_Click()
'Activar la celda del registro elegido

Range("A2").Activate
'contamos el número de elementos filtrados
Cuenta = Me.ListFiltrados.ListCount

'recorremos cada elemento del ListBox para idetificar cuál está seleccionado
For i = 0 To Cuenta - 1
    If Me.ListFiltrados.Selected(i) Then
        'una vez detectado el elemento seleccionado
        'según el NumId
        Valor = Me.ListFiltrados.List(i, 0)
        'realizamos la búsqueda y selección en la hoja de cálculo
        fila = Hoja1.Range("A2:A15").Find(What:=Valor, LookAt:=xlWhole, After:=ActiveCell).Row
        Hoja1.Range(Cells(fila, "A"), Cells(fila, "D")).Select
    End If
Next i
End Sub



El resultado final sería:

VBA: Elementos filtrados en un UserForm.


2 comentarios:

  1. Creo que se debe hacer este cambio:
    de: Hoja1.Range("A2:A15").
    a: Hoja1.Range("A2:A16").

    ResponderEliminar