TL;DR —
SpecialCellsdeja que Excel elija las celdas por tipo en lugar de por dirección: todas las celdas en blanco, todas las visibles, todas las fórmulas, todas las constantes. Es el gemelo en código de Inicio → Buscar y seleccionar → Ir a Especial. La regla más importante: cuando no encuentra nada, no devuelve un rango vacío — lanzaerror 1004, «No se encontraron celdas». Así que una llamada a secas es una bomba de relojería. Envuélvela siempre:
Dim blanks As Range
On Error Resume Next
Set blanks = ThisWorkbook.Worksheets("Data").Range("A2:A1000").SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not blanks Is Nothing Then blanks.Value = 0 ' solo se ejecuta si de verdad se encontraron celdas en blanco
Cada referencia que has construido hasta ahora describe un rectángulo — Range("A1:D100"),
Cells(r, c), un bloque tallado con Resize o CurrentRegion. Pero el trabajo real rara vez
quiere un rectángulo. Quiere todas las celdas vacías para rellenarlas, solo las filas visibles
tras un filtro, solo las fórmulas para bloquearlas. SpecialCells es cómo pides todo eso: dejas
de describir una dirección y empiezas a describir qué tipo de celda quieres. Esta guía se
construye sobre una sola idea — SpecialCells es un filtro que te devuelve una referencia, y «que
no haya coincidencias» es un error, no un conjunto vacío. Ten eso claro y el resto de trampas
desaparecen.
Lo que aprenderás
- El modelo mental —
SpecialCellselige celdas por tipo, la versión en código de Ir a Especial - La regla más importante — lanza
error 1004cuando nada coincide, así que protege cada llamada - Los tipos de celda que de verdad usas — en blanco, visibles, constantes, fórmulas, última celda
- El patrón para rellenar celdas en blanco —
xlCellTypeBlanksmás una fórmula de una línea - El patrón para copiar solo las filas visibles —
xlCellTypeVisibletras un AutoFilter (el que te salva el recuento de filas) - Por qué el resultado suele ser no contiguo (varias
Areas) y qué cambia eso
El modelo mental: SpecialCells elige celdas por tipo, no por dirección
Range y Cells responden qué celda con una ubicación — una cadena o dos números.
SpecialCells responde otra pregunta: ¿qué celdas de cierto tipo? Le das una región donde buscar
y una constante de tipo, y Excel recorre esa región y te devuelve una referencia a todas las celdas
que cumplen:
Dim used As Range: Set used = ActiveSheet.UsedRange
used.SpecialCells(xlCellTypeFormulas).Interior.Color = vbYellow ' resalta todas las formulas
Si alguna vez has usado Ir a Especial (pulsa F5 y luego Especial), esto es exactamente
ese cuadro de diálogo en código — «Constantes», «Fórmulas», «Celdas en blanco», «Solo celdas
visibles» son las mismas opciones. La potencia está en que Excel hace el recorrido: nunca recorres
la hoja en un bucle preguntando «¿esta está en blanco?» — pides todas las celdas en blanco de una
vez, y Excel te las devuelve como un único rango (a menudo con una forma extraña).
La regla más importante: lanza un error cuando no encuentra nada
Esta es la línea que convierte una macro que funciona en un fallo. Cuando ninguna celda de la
región de búsqueda coincide con el tipo, SpecialCells no devuelve un rango vacío — lanza
error 1004, «No se encontraron celdas». Un rango con cero celdas en blanco, pasado por
SpecialCells(xlCellTypeBlanks), detiene tu macro en seco:
' FRAGIL - falla con error 1004 el dia que no haya celdas en blanco:
Range("A2:A1000").SpecialCells(xlCellTypeBlanks).Value = 0
Esto es a propósito, no un bug: SpecialCells trata «sin coincidencias» como una condición
excepcional, no como un conjunto vacío. Eso significa que la forma segura no es opcional — es la
única forma correcta. La guarda de tres partes es: activa el control de errores, ejecuta la
llamada, vuelve a desactivarlo, y luego comprueba si es Nothing:
Dim hits As Range
On Error Resume Next
Set hits = Range("A2:A1000").SpecialCells(xlCellTypeBlanks)
On Error GoTo 0 ' deja de tragarse los errores de inmediato
If hits Is Nothing Then
MsgBox "No blank cells to fill."
Else
hits.Value = 0
End If
On Error Resume Next solo cubre esa única línea de riesgo; On Error GoTo 0 restaura el reporte
de errores normal justo después, para que no estés ignorando en silencio otros fallos (ver
VBA On Error). Sáltate la guarda y tu macro es una bomba de relojería que
funciona con cada archivo de prueba que tiene celdas en blanco y estalla con el primero que está
limpio.
Los tipos de celda que importan
SpecialCells(Type, [Value]) toma una constante de tipo, y un puñado cubren casi todo:
rng.SpecialCells(xlCellTypeBlanks) ' celdas vacias dentro de la region
rng.SpecialCells(xlCellTypeVisible) ' celdas no ocultas por un filtro o por filas ocultas
rng.SpecialCells(xlCellTypeConstants) ' valores escritos (numeros, texto) - no formulas
rng.SpecialCells(xlCellTypeFormulas) ' celdas que contienen una formula
rng.Cells.SpecialCells(xlCellTypeLastCell) ' la esquina inferior derecha del rango usado
xlCellTypeConstants y xlCellTypeFormulas aceptan un segundo argumento opcional para acotar por
tipo de resultado — SpecialCells(xlCellTypeFormulas, xlErrors) toma solo las fórmulas que ahora
mismo devuelven un error, que es la forma más rápida de encontrar todos los #REF! o #DIV/0! de
una hoja:
Dim bad As Range
On Error Resume Next
Set bad = ActiveSheet.Cells.SpecialCells(xlCellTypeFormulas, xlErrors)
On Error GoTo 0
If Not bad Is Nothing Then bad.Interior.Color = vbRed ' marca todas las formulas con error de una vez
El patrón para rellenar celdas en blanco
La razón clásica por la que la gente echa mano de SpecialCells es rellenar huecos en un informe —
repetir una etiqueta hacia abajo en cada celda en blanco bajo ella, o poner a cero los números
vacíos. Selecciona las celdas en blanco y luego escribe en toda la selección de una sola vez. Para
copiar el valor de la celda de encima de cada hueco, usa una fórmula R1C1 relativa y luego
conviértela en valores:
Dim gaps As Range
On Error Resume Next
Set gaps = Range("A2:A5000").SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not gaps Is Nothing Then
gaps.FormulaR1C1 = "=R[-1]C" ' cada celda en blanco = la celda justo encima
gaps.Value = gaps.Value ' congela las formulas en valores estaticos
End If
Esto rellena miles de huecos en dos líneas y sin bucle. FormulaR1C1 = "=R[-1]C" significa «una
fila arriba, misma columna», escrito en cada celda en blanco a la vez; la segunda línea reemplaza
las fórmulas por sus resultados para que el relleno sobreviva a una ordenación.
El patrón para copiar solo las filas visibles (el que te salva el recuento de filas)
xlCellTypeVisible es el tipo más útil de todos, por lo que VBA hace sin él. Después de aplicar
un AutoFilter, las filas que el filtro descarta quedan ocultas, no
eliminadas — y un .Copy a secas las copia igualmente. Para actuar solo sobre lo que el usuario
ve, tienes que pasar por SpecialCells(xlCellTypeVisible):
' Copia solo las filas que el filtro dejo visibles - las filas ocultas se omiten:
ws.Range("A1").CurrentRegion.SpecialCells(xlCellTypeVisible).Copy _
Destination:=Sheets("Summary").Range("A1")
Sin xlCellTypeVisible esto copia el bloque entero, filas ocultas incluidas, y pegas sin avisar
datos que el usuario había filtrado. Este es el puente entre el grupo de direccionamiento y el
trabajo real de filtrado: CurrentRegion encuentra el bloque, y SpecialCells(xlCellTypeVisible)
lo acota a las filas visibles. La misma idea borra las filas filtradas: filtra y luego
.Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete.
La trampa de las múltiples áreas: el resultado casi nunca es un rectángulo
Esto es lo que hace a SpecialCells distinto de todas las referencias anteriores: el rango que
devuelve normalmente no es contiguo. Diez celdas en blanco dispersas vuelven como una única
referencia formada por diez áreas separadas. Eso cambia cómo lo inspeccionas:
Dim vis As Range: Set vis = rng.SpecialCells(xlCellTypeVisible)
Debug.Print vis.Count ' total de celdas visibles en TODAS las areas
Debug.Print vis.Areas.Count ' cuantos bloques separados son
Dim a As Range
For Each a In vis.Areas
Debug.Print a.Address ' cada bloque contiguo, uno a uno
Next a
.Count es el total general de celdas; .Areas.Count es cuántos bloques inconexos forman. La
mayoría de las operaciones — fijar un valor, un color, un .Copy a otra hoja — manejan todas las
áreas a la vez, así que rara vez necesitas un bucle. La excepción es todo lo sensible al orden: si
borras filas encontradas por SpecialCells, borra .EntireRow en una sola llamada en lugar de
recorrerlas hacia arriba, porque no se garantiza que las áreas vayan de abajo arriba. Esta forma de
múltiples áreas la comparte con Union, que construye el mismo tipo de
referencia no contigua a propósito.
Cómo ayuda ExcelMaster
SpecialCells es potente precisamente porque es afilado: olvida la guarda On Error y un archivo
limpio hace fallar tu macro; olvida xlCellTypeVisible y copias las filas que un filtro estaba
ocultando; trata el resultado como un rectángulo y un bucle celda a celda cae en el orden
equivocado. Cada uno de esos es un fallo silencioso y circunstancial — funciona con tus datos y se
rompe con los de otra persona.
ExcelMaster te deja
describir el resultado en su lugar. Di «rellena cada celda en blanco de la columna A con el valor
que tiene encima» o «copia solo las filas visibles a una hoja de Resumen», y escribe por ti la
llamada SpecialCells protegida, la comprobación Is Nothing y el enrutado a solo lo visible — la
versión que sobrevive a un archivo sin celdas en blanco y a un filtro que oculta la mitad de las
filas. Te quedas con el libro y con el código; te ahorras el fallo en el primer caso límite.
Preguntas frecuentes
¿Por qué SpecialCells da un error de «No se encontraron celdas»?
Porque SpecialCells lanza error 1004 cuando ninguna celda de la región de búsqueda coincide
con el tipo que pediste — trata «sin coincidencias» como un error, no como un rango vacío. Una
región sin celdas en blanco pasada por SpecialCells(xlCellTypeBlanks) detendrá la macro. Envuelve
la llamada en On Error Resume Next, restaura con On Error GoTo 0, y comprueba
If Not result Is Nothing antes de usarla.
¿Cómo selecciono solo las celdas visibles tras aplicar un filtro en VBA?
Usa xlCellTypeVisible: rng.SpecialCells(xlCellTypeVisible). Tras un AutoFilter, las filas que el
filtro descarta quedan ocultas pero siguen formando parte del rango, así que un .Copy a secas las
incluye. Pasar por SpecialCells(xlCellTypeVisible) restringe la copia, el color o el borrado a las
filas que el usuario ve de verdad.
¿Cuál es la diferencia entre xlCellTypeConstants y xlCellTypeFormulas?
xlCellTypeConstants devuelve las celdas que contienen un valor escrito — números o texto que
introdujiste directamente. xlCellTypeFormulas devuelve las celdas que contienen una fórmula.
Ambas aceptan un segundo argumento opcional para acotar por tipo de resultado, así que
SpecialCells(xlCellTypeFormulas, xlErrors) devuelve solo las celdas de fórmula que ahora mismo
muestran un error como #REF! o #DIV/0!.
¿Cómo relleno todas las celdas en blanco de una vez con VBA?
Selecciona las celdas en blanco con SpecialCells(xlCellTypeBlanks) (protegido contra el error de
que no haya ninguna), y luego escribe en toda la selección en una sola instrucción. Para copiar el
valor de encima de cada hueco, usa gaps.FormulaR1C1 = "=R[-1]C" y después
gaps.Value = gaps.Value para congelar las fórmulas en valores estáticos. No hace falta ningún
bucle.
¿SpecialCells devuelve un rango contiguo?
Normalmente no. Las celdas en blanco o visibles que pides suelen estar dispersas, así que
SpecialCells devuelve una referencia de múltiples áreas. .Count es el número total de
celdas de todas las áreas, y .Areas.Count es cuántos bloques separados forman. La mayoría de las
operaciones manejan todas las áreas a la vez; recorre For Each a In result.Areas en un bucle solo
cuando necesites cada bloque contiguo por separado.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 16/08/2026.
Guías relacionadas: VBA Union · VBA Intersect · VBA AutoFilter · VBA CurrentRegion · VBA On Error
