TL;DR — VBA le ofrece dos operadores que parecen unir texto por igual:
&y+. Solo uno es seguro.&siempre trata ambos lados como texto: convierte los números en sus dígitos y trataNullcomo una cadena vacía.+hace aritmética cuando ve números y se vuelve contagioso cuando veNull(un soloNullconvierte todo el resultado enNull). Regla sin excepciones: use¶ construir cadenas y reserve+para los cálculos. Y cuando esté pegando miles de fragmentos dentro de un bucle, deje de usars = s & x: eso es O(n²). En su lugar, apliqueJoinsobre un array.
La concatenación es lo que más se hace con texto en VBA: armar un nombre de
archivo, un mensaje, una cadena SQL, el título de un informe. Parece trivial,
hasta que un número o una celda en blanco convierte su "Total: " + value en un
número equivocado o en un Null silencioso, y el error llega a producción porque
nada falló de forma visible.
Lo que aprenderás
- Por qué
&es el único operador de concatenación en el que debe confiar (y qué hace+en realidad) - La trampa de
Nullque hace que+anule una expresión entera - Por qué
s = s & itemdentro de un bucle es, en secreto, O(n²), y cómo lo resuelveJoin - El hábito del espacio en blanco que evita el error de
&como carácter de tipo
El modelo mental: & es pegamento, + es un pegamento falsificado que te traiciona
Imagine & como un tubo de pegamento con la etiqueta «solo texto». Le pase lo
que le pase —una cadena, un número, una fecha, incluso un valor en blanco—, lo
fuerza a texto y lo adhiere al final. + es un tubo de aspecto idéntico, pero su
etiqueta dice «primero las matemáticas». Cuando ambos lados resultan ser
cadenas, pega. En cuanto uno de los lados es un número o un Null, deja de ser
pegamento y hace aritmética, y usted no se entera hasta que la salida está mal.
Sub TwoOperators()
' & siempre concatena como texto
Debug.Print "Item " & 5 ' -> "Item 5" (el número se fuerza a texto)
Debug.Print "5" & "5" ' -> "55" (pegado)
' + hace matemáticas en cuanto interviene un número
Debug.Print "5" + "5" ' -> "55" ... pero solo porque ambos son TEXTO
Debug.Print 5 + 5 ' -> 10 (aritmética)
Debug.Print "Item " + 5 ' -> run-time error 13: Type mismatch
End Sub
Esa última línea es la prueba: "Item " + 5 revienta porque + intenta sumar un
número a una cadena. & nunca tiene este problema: "Item " & 5 simplemente
funciona.
La regla que evita el peor error de concatenación: la trampa de Null
Aquí está el modo de fallo que de verdad corrompe los datos. Cuando lee un valor
desde un recordset de base de datos, un variant vacío o una celda que regresó como
Null, los dos operadores se comportan de manera opuesta:
Sub TheNullTrap()
Dim middleName As Variant
middleName = Null ' p. ej., un campo vacío de ADO
' & trata Null como una cadena vacía — seguro
Debug.Print "Anna " & middleName & " Smith" ' -> "Anna Smith"
' + es contagioso: UN solo Null envenena toda la expresión
Debug.Print "Anna " + middleName + " Smith" ' -> Null (todo desaparece)
End Sub
Con +, un único Null en cualquier punto de la cadena convierte el resultado
entero en Null. Si luego escribe eso en una celda, obtiene un hueco en
blanco donde debería ir un nombre, y ningún error que le explique por qué. Esta es
la causa número uno de esos informes de «mi concatenación produce celdas vacías al
azar». El arreglo no consiste en comprobar Null en cada valor. El arreglo es
no usar nunca + para construir una cadena. Reserve + para los casos en que
genuinamente quiera que el Null se propague como una señal, lo cual, en la
práctica, casi nunca ocurre.
El hábito del espacio en blanco: & también es un carácter de declaración de tipo
Un detalle sutil que muerde a quien escribe código compacto. En VBA, & añadido a
un nombre de variable es el viejo sufijo de declaración de tipo para Long (como
$ lo es para String). Así que, si pega & contra un nombre sin dejar espacio,
el analizador puede interpretarlo como un carácter de tipo en lugar del operador de
concatenación:
total = count&"x" ' ambiguo — el VBE puede leer count& como un Long
total = count & "x" ' inequívoco — siempre es concatenación
Ponga siempre espacios alrededor de &. No es algo cosmético: elimina una
ambigüedad de análisis real y hace legibles las concatenaciones largas. Use
vbNewLine, vbCrLf y vbTab como constantes entre fragmentos en lugar de
escribir a mano Chr(10):
msg = "Line one" & vbNewLine & "Line two" & vbTab & "(indented)"
Por qué tu concatenación va lenta: el bucle O(n²)
Este es el criterio de rendimiento que separa una macro que termina en un
parpadeo de otra que se cuelga durante 30 segundos. Las cadenas de VBA son
inmutables: cada s = s & item reserva una cadena completamente nueva y copia
todo lo que había antes. Haga eso 10 000 veces dentro de un bucle y habrá copiado
la cadena creciente 10 000 veces: el clásico O(n²).
' LENTO — reconstruye toda la cadena en cada iteración (O(n²))
Dim s As String, i As Long
For i = 1 To 10000
s = s & data(i) & ","
Next i
' RÁPIDO — recolecta en un array y pega de una vez con Join (O(n))
Dim parts() As String
ReDim parts(1 To 10000)
For i = 1 To 10000
parts(i) = data(i)
Next i
s = Join(parts, ",") ' una sola reserva
Join es la operación inversa de Split: toma un array y un
delimitador y devuelve una sola cadena en una única reserva de memoria. Para
cualquier cosa que pase de unos pocos cientos de iteraciones, armar un array y
llamar a Join una vez es muchísimo más rápido —y se lee mejor— que ir
acumulando con &.
El criterio de decisión: para un puñado de fragmentos, & es perfecto y Join
sería excesivo. Para un bucle que construye una cadena grande, eche mano de Join
siempre.
Concatenar un rango de celdas
Una petición muy habitual: pegar una columna de celdas en una sola cadena
delimitada. No recorra celda por celda si puede evitarlo: el propio TEXTJOIN de
Excel (disponible mediante WorksheetFunction) lo hace en una sola llamada y, de
paso, omite las celdas en blanco por usted:
Sub JoinAColumn()
Dim result As String
' TEXTJOIN(delimitador, ignorar_vacías, rango)
result = WorksheetFunction.TextJoin(", ", True, Range("A1:A50"))
Debug.Print result
End Sub
Si de verdad necesita un bucle de VBA (versiones antiguas de Excel sin
TEXTJOIN), lea primero el rango en un array de tipo variant, construya un array
String y aplique Join: nunca toque la hoja de cálculo 50 veces dentro del
bucle.
Cómo ayuda ExcelMaster
Mucho código VBA de concatenación existe para ensamblar una sola cosa: una
exportación limpia —una línea de CSV, una etiqueta con formato, una clave para
emparejar—. ExcelMaster construye eso a partir de una descripción en lenguaje
natural: «crea una columna clave a partir del ID de cliente más la fecha de
pedido, separados por comas», y se encarga de los valores en blanco, los tipos y
los delimitadores sin que usted tenga que razonar sobre & frente a + ni sobre
la propagación de Null.
Seguirá escribiendo VBA cuando la concatenación viva dentro de una macro siempre activa. Pero para tareas puntuales del tipo «cose estas columnas en una exportación», describir la salida es más rápido que acertar con los operadores a mano.
Preguntas frecuentes
¿Cuál es la diferencia entre & y + en VBA?
& siempre concatena como texto: fuerza los números a sus dígitos y trata Null
como una cadena vacía. + hace aritmética cuando interviene un número y propaga
Null (un solo Null convierte toda la expresión en Null). Use & para
construir cadenas y + solo para cálculos.
¿Cómo añado un salto de línea en una cadena concatenada?
Inserte la constante vbNewLine (o vbCrLf) entre los fragmentos:
"Line 1" & vbNewLine & "Line 2". Para un tabulador, use vbTab. Estas
constantes se leen mejor y son más portables que escribir a mano Chr(13) y
Chr(10).
¿Por qué mi concatenación de cadenas en VBA va tan lenta?
Casi con seguridad está acumulando con s = s & x dentro de un bucle grande, lo
cual es O(n²) porque VBA reconstruye toda la cadena cada vez. Recolecte los
fragmentos en un array String y llame a Join(parts, delimiter) una sola vez.
¿Cómo concateno un rango de celdas en VBA?
Use WorksheetFunction.TextJoin(delimitador, ignorar_vacías, rango) para una
solución de una sola línea que, además, omite las celdas en blanco. Recurra a un
bucle solo en versiones antiguas de Excel que carezcan de TEXTJOIN y, aun así,
lea el rango en un array y aplique Join en lugar de recorrer celda por celda.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación 14-06-2026.
Guías relacionadas: VBA UCase & LCase · VBA Str · VBA Split · VBA CStr · VBA For Loop
