Estimo que no hace falta ninguna introducción a los Autofiltros de Excel, dado que en mayor o menor medida todos los hemos utilizados y conocemos sus principales funciones y configuración.
Pero. Y sí, si no hubiese "peros" este blog (estimo) no existiría.
Un lector tiene problemas a la hora de automatizar los Autofiltros mediante macros. Y yo se por que el tiene esos problemas: por que los Autofiltros son conflictivos y, de entrada, no se llevan bien con VBA. A menos que le hagamos algunos retoques al código.
las clásicas "flechitas para abajo" del Autofiltro.
[+/-] Ver el resto / Ocultar
Supongamos que filtramos todos los valores iguales a uno (1) de la primer columna, mientras tenemos activada la grabación de macros. Este sería el código resultante:
Sub Macro1()
'selecciono el rango A1 (que es donde comienza la tabla)
Range("A1").Select
'aplico el autofiltro
Selection.AutoFilter
'Excel define el rango, el campo (field) del criterio y el criterio aplicado (1)
ActiveSheet.Range("$A$1:$B$16").AutoFilter Field:=1, Criteria1:="1"
End Sub
En el código se observa
Field:=1 por que es el primer campo el que filtramos (columna 1 de la tabla) y
Criteria:=1 por que es el criterio de filtrado (todos los registros del campo 1 (codigo) que sean iguales a 1)
Nos queda:
exacto, ni mas ni menos.
Podemos quitar el Autofiltro y ejecutar nuestra macro las veces que necesitemos, y esta funcionará correctamente. Pero seamos sinceros... esta automatización no tiene hasta ahora mucho sentido.... el criterio a filtrar está dentro del código y siempre nos traerá todos los códigos iguales a 1. Necesitamos que, por ejemplo, el usuario ingrese en D1 el código, nuestra macro lo capture y posteriormente lo utilice en el criterio de filtrado. Probemos:
Sub Macro1()
Range("A1").Select
Selection.AutoFilter
ActiveSheet.Range("$A$1:$B$16").AutoFilter Field:=1, Criteria1:=[d1]
End Sub
"perféto". en D1 puse el valor 2 y ejecuté la macro, logrando el resultado esperado.
Nos envalentonamos un poco y vamos a cambiar el Field (campo) por el numero 2 y en D1 ingresaremos 12/01/1974, para aplicar ese criterio al Autofiltro:
Sub Macro1()
Range("A1").Select
Selection.AutoFilter
ActiveSheet.Range("$A$1:$B$16").AutoFilter Field:=2, Criteria1:=[d1]
End Sub
Y Excel, educadamente, nos retorna:
... nada.
Por que funciona con el campo 1 (codigo) y no con el campo 2 (fecha)? Por que en realidad el problema radica en la forma mediante la cual VBA interpreta las fechas. El formato yanquilandia se impone (mm/dd/yyyy), con el agregado de que, generalmente, primero debemos convertirla a un tipo String (cadena).
Cuando a mí se me presentó este inconveniente (hace mucho tiempo atrás) encontré una sola forma de solucionarlo, que es la que detallo a continuación. Seguro existen otras... pero como esta anduvo bien la dejé así y no intenté otros métodos. Será bienvenido cualquier aporte al respecto.
Sub AutoFiltroConFechas()
'defino una variable del tipo string
Dim Fecha As String
'armo la fecha con el formato yanqui (mm/dd/yyyy)
Fecha = Month([d1]) & "/" & Day([d1]) & "/" & Year([d1])
'selecciono el comienzo de la tabla
Range("a1").Select
Selection.AutoFilter
'y aplico el filtro: campo 2, criterio=fecha
ActiveSheet.Range("$A$1:$B$16").AutoFilter Field:=2, Criteria1:= _
"=" & Fecha & ""
End Sub
Y ahora:
funciona.
Y con otro valor (fecha) en D1:
it works, too.
Practicando un poco con las macros y los autofiltros podrán crear consultas muy avanzadas, como por ejemplo el filtrado de un codigo entre dos fechas determinadas, etc, etc. Este ejemplo es bien básico y consta de tan solo dos columnas, siendo que en la mayoría de nuestros proyectos las tablas son mucho mas amplias y complejas, en cuanto a cantidad y tipos de datos. Pero mejor... paso a paso, para complicarla.... siempre hay tiempo. De a poco pueden ir sumando columnas y hacer luego cualquier cosa.
Solo deben tener en cuenta como pasar correctamente el criterio "fecha".
gracias hermano. muy util tu publicacion.
ResponderEliminartengo una pregunta:
en lugar de poder buscar en 1 campo se podria buscar en 2 campos??
como seria
fijate que el comando para filtrar con las macros contiene dos palabras: "field" y "criteria" (campo y criterio de filtrado). a su vez esas palabras están seguidas de un número: 1, 2, 3, n.
ResponderEliminartenés que ir agregando campos y criterios, de acuerdo a tus necesidades, como por ejemplo:
Selection.AutoFilter Field:=1, Criteria1:="2", Field:=2, Criteria1:="word"
en la sentencia de arriba tengo a field1 y field2... si hubiese necesitado agregar otro filtrado, simplemente pongo field3 o el field que sea (no tienen por que estar correlativos)
y en en este ejemplo filtré el código 2 del campo y a "word" del campo 2
¿Se entiende? Otra línea: ahora filtro los datos de la primer, segunda y quinta columna:
Selection.AutoFilter Field:=1, Criteria1:="2", Field:=2, Criteria1:="word", Field:=5, Criteria1:="blog"
colocas el nro de campo (field) y luego el criterio de filtrado (valor a buscar) del mismo.
cualquier cosa me avisas y te armo otro ejemplo.
un abrazo
Muy interesante tu publicación.
ResponderEliminarUna pregunta:
Cuando aplico un filtrado con el autofiltro en la parte inferior de excel aparecen la cantidad de filas que fueran afectadas por el filtrado.
Existe alguna forma para obtener ese valor por medio de una macro.
Saludos
mirá: hay una forma muy sencilla con funciones, sin llegar a las macros:
ResponderEliminarsupongamos que tenes la tabla a la cual le aplicarás el autofiltro en el rango A1:D20.
O sea: cuatro campos y 19 registros, ya que en la primer fila están los encabezados. ¿bien?
Te vas a la celda F1 y colocas esta función:
=SUBTOTALES(3;A2:A20)
y listo, cada vez que filtres esa función te devolverá la cantidad de elementos encontrados.
Fijate que el segundo argumento comienza en A2, es decir que NO incluyo el encabezado.
El primer argumento (3) hace referencia la función CONTARA()... si buscas en la ayuda de excel sobre SUBTOTALES() verás los 7 argumentos disponibles. creo que ese es el que mejor se ajusta a este caso.
si lo necesitas si o si con macros avisame que armamos algo.
un abrazo
disculpame, SUBTOTALES() acepta 11 valores posibles en su primer argumento, no 7.
ResponderEliminarbueno, terminemos bien... jajaa, ya que estoy te paso la macro, que hace exactamente lo mismo: utiliza a SUBTOTALES, con las WorksheetFunctions de Excel:
ResponderEliminarSub CountFilter()
res = Application.WorksheetFunction.Subtotal(3, Range("a2:a20"))
MsgBox res
End Sub
en el ejemplo de arriba muestro el resultado (res) en un MsgBox, pero vos podes colocarlo en un form, una celda, etc, etc, etc.
avisame si te sirvió.
un abrazo
Hola mi nombre es luisa fernanda, tengo un caso parecido a lo del autofiltro pero lo necesito filtrar por tres campos seleccionados por lista desplegable, que al seleccionar los tres items me los filtre y genere los registros que coincidan con esas tres condiciones. me permito adjuntar el codigo aver que tengo mal. cualquier cosa mi correo es: luisa.criales@gmail.com
ResponderEliminarSub BuscarDatos()
'Consultar Fecha ingreso, Valor ingresado, Tipo de gasto
Dim FechaIngreso As Date
Dim ValorIngresado as long
Dim TipoGasto as String
Criterio1 = "=*" & Range("FechaIngreso") & "*"
Criterio2 = "=*" & Range("ValorIngresado") & "*"
Criterio3 = "=*" & Range("TipoGasto") & "*"
uf1 = Range("A" & Cells.Rows.Count).End(xlUp).Row + 1
uf2 = Range("A" & Cells.Rows.Count).End(xlUp).Row + 1
uf3 = Range("A" & Cells.Rows.Count).End(xlUp).Row + 1
'Range("A2:Z" & uf1).ClearContents
Range("A2:Z" & uf1).AutoFilter Field:=2, Criteria1:=criterio1, Operator:=xlAnd
Range("A2:Z" & uf2).AutoFilter Field:=11, Criteria1:=criterio2, Operator:=xlAnd
Range("A2:Z" & uf3).AutoFilter Field:=12, Criteria1:=criterio3, Operator:=xlAnd
Range("K1").Select
Range("L1").Select
Range("M1").Select
End Sub
Gracias!!!
luisa: me parece que tu macro no funciona correctamente por culpa del campo "fecha". Fijate en el ejemplo que doy dentro del post: convierto esa fecha a formato "yanqui": mm/dd/yyyy (mes, dia, año). Otra cosa: en mi ejemplo no uso ateriscos para las fechas.
ResponderEliminarY no uses tres variables para determinar la ultima fila de la tabla: con una sola alcanza. Ej:
Uf = Range("A" & Cells.Rows.Count).End(xlUp).Row + 1
y luego usas Uf para todos los rangos. ¿Se entiende?
Entonces: primero le das el formato sajón a la fecha (mes, dia y año, como en el ejemplo), quitas los ateriscos del filtro en donde usas esa fecha y, por último, utiliza una sola variable para determinar el fin de la tabla.
¿por que le sumas 1? eso agrega un registro en blanco... ojo.
Gracias por tu mensaje y cualquier cosa me avisas
HOla, soy luisa otra vez, tengo el codigo modificado de acuerdo como creo que te lo entendi:
ResponderEliminarSub BuscarDatos1()
Dim Fecha As Long
criterio = "=" & Range("Fecha") & ""
uf1 = Range("A" & Cells.Rows.Count).End(xlUp).Row + 1
Range("A2:Z" & uf1).AutoFilter Field:=2, Criteria1:=criterio, Operator:=xlAnd
Range("K1").Select
End Sub
no se si lo estoy haciendo bien a la celda donde esta la fecha el cambie el formato de fehca por MM/DD/AA, pero me sigue arrojando 0 registros, que puedo estar haciendo mal?
Gracias
No, no tenes que modificar el formato de la celda... ya que es solo eso: un formato... internamente Excel lo sigue leyendo igual. Una cosa es el contenido de la celda y otra es el formato que se le aplica.
ResponderEliminarYo lo logro con macros, así:
Fecha = Month([d1]) & "/" & Day([d1]) & "/" & Year([d1])
adapta ese código a la celda en donde tienes la fecha, debería funcionar sin problemas
suerte y cualquier cosa me avisas.