TL;DR — Ambos toman «el rectángulo entero», pero responden a preguntas distintas.
Worksheet.UsedRangees todo lo que Excel ha tocado alguna vez: un recuadro delimitador en caché que incluye las celdas que solo tienen formato y no encoge cuando borras datos, así que informa de más.Range.CurrentRegiones el bloque contiguo alrededor de una celda, calculado en vivo (lo mismo que seleccionaCtrl+Shift+*), y se detiene en la primera fila o columna totalmente en blanco. Para una sola tabla limpia,Range("A1").CurrentRegiones la opción fiable. ReservaUsedRangepara «limpiar toda la hoja» y nunca leasUsedRange.Rows.Countcomo si fuera el número de la última fila.
Una vez que sabes encontrar la última fila, la siguiente pregunta suele ser «dame el bloque entero de una vez para poder recorrerlo, copiarlo o darle formato». VBA tiene dos funciones integradas que parecen intercambiables y no lo son. Elegir mal es el origen de dos de los errores de macro más habituales: procesar cientos de filas fantasma y leer un recuento de filas como si fuera un número de fila.
Lo que aprenderás
- El modelo mental: un recuadro delimitador en caché frente a un bloque contiguo en vivo
- Por qué
UsedRangeinforma de más y se niega a encoger - Por qué
UsedRangepuede no empezar en A1: el error de confundir el recuento - Por qué
CurrentRegionse detiene en las filas en blanco, y cuándo eso es justo lo que quieres - Una regla clara sobre cuál usar para cada tarea
El modelo mental: una instantánea caduca frente a una medición en vivo
UsedRange es una instantánea que Excel guarda para sí mismo. Es el rectángulo
más pequeño que ha llegado a encerrar todo lo que hiciste en la hoja: escribir un
valor, aplicar un borde, poner un relleno. Excel la guarda en caché y la actualiza
con pereza, así que va por detrás de la realidad: crece con ganas y encoge a
regañadientes.
CurrentRegion es una medición en vivo tomada desde donde estás plantado. Dale
una celda y se expande hacia fuera —arriba, abajo, izquierda, derecha— hasta topar
con una fila o columna completamente en blanco por cada lado. Es la versión en
código de hacer clic en una celda y pulsar Ctrl+Shift+* (o Ctrl+A una vez). No
hay nada en caché; se calcula en el instante en que lo pides.
Sub GrabTheBlock()
Dim ws As Worksheet
Set ws = ActiveSheet
Debug.Print ws.UsedRange.Address ' recuadro delimitador en caché de la hoja
Debug.Print ws.Range("A1").CurrentRegion.Address ' bloque en vivo alrededor de A1
End Sub
Esa diferencia —en caché y pegajosa frente a en vivo y local— explica todas las trampas que vienen a continuación.
La regla que evita el error de las filas fantasma: UsedRange informa de más
El modo de fallo que más tiempo hace perder: recorres UsedRange y procesas
muchísimas más filas de las que tienes de datos, porque UsedRange cuenta celdas
que solo llevan formato. Pon un borde en A1000 una vez, borra el valor y A1000
sigue viviendo dentro de UsedRange. Peor aún, borrar el contenido de las filas
no encoge UsedRange: Excel mantiene el recuadro delimitador antiguo hasta que se
guarda el libro o fuerzas un reinicio.
' UsedRange puede ser mucho más grande que tus datos reales
Dim r As Range
For Each r In ws.UsedRange.Rows
' ...esto puede recorrer cientos de filas vacías que solo tienen formato
Next r
Si tienes que usar UsedRange después de editar mucho, obliga a Excel a
recalcularlo leyéndolo una vez, o reinícialo explícitamente:
Dim junk As Range
Set junk = ws.UsedRange ' tocarlo empuja a que se refresque
La lección de fondo: UsedRange responde a «¿qué ha tocado Excel?», no a «¿dónde
están mis datos?». Son preguntas distintas, y solo a veces tienen la misma
respuesta.
La regla sobre recuentos frente a números: UsedRange puede no empezar en A1
El segundo error clásico. Si tus datos empiezan en C5, entonces UsedRange también
empieza en C5, no en A1. Así que su .Rows.Count es la altura del bloque, no el
número de la última fila, y .Cells(1, 1) es C5, no A1.
' Los datos viven en C5:F20
ws.UsedRange.Rows.Count ' -> 16 (un RECUENTO: filas 5 a 20)
ws.UsedRange.Row ' -> 5 (donde empieza)
' número de última fila = primera fila + recuento - 1
ws.UsedRange.Row + ws.UsedRange.Rows.Count - 1 ' -> 20 (la última fila real)
Leer UsedRange.Rows.Count como «la última fila» solo es correcto cuando los datos
resultan empezar en la fila 1. No te fíes de esa coincidencia: o haces la cuenta
Row + Count - 1, o usas .End(xlUp) para obtener un número de última fila de
verdad.
La regla sobre la contigüidad: CurrentRegion se detiene en los blancos
CurrentRegion toma una única isla contigua. Una sola fila o columna totalmente
en blanco es un muro que no cruza. Eso es una virtud cuando tu hoja tiene una tabla
rodeada de espacio vacío: obtienes exactamente esa tabla, empezando en su verdadera
esquina superior izquierda, sin filas fantasma:
Dim block As Range
Set block = ws.Range("A1").CurrentRegion ' encabezado + todos los datos contiguos
Pero es una trampa cuando tus datos tienen una fila separadora en blanco intencionada
(un hueco de subtotales, un divisor visual): CurrentRegion devuelve solo el trozo
que toca tu celda semilla y se salta el resto en silencio. Y la celda semilla tiene
que estar dentro del bloque: Range("A1").CurrentRegion, cuando A1 está en blanco,
devuelve solo A1.
El criterio de decisión: cuál y cuándo
- Una tabla limpia con encabezado y sin filas en blanco internas →
Range("A1").CurrentRegion. En vivo, empieza en la verdadera esquina superior izquierda, honesta con los huecos, sin filas fantasma. Es la opción por defecto para «tomar mi tabla». - «Limpiar / reiniciar / dar formato a toda la hoja» →
ws.UsedRange. Informar de más es inofensivo —incluso útil— cuando estás borrando o quitando formato. - «¿Cuántas filas de datos tengo?» → ninguno de los dos directamente. Usa la
detección de última fila (
.End(xlUp)o.Find) de la guía de la última fila, o haz la cuentaRow + Count - 1sobreUsedRange. - Datos con filas separadoras en blanco intencionadas → nada de
CurrentRegion(se detiene en el primer hueco). Encuentra la última fila real y construye el rango de forma explícita.
Dicho de forma sencilla: CurrentRegion para leer una tabla, UsedRange para
vaciar una hoja y la detección de última fila para contar filas.
Cómo ayuda ExcelMaster
Tomar el bloque siempre es un medio para un fin: ordenarlo, quitar duplicados, copiarlo, resumirlo. ExcelMaster toma ese objetivo final en lenguaje natural —«limpia toda la tabla de pedidos y elimina las filas duplicadas»— y selecciona los datos de la forma robusta, para que nunca entregues una macro que recorra 900 filas vacías con formato ni confunda un recuento de filas con un número de fila.
Seguirás escribiendo CurrentRegion dentro de una macro programada. Pero para
trabajos puntuales del tipo «opera sobre toda mi tabla», describir la operación te
evita toda la decisión entre UsedRange y CurrentRegion, y sus dos errores famosos.
Preguntas frecuentes
¿Cuál es la diferencia entre UsedRange y CurrentRegion en VBA?
UsedRange es un recuadro delimitador en caché a nivel de hoja de todas las celdas
que Excel ha tocado alguna vez, incluidas las que solo tienen formato; informa de
más y no encoge hasta que se guarda. CurrentRegion se calcula en vivo alrededor de
una celda concreta y se expande hasta topar con una fila o columna en blanco, así
que devuelve un único bloque contiguo. Usa CurrentRegion para leer una tabla y
UsedRange para vaciar una hoja.
¿Por qué mi UsedRange es más grande que mis datos?
Porque UsedRange cuenta celdas que solo tienen formato (bordes, rellenos) y no
encoge cuando borras valores: Excel mantiene el recuadro delimitador antiguo hasta
que se guarda el archivo. Elimina por completo las filas o columnas sobrantes, o usa
Range("A1").CurrentRegion para obtener solo los datos contiguos.
¿UsedRange siempre empieza en la celda A1?
No. UsedRange empieza en la esquina superior izquierda del área usada, así que si
tus datos empiezan en C5, empieza en C5. Por eso UsedRange.Rows.Count es un
recuento de filas, no el número de la última fila: calcula la última fila como
UsedRange.Row + UsedRange.Rows.Count - 1.
¿Por qué CurrentRegion se salta parte de mis datos?
CurrentRegion solo toma el bloque contiguo alrededor de la celda semilla, y se
detiene en cualquier fila o columna totalmente en blanco. Si tus datos tienen una
fila separadora en blanco intencionada, CurrentRegion devuelve solo el trozo que
toca tu celda. Usa la detección de última fila y construye el rango de forma
explícita para datos con huecos internos.
¿Cómo selecciono toda la tabla de datos en VBA?
Para una sola tabla limpia, Range("A1").CurrentRegion.Select toma el encabezado
más todos los datos contiguos, empezando en la verdadera esquina superior izquierda.
Asegúrate de que la celda semilla esté dentro de la tabla: una semilla en blanco
devuelve solo esa celda.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 30/07/2026.
Guías relacionadas: VBA Última fila · VBA Offset · VBA Range · VBA For Loop
