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

VBA Word from Excel — Fill a Template, Avoid the Range Clash and Error 462

|

VBA Word from Excel — Fill a Template, Avoid the Range Clash and Error 462

TL;DR — To Word, a document is one long run of characters, and a Word Range is just a start and an end position in it. You do not visit cells; you describe a stretch of text and act on it. The working pattern from Excel is: keep the layout in a Word template with placeholders such as {{Client}}, open a copy, replace the placeholders with worksheet values, save, close, quit. Three things break this pattern: Dim r As Range in Excel means Excel's Range, so Set r = doc.Content fails with a type mismatch; an unqualified ActiveDocument or Selection creates a hidden link to Word that fails with error 462 on the second run; and Find and Replace refuses replacement text longer than 255 characters. Qualify every Word object through your own variables and all three go away.

Sub QuickLetter()
    Dim wd As Object, doc As Object
    Set wd = CreateObject("Word.Application")              ' a new, hidden Word
    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

This is the second article in a three-part cluster on driving other Office apps from Excel. The PowerPoint guide covers a deck, made of shapes on slides. Here, Word: a stream of text. The References guide explains how VBA learns the other program's vocabulary, which is exactly where the Range clash below comes from. The rule for all three: every object belongs to one application, so say which one.

What you'll learn

  • The mental model: a document is a run of text and a Range is a pair of positions
  • How to start Word, open a template and close everything cleanly
  • How to replace placeholders, including text longer than 255 characters
  • The Range clash between Excel and Word, and how to avoid it
  • Why an unqualified ActiveDocument causes error 462 and a leftover WINWORD.EXE
  • How to paste an Excel table, save as DOCX and export to PDF

The mental model: a run of text, not a grid

Excel addresses a value by row and column. Word has no rows and columns, except inside tables. A Word document is a sequence of characters, paragraphs marks included, and almost everything is a Range: a start position and an end position in that sequence.

You want Word expression
the whole body text doc.Content
one paragraph doc.Paragraphs(3).Range
a marked spot in a template doc.Bookmarks("Total").Range
the end of the document doc.Content collapsed to its end

You act on a range by setting its .Text, formatting its .Font, or searching it with .Find. When you change the text, the positions after it shift, which is why code that remembers character numbers breaks and code that searches for markers does not.

So the division of work is the same as with PowerPoint: Excel holds the data, Word holds the layout. Design the letter, contract or report in Word, as a template the business can edit, and let the macro put values into it.

Starting Word and finishing cleanly

Unlike PowerPoint, Word starts a new, invisible copy for CreateObject, which the CreateObject guide describes. That copy is yours, so quitting it is safe. The danger is the opposite one: if the macro stops on an error before wd.Quit, the invisible Word keeps running, and the next time the template is opened Word complains that it is locked. Put the clean-up where an error still reaches it:

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      ' may be a long paragraph

    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 with a template path creates a new, untitled document based on the .dotx, so the template itself is never changed. The On Error guide explains the jump to CleanUp. If you want to watch Word while you develop, add wd.Visible = True after creating it.

Replacing placeholders, and the 255-character wall

Find.Execute with Replace:=2 (wdReplaceAll) is the quick way to swap a placeholder, and for names, dates and amounts it is all you need. But give it a paragraph of contract terms and it stops with error 5854, String parameter too long: the replacement text is limited to 255 characters.

The robust version finds each placeholder and writes the text into the found range directly, which has no length limit:

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                         ' a Word range, NOT Excel's Range
    Set r = doc.Content
    With r.Find
        .ClearFormatting
        .Text = tag
        .MatchCase = True
        .Wrap = wdFindStop
        Do While .Execute
            r.Text = newText                ' r is now the found placeholder
            r.Collapse wdCollapseEnd        ' continue after what we wrote
        Loop
    End With
End Sub

When Execute succeeds, the range r moves to the text it found, so setting r.Text replaces exactly the placeholder. Collapsing to the end lets the loop continue from there, so a value that happens to contain the tag is not replaced again. Curly-brace tags are easy for the template author to see and impossible to confuse with real text. Word's content controls and bookmarks work too, but plain tags are the ones non-developers can maintain.

The Range clash: Excel's Range is not Word's Range

Both programs have an object called Range, and also Shape, Font, Border and Selection. Inside Excel's VBA, an unqualified Range always means Excel's, because Excel's library sits above Word's in the priority list. So this fails, even with a reference to Word set:

