TL;DR —
Join(sourceArray, delimiter)colapsa un array unidimensional en una sola cadena, poniendodelimiterentre cada elemento. Es el inverso exacto de Split: Split corta una cadena en un array, Join pega el array de vuelta. Reemplaza el bucles = s & item & ","— y, a diferencia de ese bucle, no deja ningún delimitador sobrante al final. La trampa: Join toma un array 1-D, no un Range y no un array 2-D, así queJoin(Range("A1:A10").Value, ",")falla hasta que aplanas la columna a 1-D primero.
Sub JoinDemo()
Dim parts As Variant, line As String
parts = Array("Jones", "Sarah", "Finance")
line = Join(parts, ",") ' pega con una coma entre cada uno
Debug.Print line ' Jones,Sarah,Finance <- sin coma al final
Debug.Print Join(parts) ' Jones Sarah Finance <- delimitador por defecto es un ESPACIO
Debug.Print Join(parts, "") ' JonesSarahFinance <- delimitador vacio = concatenar
End Sub
La firma — fíjate en que el delimitador es opcional y por defecto es un espacio, no nada:
Join(sourceArray, [delimiter])
' array 1-D por defecto " " (un espacio), no ""
Lo que aprenderás
- El modelo mental — Join es Split ejecutado al revés
- Por qué Join reemplaza el bucle de concatenación (y mata el bug del delimitador sobrante)
- La trampa número uno: Join necesita un array 1-D, así que un Range o un array 2-D falla
- El delimitador por defecto es un espacio, y cada elemento se convierte a texto
- El ida y vuelta Split-Filter-Join que convierte un bucle en una sola línea
El modelo mental: Join es Split, al revés
Sostén Split y Join como una pareja emparejada y ambos dejan de ser quisquillosos.
Split toma una cadena con la estructura ya incorporada — una línea CSV, un
Apellido,Nombre, una fila de log delimitada — y te entrega los campos como un array. Join hace lo
contrario: toma esos campos y los suelda de vuelta en una sola cadena con un separador de tu elección entre
ellos. Si Split es «des-concatenar», Join es «concatenar toda esta lista de una vez».
Como son inversos, se componen limpiamente. Separa una línea, cambia algunas piezas, y vuelve a unirla con Join:
Dim parts As Variant
parts = Split("Jones,Sarah,Finance", ",")
parts(2) = "Operations" ' edita un campo
Debug.Print Join(parts, ",") ' Jones,Sarah,Operations
Por qué Join gana al bucle de concatenación
Todo el mundo escribe el bucle de construcción de cadenas antes de conocer Join, y todo el mundo escribe el mismo bug:
' El bucle con el clasico bug del delimitador sobrante
Dim i As Long, s As String
For i = 0 To UBound(parts)
s = s & parts(i) & "," ' deja "Jones,Sarah,Finance," - coma al final
Next i
s = Left(s, Len(s) - 1) ' el truco feo para cortarla
Ese separador sobrante no es un caso límite raro — es cada vez, y por eso la amputación
Left(s, Len(s) - 1) es una imagen tan habitual. Join no tiene ese problema porque pone el delimitador
entre los elementos por diseño, nunca después del último:
s = Join(parts, ",") ' Jones,Sarah,Finance - correcto, a la primera
Una sola llamada, ningún carácter sobrante, ninguna aritmética Len - 1, y nada que estropear tampoco con
un array vacío (Join de un array vacío es simplemente "").
La trampa número uno: Join necesita un array 1-D, no un Range
De aquí vienen la mayoría de los reportes de «Join no funciona». Join acepta solo un array unidimensional. En cuanto le entregas algo bidimensional, falla — y leer un Range de varias celdas te da exactamente eso:
' FALLA - .Value de un rango de varias celdas es un array 2-D (10 filas x 1 col)
s = Join(Range("A1:A10").Value, ",") ' discrepancia de tipos / error 13
Range("A1:A10").Value no es una lista — es un array variant bidimensional de 10 x 1, y Join no tiene ni
idea de qué hacer con dos dimensiones. Debes aplanar la columna a 1-D primero. La forma idiomática de
aplanar es Application.Transpose, que descarta la dimensión unitaria de una sola columna:
Dim flat As Variant
flat = Application.Transpose(Range("A1:A10").Value) ' columna 2-D -> array 1-D
s = Join(flat, ",") ' ahora Join esta contento
Por eso Transpose está en este grupo — es el puente de las celdas al array 1-D
que Join y Filter requieren ambos. (Ojo con su propio límite: Application.Transpose tope en 65 536
elementos, así que aplana columnas muy altas con un bucle en su lugar.)
El delimitador por defecto y la coerción a texto
Dos sorpresas menores. Primero, si omites el delimitador, Join usa un espacio único, no una cadena
vacía — Join(parts) da "Jones Sarah Finance". Pasa "" explícitamente cuando quieras una concatenación
directa sin nada entre medias.
Segundo, Join fuerza cada elemento a texto. Los números, las fechas y los booleanos se convierten usando
la configuración regional de tu sistema — un Double puede mostrarse como 1.5 o 1,5 según la máquina, y
una fecha sigue el formato local. Si necesitas un formato concreto (un . decimal invariante, una fecha
ISO), formatea cada elemento con Format o CStr antes de hacer Join, en vez de
confiar en la configuración regional. Un elemento del array que sea un objeto o un variant sin inicializar
lanzará un error en lugar de convertirse.
La opinión: nunca vuelvas a construir una cadena delimitada en un bucle
Si estás concatenando elementos de un array con & dentro de un bucle For, estás escribiendo un bug que
luego parchearás con Left(s, Len(s) - 1). Join existe precisamente para eliminar ese patrón. La regla es
simple: siempre que la fuente ya sea un array, construye la cadena con Join; siempre que la fuente esté en
celdas, aplánala a un array 1-D primero, y luego haz Join — no hagas bucles.
Y ten presente la pareja como una tubería. Split, Filter, Join se componen en una sola expresión honesta que se lee como la frase que dirías en voz alta — «toma esta línea, conserva los campos que mencionan 2026, y únelos con comas»:
result = Join(Filter(Split(line, ","), "2026"), ", ")
Split analiza, Filter reduce a un subconjunto, Join reensambla — tres funciones integradas, sin bucle, sin errores por uno.
Cómo ayuda ExcelMaster
Unir nunca es el objetivo real. El objetivo es «construye la línea de asunto del correo a partir de estos campos», o «escribe una fila delimitada por registro en un log». Para cuando has aplanado el rango, has formateado cada número para que los decimales sobrevivan y has elegido el delimitador, la fontanería es más larga que la idea. ExcelMaster te deja describir la salida en español llano — «haz una lista separada por punto y coma de los nombres de cliente de cada región» — y genera Python que lee las celdas, las formatea de forma predecible y respalda tu archivo antes de escribir — tú describes la salida, y él se encarga del aplanado, los formatos numéricos y los delimitadores.
Preguntas frecuentes
¿Qué hace Join en VBA?
Join(sourceArray, delimiter) toma un array unidimensional y devuelve una sola cadena con delimiter
colocado entre cada elemento. Join(Array("a", "b", "c"), ",") devuelve "a,b,c". Es el inverso de
Split, y nunca deja un delimitador sobrante después del último elemento.
¿Por qué VBA Join da un type mismatch en un rango?
Porque Range("A1:A10").Value es un array bidimensional (filas por columnas), y Join acepta solo un array
unidimensional. Aplana la columna primero con Application.Transpose(Range("A1:A10").Value), que convierte
un array 2-D de una sola columna en un array 1-D, y luego pásaselo a Join.
¿Cuál es el delimitador por defecto en VBA Join?
Un espacio único. Join(parts) sin delimitador devuelve los elementos separados por espacios, no pegados.
Pasa una cadena vacía, Join(parts, ""), cuando quieras una concatenación directa sin nada entre los
elementos.
¿Cómo uno un array sin una coma sobrante en VBA?
Usa Join en lugar de un bucle. Join(parts, ",") pone la coma solo entre los elementos, así que nunca
hay un separador sobrante que quitar. El bucle s = s & item & "," siempre deja uno, y por eso la gente
luego lo corta con Left(s, Len(s) - 1) — Join elimina la necesidad por completo.
¿Puede VBA Join manejar números y fechas?
Sí, pero fuerza cada elemento a texto usando tu configuración regional, así que los decimales y los formatos
de fecha siguen la máquina local. Para un resultado predecible, formatea cada elemento con Format o CStr
antes de unir, en vez de confiar en la configuración regional. Los objetos o los variant sin inicializar en
el array provocan un error.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 03/09/2026.
Guías relacionadas: VBA Split · VBA Filter · VBA Transpose · VBA Format · VBA For Loop
