TL;DR —
Filter(sourceArray, match)devuelve un array nuevo de base cero que contiene solo los elementos que contienen la subcadenamatch. Es una búsqueda sobre un array en memoria, no una hoja — nada que ver conAutoFilter. Tres cosas muerden: coincide con una subcadena (así que"AB"conserva"CAB"), distingue mayúsculas por defecto (pasavbTextComparepara ignorarlas), y un resultado sin coincidencias es un array vacío conUBound = -1, no un error. El tercer argumento opcionalIncludelo invierte:Filter(a, "x", False)conserva todo lo que no contiene"x".
Sub FilterDemo()
Dim names As Variant, hits As Variant
names = Array("Smith", "Jones", "Smithson", "Adams")
hits = Filter(names, "Smith") ' conserva los elementos que contienen "Smith"
Debug.Print hits(0) ' Smith <- indice 0, siempre base cero
Debug.Print hits(1) ' Smithson <- coincide subcadena, no palabra entera
Debug.Print UBound(hits) ' 1 <- dos aciertos: indices 0 y 1
hits = Filter(names, "smith") ' minusculas -> SIN coincidencia por defecto
Debug.Print UBound(hits) ' -1 <- array vacio, no un error
End Sub
La firma completa, incluidos los dos argumentos que hacen tropezar a la gente:
Filter(sourceArray, match, [include], [compare])
' array 1-D texto True/False vbTextCompare = ignora mayusculas
Lo que aprenderás
- El modelo mental — Filter busca en un array y te devuelve los que se quedan
- Por qué
Filterno esAutoFilter, y cuándo quieres de verdad cada uno - La trampa de la subcadena:
Filtercoincide dentro de las palabras, no con valores enteros - La distinción de mayúsculas, y el arreglo con
vbTextCompare - La trampa del resultado vacío (
UBound = -1) y cómo protegerse de ella Include:=Falsepara invertir el filtro, y el ida y vuelta con Split y Join
El modelo mental: Filter busca en un array, no en una hoja
Filter es la prima en arrays de InStr. Donde InStr
pregunta «¿está este texto dentro de una cadena, y dónde?», Filter pregunta «¿cuáles de estas cadenas
contienen este texto?» y te devuelve un array totalmente nuevo que contiene solo las que sí. Le das una
lista; te da la lista más corta.
Ese enfoque te dice exactamente cuándo recurrir a él: ya tienes un array de cadenas unidimensional en memoria — los trozos de un Split, las claves de un Dictionary, una lista de nombres de archivo de Dir — y quieres el subconjunto que menciona algo. Es un reemplazo en una línea del bucle que todo el mundo escribe:
' La forma larga que todos escriben primero
Dim i As Long, n As Long
ReDim keep(UBound(names)) As String
For i = 0 To UBound(names)
If InStr(1, names(i), "Smith") > 0 Then
keep(n) = names(i): n = n + 1
End If
Next i
ReDim Preserve keep(n - 1)
' Lo mismo, en una sola llamada
keep = Filter(names, "Smith")
La confusión que hay que despejar: Filter no es AutoFilter
Esta es la mayor fuente de preguntas «¿por qué no funciona Filter en mi hoja?», y la respuesta es que sostienes dos herramientas no relacionadas que resulta que comparten una palabra. No son variantes una de otra:
Filter() — la función |
AutoFilter — el método |
|
|---|---|---|
| Opera sobre | un array 1-D en memoria | un Range de hoja |
| Devuelve | un array nuevo y más pequeño | nada — oculta filas en la interfaz |
| ¿Toca celdas? | nunca | sí, es un estado visible de la hoja |
| Tipo de coincidencia | subcadena, distingue mayúsculas | igual / contiene / mayor que, vía criterios |
| Lo quieres cuando | ya tienes un array | quieres mostrar al usuario filas filtradas |
Si tus datos están en celdas y quieres reducirlos, quieres AutoFilter o, para
copias con varios criterios, Filtro avanzado — no esta función. Filter()
se gana su sitio después de que hayas traído los datos a un array. Una tubería habitual y correcta es: lee
una columna, aplánala a un array 1-D (trabajo para Transpose), y luego pásala por
Filter en memoria sin tocar la hoja para nada.
Trampa 1: Filter coincide con una subcadena, no con un valor entero
Filter conserva cualquier elemento donde el texto buscado aparezca en cualquier lugar dentro de él.
Eso es una ventaja para búsquedas de tipo «contiene» y un tiro al pie para búsquedas de tipo «igual a»:
Dim codes As Variant, r As Variant
codes = Array("AB", "ABC", "CAB", "XY")
r = Filter(codes, "AB")
' r contiene "AB", "ABC" Y "CAB" - cada elemento que CONTIENE "AB"
Si querías solo los elementos iguales a "AB", Filter es la herramienta equivocada — no puede hacer
coincidencia exacta. Para una prueba de pertenencia con coincidencia exacta, recurre a un
Dictionary (dict.Exists(key)) o a Application.Match. Usa Filter cuando
«contiene» sea de verdad lo que quieres decir.
Trampa 2: Filter distingue mayúsculas por defecto
De fábrica, Filter usa una comparación binaria — "smith" no coincide con "Smith". Esto es lo
contrario del valor por defecto mental de la mayoría de la gente y devuelve en silencio un array vacío. El
cuarto argumento lo arregla:
r = Filter(names, "smith") ' binario -> se salta "Smith"
r = Filter(names, "smith", True, vbTextCompare) ' texto -> coincide con "Smith", "SMITH", "smith"
Fíjate en que debes suministrar el tercer argumento (Include, aquí True) para llegar al cuarto. Como
alternativa, Option Compare Text en la parte superior del módulo hace que cada comparación de cadenas de
ese módulo ignore las mayúsculas, Filter incluido — cómodo, pero cambia el comportamiento en todo el
módulo, así que pasa vbTextCompare por llamada cuando quieras el efecto local.
Trampa 3: sin coincidencia devuelve un array vacío, e Include invierte
Un Filter que no coincide con nada no lanza un error — devuelve un array válido de longitud cero, cuyo
UBound es -1. Un bucle For i = 0 To UBound(r) sobre él no hace nada sin riesgo, pero acceder a
r(0) revienta con subíndice fuera del intervalo. Protégete con UBound antes de indexar:
r = Filter(names, "Zzz")
If UBound(r) < 0 Then
MsgBox "No matches."
Else
MsgBox (UBound(r) + 1) & " match(es) found." ' cantidad = UBound + 1
End If
Y el argumento que casi nadie recuerda: Include. Su valor por defecto es True (conserva las
coincidencias). Pasa False y Filter invierte — conserva cada elemento que no contiene la
coincidencia. Así es como quitas elementos de una lista en una sola línea:
' Descarta cada ruta que menciona "temp"
clean = Filter(paths, "temp", False)
La opinión: Filter es para arrays que ya tienes — y la línea Split-Filter-Join
Filter es un pegamento excelente y un motor pobre. Brilla con datos que ya son un array de cadenas 1-D y
donde «contiene» es la pregunta real — recortar el listado de una carpeta, acotar tokens de un Split,
mantener las líneas de error fuera de un array de log. Es la respuesta equivocada en el momento en que
quieres coincidencias exactas (usa un Dictionary), en el momento en que tus datos siguen en celdas (usa
AutoFilter), o en el momento en que los elementos no son cadenas (Filter fuerza a cadena y compara texto, lo
que engaña en silencio con los números).
Su mejor truco es ser el centro de una tubería de tres funciones. Split analiza, Filter conserva, Join reensambla — una sola expresión que reemplaza un bucle de quince líneas:
' De una linea CSV, conserva solo los campos que mencionan "2026" y reunelos
result = Join(Filter(Split(line, ","), "2026"), ", ")
Esa línea es todo el grupo en miniatura: Split convierte la cadena en un array,
Filter la reduce a un subconjunto, Join la colapsa de vuelta — sin bucle, sin
aritmética de índices, sin errores por uno.
Cómo ayuda ExcelMaster
Filtrar rara vez es el objetivo. El objetivo es «saca las facturas vencidas de esta exportación, descarta las filas de prueba y dame los códigos de cliente». Para cuando has leído la columna a un array, la has aplanado, has protegido la distinción de mayúsculas, has manejado el resultado vacío y has reunido a los supervivientes, la fontanería eclipsa la única respuesta que querías. ExcelMaster te deja enunciar ese objetivo en español llano — «lista los códigos de cliente de cada factura vencida que no sea de prueba» — y genera Python que lee los datos, aplica la lógica de coincidencia real y respalda tu archivo primero — tú describes el resultado que quieres, y él se encarga de la distinción de mayúsculas, los casos vacíos y los bordes.
Preguntas frecuentes
¿Qué hace la función Filter en VBA?
Filter(sourceArray, match) devuelve un array nuevo que contiene solo los elementos de sourceArray que
contienen la subcadena match. La fuente debe ser un array unidimensional, y el resultado es siempre de base
cero. Busca en un array en memoria y devuelve un array más pequeño — no cambia ninguna celda.
¿Es VBA Filter lo mismo que AutoFilter?
No. Filter() es una función que reduce a un subconjunto un array unidimensional en memoria y devuelve un
array nuevo. AutoFilter es un método de hoja que oculta filas en la hoja visible según criterios.
Comparten un nombre y nada más — si tus datos están en celdas, quieres AutoFilter; si ya son un array,
quieres Filter().
¿Por qué VBA Filter no devuelve nada cuando el texto claramente coincide?
Casi siempre es por la distinción de mayúsculas. Filter usa una comparación binaria por defecto, así que
"smith" no coincide con "Smith". Pasa vbTextCompare como cuarto argumento —
Filter(a, "smith", True, vbTextCompare) — o pon Option Compare Text en la parte superior del módulo.
¿Cómo excluyo elementos con VBA Filter?
Pasa False como tercer argumento, Include. Filter(paths, "temp", False) devuelve cada elemento que
no contiene "temp". Con Include omitido o True, Filter conserva las coincidencias; con False
conserva las no coincidencias.
¿Cómo compruebo si VBA Filter encontró alguna coincidencia?
Comprueba el UBound del resultado. Un Filter sin coincidencias devuelve un array vacío cuyo UBound es
-1, no un error, así que If UBound(result) < 0 Then significa que nada coincidió. El número de
coincidencias es UBound(result) + 1, ya que el array es de base cero.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 03/09/2026.
Guías relacionadas: VBA Join · VBA Transpose · VBA Split · VBA AutoFilter · VBA Dictionary
