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

VBA Resize en Excel — redimensionar un rango desde su ancla (y por qué es un recuento, no un incremento)

|

VBA Resize en Excel — redimensionar un rango desde su ancla (y por qué es un recuento, no un incremento)

TL;DRResize(rows, columns) mantiene fija el ancla superior izquierda de un rango y vuelve a dibujar el rectángulo para que tenga exactamente esas filas de alto y esas columnas de ancho. No mueve la referencia (eso es Offset) y no selecciona — devuelve un rango nuevo en la misma esquina. La trampa: los argumentos son un recuento absoluto, con base 1, del tamaño final, no un incremento. Range("A1").Resize(5, 3) es A1:C5 (5 filas y 3 columnas en total); Resize(0, ...) lanza el error 1004. Omite un argumento para dejar esa dimensión sin cambios.

Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Data")
' El ancla se queda en A1; el rectangulo se redibuja a 5 filas por 3 columnas.
ws.Range("A1").Resize(5, 3).Select        ' selecciona A1:C5
' Omite el recuento de columnas para conservar el ancho y solo crecer en alto:
ws.Range("A1:D1").Resize(10).Select       ' A1:D10 (el ancho se queda en 4)

Resize es la forma en que una macro deja de codificar a mano "A1:D100" y empieza a ajustar la referencia a lo que los datos son de verdad. Es un método pequeño con un gran malentendido pegado: la gente lee Resize(5) como «suma cinco filas» cuando significa «ten cinco filas». Esta guía se construye sobre la idea de la que se desprende cada regla posterior: Resize fija el ancla y declara el tamaño final. Ten eso claro y la regla de recuento-no-incremento, los argumentos omitidos y el modismo de quitar el encabezado dejan todos de ser sorpresas.

Lo que aprenderás

  • El modelo mental — Resize fija el ancla superior izquierda y vuelve a dibujar el rectángulo
  • La regla más importante — los argumentos son un recuento total, no un incremento que sumar
  • Omitir un argumento para dejar una dimensión sin cambios
  • Por qué el ancla es siempre la superior izquierda, incluso en un rango de varias celdas
  • Los dos patrones que valen la pena — quitar un encabezado y escribir una matriz en un bloque a medida
  • Dónde encaja Resize junto a Offset y CurrentRegion

El modelo mental: Resize fija el ancla y vuelve a dibujar el rectángulo

Todo rango tiene una celda superior izquierda — su ancla. Resize deja esa ancla exactamente donde está y vuelve a dibujar el rectángulo con el tamaño que le des:

ws.Range("B2").Resize(3, 4)   ' el ancla B2 se queda; el rango nuevo es B2:E4 (3 filas, 4 columnas)

Imagina agarrar el tirador inferior derecho de una selección y arrastrar: la esquina superior izquierda queda clavada y el tamaño cambia bajo tu mano. Ese es todo el método. Dos cosas que no es: no es Offset, que desliza la referencia entera a una posición nueva sin cambiar su tamaño; y no es una selección ni una acción — Resize devuelve un rango, y tienes que usar el resultado (.Value =, .Select, Set r = ...). Una llamada a Resize sola en una línea no hace absolutamente nada.

La regla más importante: es un recuento, no un incremento

Este es el malentendido que produce rangos del tamaño equivocado. Resize(rows, columns) es el total absoluto, con base 1, del rectángulo final — no una cantidad que sumar al tamaño actual:

ws.Range("A1").Resize(5, 3)   ' A1:C5  -> 5 filas y 3 columnas EN TOTAL, no "5 filas mas"
ws.Range("A1").Resize(1, 1)   ' A1     -> una sola celda (1 fila, 1 columna)

Así que Resize(1) es una fila, no «encoge en uno». Y como un rango no puede tener tamaño cero ni negativo, Resize(0, 3) o Resize(-1, 3) lanza el error 1004 en tiempo de ejecución. Si estás calculando un número de filas, protégelo: un bloque de datos con solo la fila de encabezado da Rows.Count - 1 = 0, y pasarle eso a Resize provoca un fallo. Comprueba el caso vacío antes de redimensionar.

Omite un argumento para dejar una dimensión sin tocar

Los dos argumentos son opcionales, y omitir uno significa «deja esa dimensión sin cambios». Este es el uso más común en el mundo real — fija un lado, cambia el otro:

ws.Range("A1:D1").Resize(10)        ' filas -> 10, las columnas se quedan en 4  => A1:D10
ws.Range("A1:D1").Resize(, 6)       ' columnas -> 6, las filas se quedan en 1   => A1:F1

Fíjate en la coma suelta de Resize(, 6) — así es como te saltas el primer argumento y fijas solo el segundo. Leer Resize(10) como «10 filas, mismo ancho» es exactamente correcto, y es la razón de que convertir una fila de encabezado en una tabla entera sea una sola línea.

El ancla es siempre la superior izquierda

Resize calcula desde el ancla e ignora el tamaño existente salvo esa esquina. Llámalo sobre un rango de varias celdas y las dimensiones antiguas desaparecen:

ws.Range("B2:D10").Resize(1, 1)   ' colapsa a B2 - solo el ancla

