1

I need to do some heavy find-replace modifications in a bunch of Word documents and I am trying to speed this up by making this a string operation using the Office Open XML. I can extract the XML encoding from the document, make my modifications but I haven't found a way to inject it back into the document.

Currently my macro looks roughly like this:

Dim sDocXML As String
Dim sXMLReplaced As String

With appWD.ActiveDocument
    sDocXML = .Content.WordOpenXML
    WriteDown "C:\temp\xml.txt", sDocXML
    sXMLReplaced = DoReplacements(sDocXML)        
    WriteDown "C:\temp\xmlreplaced.txt", sXMLReplaced
    ????.InsertXML sXMLReplaced
End with

The problem is with the .InsertXML part because I have no idea what to inject where. I tried to do it with .Content level, .Paragraphs.Range level, .Paragraphs(1).Range etc. There seems to be next to no documentation in using the .InsertXML and I guess I am just using it the wrong way. The line always returns an error, either that the object doesn't support the method (where it is not super clear to me which object which method... if it is the final .InsertXML, or if I chained the objects incorrectly together) or most frequently: XML markup cannot be inserted in the specified location.

The DoReplacements function doesn't change any structure of the XML, only the contents of the inner text, using clearly defined delimiters that do not appear outside of it. All I need to do is to is replacing this:

<w:body>
    <w:p w:rsidR="000F263E" w:rsidRPr="00B72526" w:rsidRDefault="000F263E" w:rsidP="000F263E">
        <w:pPr>
            <w:shd w:val="clear" w:color="auto" w:fill="FFFFFF" w:themeFill="background1"/>                 
            <w:spacing w:after="0" w:line="240" w:lineRule="auto"/>
            <w:jc w:val="both"/>
            <w:rPr>
                <w:rFonts w:ascii="Arial" w:eastAsia="Times New Roman" w:hAnsi="Arial" w:cs="Arial"/>
                <w:color w:val="000000"/>
                <w:sz w:val="18"/>
                <w:szCs w:val="18"/>
            </w:rPr>
        </w:pPr>
        <w:r w:rsidRPr="00A84F56">
            <w:rPr>
                <w:rFonts w:ascii="Arial" w:eastAsia="Times New Roman" w:hAnsi="Arial" w:cs="Arial"/>
                <w:color w:val="000000" w:themeColor="text1"/>
                <w:sz w:val="18"/>
                <w:szCs w:val="18"/>
            </w:rPr>
            <w:t>{{Date}}</w:t>
        </w:r>
    </w:p>
</w:body>

to this:

<w:body>
    <w:p w:rsidR="000F263E" w:rsidRPr="00B72526" w:rsidRDefault="000F263E" w:rsidP="000F263E">
        <w:pPr>
            <w:shd w:val="clear" w:color="auto" w:fill="FFFFFF" w:themeFill="background1"/>                 
            <w:spacing w:after="0" w:line="240" w:lineRule="auto"/>
            <w:jc w:val="both"/>
            <w:rPr>
                <w:rFonts w:ascii="Arial" w:eastAsia="Times New Roman" w:hAnsi="Arial" w:cs="Arial"/>
                <w:color w:val="000000"/>
                <w:sz w:val="18"/>
                <w:szCs w:val="18"/>
            </w:rPr>
        </w:pPr>
        <w:r w:rsidRPr="00A84F56">
            <w:rPr>
                <w:rFonts w:ascii="Arial" w:eastAsia="Times New Roman" w:hAnsi="Arial" w:cs="Arial"/>
                <w:color w:val="000000" w:themeColor="text1"/>
                <w:sz w:val="18"/>
                <w:szCs w:val="18"/>
            </w:rPr>
            <w:t>01/01/2026</w:t>
        </w:r>
    </w:p>
</w:body>

And injecting it back to the document (obviously with many more paragraphs and placeholders).

2
  • From what you have tried, do you get errors or does it just not seem to be applying your changes? Commented Oct 17 at 11:35
  • @MadsHansen Updated. Yes, I typically get the error XML markup cannot be inserted in the specified location. Commented Oct 17 at 12:16

1 Answer 1

3

This basic test worked for me:

Sub Tester()
    
    Dim txt As String
    
    txt = ThisDocument.Range.WordOpenXML

    Debug.Print txt
    txt = Replace(txt, "{{Date}}", "01/01/2026")
    
    ThisDocument.Content.Delete
    
    Selection.InsertXML txt

End Sub

Before:
enter image description here

After:

enter image description here

Sign up to request clarification or add additional context in comments.

8 Comments

Had an issue with object not supporting the method but never mind. Your code is for a macro in the Word document, I am running this from Excel, so had to prefix the selection with the relevant application.
I missed that you weren't doing that from within Word...
OK, interesting. This works but not for my case. I still get XML markup cannot be inserted in the specified location. I figured the issue is with the document I use as a template so I have run a bunch of test on elements within, ruled out page break, header, footer, pictures... and the problem is a table I have in the document, full of replaceables. Comparison of the input/output XML strings reveals only the predicted changes in the replaceables, otherwise the XML is exactly the same.
Ok, your answer is correct even though I can't make it work yet. The problem isn't the table but one of the replaced texts. I have a suspicion about a special character.
Le sigh Yes, it doesn't like ampersands. FML.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.