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

VBA Word en Excel — rellenar una plantilla, evitar el choque de Range y el error 462

|

VBA Word en Excel — rellenar una plantilla, evitar el choque de Range y el error 462

TL;DR — Para Word, un documento es una larga tira de caracteres, y un Range de 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 Range en Excel significa el Range de Excel, así que Set r = doc.Content falla con Type mismatch («No coinciden los tipos»); un ActiveDocument o Selection sin 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 Range entre Excel y Word, y cómo evitarlo
  • Por qué un ActiveDocument sin 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