TL;DR — Para Word, un documento es una larga tira de caracteres, y un
Rangede Word no es más que una posición de inicio y otra de fin dentro de ella. No recorres celdas: describes un tramo de texto y actúas sobre él. El patrón que funciona desde Excel es: deja el diseño en una plantilla de Word con marcadores como{{Client}}, abre una copia, sustituye los marcadores por valores de la hoja, guarda, cierra y sal de Word. Tres cosas rompen este patrón:Dim r As Rangeen Excel significa el Range de Excel, así queSet r = doc.Contentfalla con Type mismatch («No coinciden los tipos»); unActiveDocumentoSelectionsin calificar crea un vínculo oculto con Word que falla con el error 462 en la segunda ejecución; y Buscar y reemplazar rechaza textos de reemplazo de más de 255 caracteres. Califica cada objeto de Word a través de tus propias variables y los tres desaparecen.
Sub QuickLetter()
Dim wd As Object, doc As Object
Set wd = CreateObject("Word.Application") ' un Word nuevo y oculto
Set doc = wd.Documents.Add(ThisWorkbook.Path & "\Letter.dotx")
doc.Content.Find.Execute FindText:="{{Client}}", _
ReplaceWith:=Range("B2").Value, Replace:=2 ' 2 = wdReplaceAll
doc.SaveAs2 ThisWorkbook.Path & "\Letter_out.docx"
doc.Close
wd.Quit
End Sub
Este es el segundo artículo de una serie de tres sobre cómo manejar otras apps de Office desde Excel. La
guía de PowerPoint trata la presentación, hecha de formas sobre diapositivas.
Aquí, Word: un flujo de texto. La guía de referencias explica cómo aprende VBA el
vocabulario del otro programa, que es justo de donde viene el choque de Range que verás más abajo. La regla
para los tres: cada objeto pertenece a una aplicación, así que di a cuál.
Lo que aprenderás
- El modelo mental: un documento es una tira de texto y un Range es un par de posiciones
- Cómo arrancar Word, abrir una plantilla y cerrarlo todo limpiamente
- Cómo sustituir marcadores, incluidos textos de más de 255 caracteres
- El choque de
Rangeentre Excel y Word, y cómo evitarlo - Por qué un
ActiveDocumentsin calificar provoca el error 462 y deja un WINWORD.EXE colgado - Cómo pegar una tabla de Excel, guardar en DOCX y exportar a PDF
El modelo mental: una tira de texto, no una cuadrícula
Excel localiza un valor por fila y columna. Word no tiene filas ni columnas, salvo dentro de las tablas. Un
documento de Word es una secuencia de caracteres, marcas de párrafo incluidas, y casi todo es un Range: una
posición de inicio y una posición de fin dentro de esa secuencia.
| Lo que quieres | Expresión de Word |
|---|---|
| todo el texto del cuerpo | doc.Content |
| un párrafo | doc.Paragraphs(3).Range |
| un punto marcado en una plantilla | doc.Bookmarks("Total").Range |
| el final del documento | doc.Content contraído a su final |
Actúas sobre un rango asignando su .Text, dando formato a su .Font o buscando dentro con .Find. Cuando
cambias el texto, las posiciones que vienen detrás se desplazan; por eso el código que memoriza números de
carácter se rompe y el código que busca marcadores no.
Así que el reparto del trabajo es el mismo que con PowerPoint: Excel guarda los datos, Word guarda el diseño. Diseña la carta, el contrato o el informe en Word, como una plantilla que el negocio pueda editar, y deja que la macro meta los valores.
Arrancar Word y terminar limpiamente
A diferencia de PowerPoint, Word arranca una copia nueva e invisible con CreateObject, como describe la
guía de CreateObject. Esa copia es tuya, así que cerrarla es seguro. El peligro
es el contrario: si la macro se para por un error antes de wd.Quit, el Word invisible sigue en marcha, y la
próxima vez que se abra la plantilla Word se quejará de que está bloqueada. Pon la limpieza donde un error
todavía llegue:
Sub MakeLetter()
Const wdExportFormatPDF As Long = 17
Dim wd As Object, doc As Object
On Error GoTo CleanUp
Set wd = CreateObject("Word.Application")
Set doc = wd.Documents.Add(Template:=ThisWorkbook.Path & "\Letter.dotx")
ReplaceTag doc, "{{Client}}", Range("B2").Value
ReplaceTag doc, "{{Amount}}", Format(Range("B3").Value, "#,##0.00")
ReplaceTag doc, "{{Terms}}", Range("B4").Value ' puede ser un parrafo largo
doc.SaveAs2 ThisWorkbook.Path & "\Letter_" & Range("B2").Value & ".docx"
doc.ExportAsFixedFormat OutputFileName:=ThisWorkbook.Path & "\Letter.pdf", _
ExportFormat:=wdExportFormatPDF
CleanUp:
If Not doc Is Nothing Then doc.Close SaveChanges:=False
If Not wd Is Nothing Then wd.Quit
Set doc = Nothing
Set wd = Nothing
If Err.Number <> 0 Then MsgBox "Letter failed: " & Err.Description
End Sub
Documents.Add con la ruta de una plantilla crea un documento nuevo y sin título basado en el .dotx, así
que la plantilla en sí nunca se modifica. La guía de On Error explica el salto a
CleanUp. Si quieres ver Word mientras desarrollas, añade wd.Visible = True después de crearlo.
Sustituir marcadores, y el muro de los 255 caracteres
Find.Execute con Replace:=2 (wdReplaceAll) es la forma rápida de cambiar un marcador, y para nombres,
fechas e importes es todo lo que necesitas. Pero dale un párrafo de condiciones contractuales y se para con
el error 5854, String parameter too long (el parámetro de cadena es demasiado largo): el texto de reemplazo
está limitado a 255 caracteres.
La versión robusta busca cada marcador y escribe el texto directamente en el rango encontrado, que no tiene límite de longitud:
Sub ReplaceTag(doc As Object, ByVal tag As String, ByVal newText As String)
Const wdFindStop As Long = 0
Const wdCollapseEnd As Long = 0
Dim r As Object ' un rango de Word, NO el Range de Excel
Set r = doc.Content
With r.Find
.ClearFormatting
.Text = tag
.MatchCase = True
.Wrap = wdFindStop
Do While .Execute
r.Text = newText ' r es ahora el marcador encontrado
r.Collapse wdCollapseEnd ' sigue despues de lo que escribimos
Loop
End With
End Sub
Cuando Execute tiene éxito, el rango r pasa a ser el texto que encontró, así que asignar r.Text
sustituye exactamente el marcador. Contraerlo hasta el final permite que el bucle siga desde ahí, de modo que
un valor que por casualidad contenga la etiqueta no se vuelve a sustituir. Las etiquetas entre llaves son
fáciles de ver para quien diseña la plantilla e imposibles de confundir con texto real. Los controles de
contenido y los marcadores (bookmarks) de Word también sirven, pero las etiquetas simples son las que puede
mantener alguien que no programa.
El choque de Range: el Range de Excel no es el Range de Word
Los dos programas tienen un objeto llamado Range, y también Shape, Font, Border y Selection. Dentro
del VBA de Excel, un Range sin calificar siempre significa el de Excel, porque la biblioteca de Excel está
por encima de la de Word en la lista de prioridad. Así que esto falla, incluso con una referencia a Word
marcada:
Dim r As Range ' Excel.Range
Set r = doc.Content ' Run-time error 13: Type mismatch
La solución es decir a qué aplicación te refieres:
Dim r As Word.Range con referencia, o Dim r As Object sin ella, como en ReplaceTag más arriba. La
guía de referencias muestra la lista de prioridad que decide qué significa un
nombre sin calificar. El hábito es sencillo: en código de Excel, cualquier variable que guarde un objeto de
Word es Word.Algo u Object, nunca un nombre a secas.
Error 462: el vínculo oculto de un ActiveDocument sin calificar
El segundo choque es más silencioso. Con una referencia a la biblioteca de Word marcada, Excel te deja escribir los nombres globales de Word sin ningún prefijo:
Set wd = New Word.Application
wd.Documents.Add
ActiveDocument.Content.Text = "Hello" ' sin calificar - funciona la primera vez
wd.Quit
La primera ejecución funciona. La segunda se para con el error 462 en tiempo de ejecución, The remote server
machine does not exist or is unavailable (el equipo servidor remoto no existe o no está disponible), o el
Administrador de tareas muestra un WINWORD.EXE que no desaparece nunca. El ActiveDocument sin calificar no
pasó por tu variable wd; VBA creó por su cuenta una conexión oculta con Word para él. wd.Quit cerró Word,
pero la conexión oculta sigue apuntando a la copia cerrada, y solo se limpia cuando el proyecto VBA se
restablece.
La regla: llega a cada objeto de Word a través de una variable que hayas creado tú. Escribe
wd.ActiveDocument o, mejor aún, guarda el documento en doc y no uses nunca ActiveDocument ni
Selection. El enlace tardío ayuda aquí: sin referencia marcada, un ActiveDocument sin calificar es
simplemente una variable sin declarar, y Option Explicit lo detiene al
compilar.
Pegar una tabla de Excel en el documento
Una tabla a la que ya diste formato en Excel puede entrar en Word como una tabla de Word de verdad, en un marcador que colocó quien diseñó la plantilla:
Sub PasteTable(doc As Object)
Dim target As Object
ThisWorkbook.Worksheets("Summary").Range("A1:D12").Copy
Set target = doc.Bookmarks("SalesTable").Range
target.PasteExcelTable LinkedToExcel:=False, WordFormatting:=False, RTF:=False
Application.CutCopyMode = False
End Sub
LinkedToExcel:=False hace una copia simple, que es lo correcto para una carta o un informe que se va a
enviar. Una tabla vinculada se rompe en cuanto el documento sale de tu PC. WordFormatting:=False conserva
el aspecto de Excel; ponlo a True para adoptar el estilo de tabla del documento. Para un rango que deba
verse exactamente como en la hoja y no editarse nunca, la alternativa es CopyPicture y pegar como imagen,
como en la guía de PowerPoint.
Dentro del propio Word: el mismo modelo de objetos
Si buscabas Word VBA porque quieres una macro dentro de Word, todo lo anterior sigue valiendo, menos el
puente. En el editor de VBA del propio Word, ActiveDocument, Range y Selection son objetos de Word, y no
hay variable wd por la que calificar. El modelo de tira de texto, el bucle de Find y el límite de 255
caracteres son los mismos. Lo que cambia es la dirección: desde Word, Excel pasa a ser el programa ajeno, y
las mismas reglas se aplican al Range de Excel.
La decisión de criterio: Word para el diseño, Excel para el bucle
Para una sola carta, cualquiera de los dos programas sirve. Para doscientas, la decisión de diseño importa. Mi
regla: el bucle y los datos se quedan en Excel, el diseño se queda en una plantilla de Word, y la macro
nunca da formato a texto que podría haber dejado en manos de la plantilla. Arranca Word una vez, crea un
documento por fila a partir del mismo .dotx, cierra cada uno después de guardarlo y sal de Word al final.
Eso es una combinación de correspondencia que controlas tú, con los nombres de archivo, la salida en PDF y el
manejo de errores que elijas. La combinación de correspondencia integrada de Word va bien para imprimir un
único documento combinado largo; en cuanto necesitas un archivo por fila, gana la macro.
Cómo ayuda ExcelMaster
Los bugs de automatización de Word se esconden en el espacio entre los dos programas: un error de tipos en una línea que parece correcta, un WINWORD.EXE que nunca se cierra, una cláusula de contrato demasiado larga para reemplazarla.
ExcelMaster te deja describir el resultado, por ejemplo «una carta por cliente a partir de mi plantilla, guardada en PDF con el nombre del cliente». Escribe la macro con cada objeto de Word calificado, un bucle de marcadores sin límite de longitud y una limpieza que se ejecuta incluso cuando falla una fila.
Preguntas frecuentes
¿Cómo abro un documento de Word desde Excel VBA?
Crea Word con CreateObject("Word.Application") y después llama a wd.Documents.Open con la ruta del
archivo, o a wd.Documents.Add con la ruta de una plantilla para obtener un documento nuevo basado en ella.
Guarda el resultado en una variable y trabaja solo a través de esa variable.
¿Por qué me sale el error 462 al automatizar Word desde Excel?
Tu código usó un objeto de Word sin calificarlo, normalmente ActiveDocument o Selection, así que VBA creó
una conexión oculta con Word. Después de Quit, esa conexión apunta a un programa cerrado. Llega a cada
objeto de Word a través de tu propia variable wd o doc.
¿Por qué Dim r As Range da un error de tipos con Word?
En el VBA de Excel, Range significa el Range de Excel. Un rango de Word es un tipo distinto, así que
asignarle doc.Content falla con Type mismatch. Decláralo como Word.Range con una referencia a Word, o
como Object sin ella.
¿Cómo reemplazo en Word un texto de más de 255 caracteres con VBA?
Busca el marcador con Range.Find.Execute y luego asigna el valor largo al .Text del rango encontrado. El
límite de 255 caracteres solo se aplica al argumento ReplaceWith de Buscar y reemplazar, no a
Range.Text.
¿Cómo guardo un documento de Word como PDF desde Excel VBA?
Llama a doc.ExportAsFixedFormat con un nombre de archivo de salida y ExportFormat:=17, que es
wdExportFormatPDF. El documento sigue abierto, así que ciérralo y sal de Word después.
Probado en
Probado en: Excel 365 y Word 365 (Windows 11), VBA 7.1 — última verificación el 02/10/2026.
Guías relacionadas: VBA PowerPoint · VBA References · VBA CreateObject · VBA Outlook · VBA On Error · VBA Option Explicit · VBA Replace · VBA Save as PDF