Eso sorprende a quienes esperan que Resize ajuste su bloque existente en relación con su tamaño actual. No lo hace — replantea el tamaño desde la superior izquierda. Si quieres reformar desde la primera celda de un rango a propósito, eso es justo lo que pasa; si lo llamaste sobre un rango grande por accidente, acabas de tirar el tamaño a la basura. Cuando necesites el ancla de forma explícita, rng.Cells(1, 1) (ver VBA Cells) te da la celda superior izquierda desde la que redimensionar.

Los dos patrones que valen la pena

Casi todo Resize útil es uno de estos dos. Primero, quitar una fila de encabezado — combínalo con Offset, porque Offset por sí solo conserva la misma altura y se derramaría una fila más allá del fondo:

Dim tbl As Range: Set tbl = ws.Range("A1").CurrentRegion   ' bloque entero, encabezado incluido
Dim body As Range
' Baja mas alla del encabezado y LUEGO encoge la altura en uno para que no se pase:
Set body = tbl.Offset(1, 0).Resize(tbl.Rows.Count - 1, tbl.Columns.Count)

Offset mueve, Resize reforma — juntos recortan el cuerpo de datos de un bloque. Segundo, escribir una matriz en un bloque que la ajuste. Asignar una matriz a una sola celda sin redimensionar rellena solo esa celda; primero redimensiona el ancla a las dimensiones de la matriz:

Dim data(1 To 100, 1 To 3) As Variant
' ... rellena data ...
ws.Range("A1").Resize(UBound(data, 1), UBound(data, 2)).Value = data   ' rellena A1:C100 de una vez

Esa única asignación es órdenes de magnitud más rápida que recorrer celda a celda, y Resize es lo que hace que el destino cuadre exactamente con los datos.

Offset mueve, Resize reforma

Ten claro el par y los rangos dinámicos dejan de ser un engorro: Offset cambia dónde está una referencia; Resize cambia cómo de grande es. Reposicionas con uno y reformas con el otro, y casi todo el trabajo real usa los dos — encuentra un ancla, desplázate más allá de lo que quieres saltar, redimensiona para ajustar lo que queda. Combina eso con CurrentRegion para detectar el bloque en primer lugar y tienes el kit completo para referirte a datos cuyo tamaño no conoces de antemano — sin escribir jamás una dirección codificada a mano que se rompe el día en que los datos crecen una fila. La forma vive en los datos; Resize solo ajusta la referencia a ella.

Cómo ayuda ExcelMaster

Resize esconde un puñado de trampas silenciosas: el malentendido de recuento-frente-a-incremento que produce un bloque del tamaño equivocado, un error 1004 cuando un número de filas calculado llega a cero, un ancla que descarta tu tamaño existente, y la asignación de matriz que rellena una sola celda porque el destino nunca se redimensionó. Ninguna de ellas lanza un mensaje útil en el momento en que las cometes.

ExcelMaster te deja describir el resultado en su lugar. Di «escribe esta tabla en la hoja empezando en A1» o «selecciona los datos sin la fila de encabezado», y redimensiona el ancla a las dimensiones exactas de la matriz, o se desplaza más allá del encabezado y encoge la altura en uno — protegiendo el caso del bloque vacío para que nada falle. Te quedas con el libro y con el código; te ahorras la pasada de depuración en la que solo se rellenó la primera celda.

Preguntas frecuentes

¿Qué hace Resize en Excel VBA?

Resize(rows, columns) devuelve un rango nuevo que conserva la celda superior izquierda del rango original (su ancla) y mide exactamente rows de alto y columns de ancho. No mueve la referencia y no selecciona nada por sí mismo — usas el rango devuelto, por ejemplo Range("A1").Resize(10, 3).Value = data.

¿Resize es un incremento o un tamaño absoluto?

Es un recuento absoluto, con base 1, del tamaño final, no una cantidad que sumar. Range("A1").Resize(5, 3) es A1:C5 (cinco filas y tres columnas en total), y Resize(1, 1) es una sola celda. Como un rango no puede estar vacío, Resize(0, ...) o un recuento negativo lanza el error 1004 en tiempo de ejecución.

¿Cuál es la diferencia entre Resize y Offset en VBA?

Offset mueve un rango a una posición nueva sin cambiar su tamaño; Resize cambia el tamaño manteniendo fija el ancla superior izquierda. Son complementarios y a menudo se usan juntos, como en rng.Offset(1, 0).Resize(rng.Rows.Count - 1, rng.Columns.Count) para saltar una fila de encabezado y luego recortar la altura para que el resultado no se pase.

¿Cómo escribo una matriz en un rango con Resize?

Redimensiona la celda ancla para que coincida con las dimensiones de la matriz y luego asigna en una sola instrucción: Range("A1").Resize(UBound(data, 1), UBound(data, 2)).Value = data. Asignar una matriz a una sola celda sin redimensionar rellena solo esa celda, así que el Resize es lo que hace que todo el bloque reciba los datos, y es mucho más rápido que un bucle celda a celda.

¿Cómo redimensiono solo el número de filas y conservo las columnas?

Omite el segundo argumento: Range("A1:D1").Resize(10) fija la altura en 10 filas y deja el ancho en 4, dando A1:D10. Para cambiar solo las columnas, sáltate el primer argumento con una coma suelta: Range("A1:D1").Resize(, 6) da A1:F1.

Probado en

Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 15/08/2026.

Guías relacionadas: VBA Offset · VBA CurrentRegion · VBA Cells · VBA Range · VBA Bucle For