🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

UsedRange frente a CurrentRegion en VBA en Excel — toma el bloque de datos completo (y en cuál confiar)

|

UsedRange frente a CurrentRegion en VBA en Excel — toma el bloque de datos completo (y en cuál confiar)

TL;DR — Ambos toman «el rectángulo entero», pero responden a preguntas distintas. Worksheet.UsedRange es 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.CurrentRegion es el bloque contiguo alrededor de una celda, calculado en vivo (lo mismo que selecciona Ctrl+Shift+*), y se detiene en la primera fila o columna totalmente en blanco. Para una sola tabla limpia, Range("A1").CurrentRegion es la opción fiable. Reserva UsedRange para «limpiar toda la hoja» y nunca leas UsedRange.Rows.Count como 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é UsedRange informa de más y se niega a encoger
  • Por qué UsedRange puede no empezar en A1: el error de confundir el recuento
  • Por qué CurrentRegion se 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 internasRange("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 cuenta Row + Count - 1 sobre UsedRange.
  • 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