Probado en: Excel 365 v2509 · Excel 2021 · Excel 2019 · última verificación 05/06/2026
En resumen — Una matriz (array) es una variable con muchos compartimentos. La jugada clave en Excel VBA: leer un rango entero en una matriz, trabajar en memoria y reescribir una sola vez — en lugar de tocar las celdas una a una:
Sub ActualizacionRapida()
Dim arr As Variant
arr = Range("A2:C10000").Value2 ' UNA lectura -> matriz 2D
Dim i As Long
For i = 1 To UBound(arr, 1)
arr(i, 3) = arr(i, 2) * 1.1 ' trabajar en memoria (instantáneo)
Next i
Range("A2:C10000").Value2 = arr ' UNA escritura
End Sub
En 10.000 filas es la diferencia entre ~8 segundos y ~0,1. El resto de la guía construye esa línea y sus trampas.
Por qué matrices — y qué son
Una variable normal guarda un valor. Una matriz guarda una lista de valores bajo un solo nombre, accesible por índice:
Dim notas(1 To 3) As Long
notas(1) = 90
notas(2) = 75
notas(3) = 60
¿Para qué molestarse? Velocidad y estructura. Cada vez que VBA lee o escribe una celda cruza una frontera lenta entre el código y Excel. Una matriz vive en memoria, así que recorrer 10.000 compartimentos es miles de veces más rápido que recorrer 10.000 celdas.
Ejemplo 1 — Matrices estáticas y la base del índice
Una matriz estática tiene un tamaño fijo que defines al declararla. Indica los límites de forma explícita para no adivinar:
Dim meses(1 To 12) As String ' índices 1..12 — legible
Dim baseCero(0 To 9) As Double ' índices 0..9
Consejo: escribe siempre
(1 To n)en vez de(n).Dim a(10)crea en realidad 11 compartimentos (0–10), salvo que pongasOption Base 1. El(1 To 10)explícito elimina toda duda.
Ejemplo 2 — Matrices dinámicas con ReDim
Cuando no conoces el tamaño de antemano, declara una matriz vacía y dimensiónala luego con ReDim:
Dim nombres() As String
Dim n As Long
n = Cells(Rows.Count, 1).End(xlUp).Row - 1 ' filas de datos
ReDim nombres(1 To n) ' dimensionar ahora
Dim i As Long
For i = 1 To n
nombres(i) = Cells(i + 1, 1).Value
Next i
Un ReDim simple borra el contenido. Para conservar lo existente, usa ReDim Preserve.
Ejemplo 3 — ReDim Preserve (y su gran trampa)
ReDim Preserve cambia el tamaño sin perder datos — perfecto para una lista que crece:
Dim aciertos() As String
Dim cuenta As Long
cuenta = 0
Dim celda As Range
For Each celda In Range("A2:A100")
If celda.Value <> "" Then
cuenta = cuenta + 1
ReDim Preserve aciertos(1 To cuenta) ' crecer de uno, conservar el resto
aciertos(cuenta) = celda.Value
End If
Next celda
La trampa: en una matriz 2-D,
ReDim Preservesolo puede redimensionar la última dimensión.ReDim Preserve rejilla(1 To 5, 1 To 10)vale si solo cambia el10; cambiar el5lanza «Subíndice fuera del intervalo». Solución: pon el eje que crece al final, o transpón.
Ejemplo 4 — UBound y LBound (nunca codifiques el tamaño a mano)
Pregunta a la matriz por su tamaño en vez de suponerlo:
Dim arr As Variant
arr = Array("Lun", "Mar", "Mié") ' una matriz base 0
Dim i As Long
For i = LBound(arr) To UBound(arr) ' sea cual sea la base
Debug.Print arr(i)
Next i
Para una matriz 2-D desde un rango, indica la dimensión: UBound(arr, 1) es el número de filas, UBound(arr, 2) el de columnas.
Ejemplo 5 — Leer un rango en una matriz (el truco 100×)
Esta es toda la razón de aprender matrices. UnRango.Value2 te entrega, en una sola lectura, una matriz bidimensional con base 1:
Sub SumarColumnaRapido()
Dim arr As Variant
arr = Range("A2:C10000").Value2 ' arr(fila, columna), ambos base 1
Dim total As Double, i As Long
For i = 1 To UBound(arr, 1)
total = total + arr(i, 2) ' columna 2 = Cantidad
Next i
MsgBox "Cantidad total: " & total
End Sub
Dos cosas que recordar:
- El resultado siempre es base 1 —
arr(1, 1)es la celda superior izquierda, sin importarOption Base. - Una sola celda no devuelve una matriz.
Range("A1").Value2es solo el valor; solo un rango multicelda se convierte en matriz 2-D.
Ejemplo 6 — Recorrer una matriz con For Each
Cuando solo te importan los valores (no su posición), For Each se lee mejor:
Dim regiones As Variant
regiones = Array("Norte", "Sur", "Este", "Oeste")
Dim r As Variant
For Each r In regiones
Debug.Print r
Next r
Ejemplo 7 — Construir matrices rápido con Array() y Split()
Dos líneas que ahorran un montón de asignaciones:
' Array() — una lista literal rápida (base 0)
Dim dias As Variant
dias = Array("Lun", "Mar", "Mié", "Jue", "Vie")
' Split() — convertir texto con separador en matriz (base 0)
Dim partes As Variant
partes = Split("manzana;plátano;cereza", ";")
Debug.Print partes(0) ' manzana
Debug.Print UBound(partes) ' 2 (tres elementos, 0..2)
Join(partes, ", ") hace lo contrario — de matriz a cadena.
Errores frecuentes con matrices (y la solución)
| Síntoma | Causa | Solución |
|---|---|---|
«Subíndice fuera del intervalo» en arr(i) |
i está fuera de LBound..UBound |
Recorrer LBound(arr) To UBound(arr) |
| La matriz tiene un compartimento vacío de más | Dim a(10) hizo 0..10 = 11 compartimentos |
Declarar (1 To 10) |
ReDim Preserve falla en una matriz 2-D |
Solo la última dimensión puede crecer | Poner el eje que crece al final, o transponer |
Range("A1").Value2 no es una matriz |
Una sola celda devuelve un escalar | Leer un rango multicelda |
| Datos reescritos desplazados | El rango de escritura tiene otro tamaño que arr |
Escribir en un rango exactamente del tamaño de la matriz |
Olvida la fontanería de matrices — describe la transformación
Las matrices son rápidas, pero ReDim Preserve, UBound(arr, 2) y la contabilidad base-1-frente-a-base-0 son justo el detalle que convierte cinco minutos en una tarde. ExcelMaster Agent te deja enunciar el objetivo — «carga toda la tabla, sube cada precio un 10 % y reescríbela» — y genera el patrón leer-en-matriz / procesar / reescribir, con los límites correctos. Pruébalo gratis →
Guías relacionadas
- VBA Range en Excel — referenciar, leer y escribir celdas
- VBA Dictionary en Excel — búsquedas, eliminar duplicados y agrupar
- VBA For en Excel — 8 ejemplos reales
Preguntas frecuentes
¿Qué hace una matriz en VBA?
Una matriz guarda muchos valores del mismo tipo bajo un solo nombre, accesibles por índice (arr(1), arr(2)…). Permite leer y procesar una lista de datos en memoria, mucho más rápido que leer esos mismos datos celda por celda.
¿Cómo uso una matriz en vez de un rango en Excel VBA?
Lee el rango en una matriz de una vez — arr = Range("A1:C10000").Value2 — recórrela con UBound y reescríbela con Range(...).Value2 = arr. Eso reemplaza miles de accesos lentos por una lectura y una escritura.
¿Cuál es la diferencia entre ReDim y ReDim Preserve?
ReDim cambia el tamaño de una matriz dinámica y borra su contenido. ReDim Preserve cambia el tamaño y conserva los valores — pero en una matriz 2-D solo puede cambiar la última dimensión.
¿Por qué mi matriz VBA es base 0?
Las matrices de Array() y Split() empiezan en el índice 0 por defecto (salvo Option Base 1). Las matrices leídas de un rango (.Value2) siempre son base 1. Recorre LBound(arr) To UBound(arr) y la base deja de importar.
¿Cómo obtengo la longitud de una matriz VBA?
Con UBound(arr) - LBound(arr) + 1. Para una matriz 2-D desde un rango, el número de filas es UBound(arr, 1) y el de columnas UBound(arr, 2).