Dim r As Range                  ' Excel.Range
Set r = doc.Content             ' Run-time error 13: Type mismatch

The fix is to say which application you mean: Dim r As Word.Range with a reference, or Dim r As Object without one, as in ReplaceTag above. The References guide shows the priority list that decides what an unqualified name means. The habit is simple: in Excel code, any variable that holds a Word object is either Word.Something or Object, never a bare name.

The second clash is quieter. With a reference to the Word library set, Excel lets you write Word's global names without any prefix:

Set wd = New Word.Application
wd.Documents.Add
ActiveDocument.Content.Text = "Hello"        ' unqualified - works the first time
wd.Quit

The first run works. The second run stops with run-time error 462, The remote server machine does not exist or is unavailable, or Task Manager shows a WINWORD.EXE that never goes away. The unqualified ActiveDocument did not go through your wd variable; VBA made its own hidden connection to Word for it. wd.Quit closed Word, but the hidden connection still points at the closed copy, and it is only cleared when the VBA project resets.

The rule: reach every Word object through a variable you created. Write wd.ActiveDocument, or better, keep the document in doc and never use ActiveDocument or Selection at all. Late binding helps here: with no reference set, an unqualified ActiveDocument is simply an undeclared variable, and Option Explicit stops it at compile time.

Pasting an Excel table into the document

A table you have already formatted in Excel can go into Word as a real Word table at a bookmark the template author placed:

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 makes a plain copy, which is right for a letter or report that will be sent. A linked table breaks as soon as the document leaves your PC. WordFormatting:=False keeps the Excel look; set it to True to adopt the document's table style instead. For a range that should look exactly like the sheet and never be edited, CopyPicture and a picture paste, as in the PowerPoint guide, is the alternative.

Inside Word itself: the same object model

If you searched for Word VBA because you want a macro inside Word, everything above still applies, minus the bridge. In Word's own VBA editor, ActiveDocument, Range and Selection mean Word's objects, and there is no wd variable to qualify through. The run-of-text model, the Find loop and the 255-character limit are the same. What changes is direction: from Word, Excel becomes the foreign program, and the same rules apply to Excel's Range.

The judgment call: Word for the layout, Excel for the loop

For one letter, either program can do the job. For two hundred, the design decision matters. My rule: the loop and the data stay in Excel, the layout stays in a Word template, and the macro never formats text it could have left to the template. Start Word once, create one document per row from the same .dotx, close each after saving, and quit at the end. That is a mail merge you control, with file names, PDF output and error handling of your choosing. Word's built-in mail merge is fine for printing one long merged document; as soon as you need one file per row, the macro wins.

How ExcelMaster helps

Word automation bugs hide in the space between the two programs: a type mismatch on a line that looks right, a WINWORD.EXE that never quits, a contract clause that is too long to replace.

ExcelMaster lets you describe the result, such as "one letter per customer from my template, saved as PDF with the customer name". It writes the macro with every Word object qualified, a placeholder loop with no length limit, and clean-up that runs even when a row fails.

Frequently asked questions

How do I open a Word document from Excel VBA?

Create Word with CreateObject("Word.Application"), then call wd.Documents.Open with the file path, or wd.Documents.Add with a template path to get a new document based on it. Keep the result in a variable and work only through that variable.

Why do I get error 462 when automating Word from Excel?

Your code used a Word object without qualifying it, usually ActiveDocument or Selection, so VBA made a hidden connection to Word. After Quit, that connection points at a closed program. Reach every Word object through your own wd or doc variable.

Why does Dim r As Range give a type mismatch with Word?

In Excel's VBA, Range means Excel's Range. A Word range is a different type, so assigning doc.Content to it fails. Declare it as Word.Range with a reference to Word, or as Object without one.

How do I replace text longer than 255 characters in Word with VBA?

Find the placeholder with Range.Find.Execute, then set the found range's .Text to the long value. The 255-character limit only applies to the ReplaceWith argument of Find and Replace, not to Range.Text.

How do I save a Word document as PDF from Excel VBA?

Call doc.ExportAsFixedFormat with an output file name and ExportFormat:=17, which is wdExportFormatPDF. The document stays open, so close it and quit Word afterwards.

Tested in

Tested in: Excel 365 and Word 365 (Windows 11), VBA 7.1 — last verified 2026-10-02.

Related guides: VBA PowerPoint · VBA References · VBA CreateObject · VBA Outlook · VBA On Error · VBA Option Explicit · VBA Replace · VBA Save as PDF