Microsoft Office Forums

Go Back   Microsoft Office Forums > >

Reply
 
Thread Tools Display Modes
  #1  
Old 03-16-2025, 04:34 AM
Jakster Jakster is offline Search for and replace merge fields in Word doc with plain text using VBA Windows 11 Search for and replace merge fields in Word doc with plain text using VBA Office 2021
Novice
Search for and replace merge fields in Word doc with plain text using VBA
 
Join Date: Mar 2025
Posts: 6
Jakster is on a distinguished road
Default Search for and replace merge fields in Word doc with plain text using VBA

I have many documents (Word templates - .dotx) that have various merge fields in them. Some are just regular merge fields while others may be IF fields or DATE fields.



While most of the fields are on their own line, some also have text before or after the field or are within paragraphs in some documents.

I would like create a routine that will open each file in a particular folder and search for those particular fields and will replace the fields with text only. That is, the fields are no longer needed.

I have tried creating the routine (using code from the internet - including from GMayor! - plus my own edits), using lists of search and replace terms, but seem to be getting stuck with the find and replace part of it. Specifically, I am not finding the fields that are not straightforward merge fields (ie; the DATE and IF fields).

I suspect I am using the wrong approach (although I have tried several!) and would appreciate and assistance pointing me in the right direction. (My efforts are below)

EDIT: A solution I thought may work (but I haven't been able to get working) was to unlink all mergefields, turning them to regular text and then searching for the relevant phrases with the double brackets that remain.. Would this be possible?

Examples of things I am trying to search and replace for include: {IF TRUE {DATE \@ "d MMM yyyy" }, { MERGEFIELD COMPANY_NAME}, { MERGEFIELD ACN}, etc.

Thanks in advance for any help.


Code:
Sub SearchAndReplace()
    Dim oWordApp As Object, oWordDoc As Object, rngStory As Object
    Dim sFolder As String, strFilePattern As String
    Dim strFileName As String, sFileName As String
    Dim strFind, strRep, strSearchList, strRepList As String
    Dim i, x As Long
    Dim lngValidate As Long
    Dim oShp As Shape

    'Application.ScreenUpdating = False
    
    strSearchList = "DATE \@, MERGEFIELD Company Name,(IN LIQUIDATION),MERGEFIELD ACN,MERGEFIELD Trading_Name,MERGEFIELD Trust"
    strRepList = "[RF_TODAY_LONG],[RF_ADMIN_FULL_NAME],[RF_ADMIN_APPT_SUFFIX],[RF_JOBINFO_A.C.N.],[RF_JOBINFO_FORMERLY_TRADING_AS],[RF_JOBINFO_ TRUST_NAME],[RF_JOBINFO_A.B.N.]"

    'Use to select folder
    'sFolder = GetFolder & "\"

    '~~> Change this to the folder which has the files (or comment and use GetFolder)
    sFolder = "S:\TEMPLATES\APL Precedents\CVL\"
    '~~> This is the file extension you want to loop through
    strFilePattern = "*.dotx"

    '~~> Establish an Word application object
    On Error Resume Next
    Set oWordApp = GetObject(, "Word.Application")

    If Err.Number <> 0 Then
        Set oWordApp = CreateObject("Word.Application")
    End If
    Err.Clear
    On Error GoTo 0

    oWordApp.Visible = True

    '~~> Loop through the folder to get the word files
    strFileName = Dir$(sFolder & strFilePattern)
    Do Until strFileName = ""
        sFileName = sFolder & strFileName

        '~~> Open the word doc
        Set oWordDoc = oWordApp.Documents.Open(sFileName)

        oWordDoc.ActiveWindow.View.ShowFieldCodes = True
        
        'Convert merge fileds to text
        'oWordDoc.Fields.Unlink

        'Fix the skipped blank Header/Footer problem.
        lngValidate = oWordDoc.Sections(1).Headers(1).Range.StoryType
        
        'Iterate through all story types in the current document.
        For Each rngStory In oWordDoc.StoryRanges
        
            '~~> Iterate through all linked stories. Do Find and Replace.
            Do
                For i = 0 To UBound(Split(strSearchList, ","))
                    strFind = Split(strSearchList, ",")(i)
                    strRep = Split(strRepList, ",")(i)
                    ReplaceFields rngStory, strFind, strRep
                    SearchAndReplaceInStory rngStory, strFind, strRep
                Next
                On Error Resume Next
                Select Case rngStory.StoryType
                    Case 6, 7, 8, 9, 10, 11
                        If rngStory.ShapeRange.Count > 0 Then
                            For Each oShp In rngStory.ShapeRange
                                If oShp.TextFrame.HasText Then
                                    For x = 0 To UBound(Split(strSearchList, ","))
                                        strFind = Split(strSearchList, ",")(x)
                                        strRep = Split(strRepList, ",")(x)
                                        ReplaceFields rngStory, strFind, strRep
                                        SearchAndReplaceInStory oShp.TextFrame.TextRange, strFind, strRep
                                    Next
                                End If
                            Next
                        End If
                    Case Else
                      'Do Nothing
                End Select
                On Error GoTo 0
                'Get next linked story (if any)
                Set rngStory = rngStory.NextStoryRange
            Loop Until rngStory Is Nothing
        Next

        '~~> Close the file after saving
        oWordDoc.Close SaveChanges:=True

        '~~> Find next file
        strFileName = Dir$()
    Loop
    
    'Application.ScreenUpdating = true

    '~~> Quit and clean up
    oWordApp.Quit

    Set oWordDoc = Nothing
    Set oWordApp = Nothing
End Sub

Sub SearchAndReplaceInStory(ByVal rngStory As Word.Range, ByVal strSearch As String, ByVal strReplace As String)

    rngStory.TextRetrievalMode.IncludeFieldCodes = True
    rngStory.TextRetrievalMode.IncludeHiddenText = True

    With rngStory.Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Forward = True
        .Wrap = wdFindContinue
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
        .Text = strSearch
        .Replacement.Text = strReplace
        .Execute Replace:=wdReplaceAll
    End With
    
lbl_Exit:
  Exit Sub
End Sub

Sub ReplaceFields(ByVal rngStory As Word.Range, ByVal strSearch As String, ByVal strReplace As String)
'Graham Mayor - http://www.gmayor.com - Last updated - 25 Sep 2018
'Modified by me

    Dim oFld As Field

    For Each oFld In rngStory.Fields
        If oFld.Type = wdFieldMergeField Or oFld.Type = wdFieldDate Or oFld.Type = wdFieldIf Then
            If InStr(1, oFld.Code, strSearch) > 0 Then
                oFld.Code.Text = Replace(oFld.Code.Text, strSearch, strReplace)
                oFld.Update
                oFld.Unlink
            End If
        End If
    Next oFld
    
lbl_Exit:
    Set oFld = Nothing
    Exit Sub
    
End Sub
 
Function GetFolder() As String

    Dim oFolder As Object
    
    GetFolder = ""
    Set oFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Choose a folder", 0)
    
    If (Not oFolder Is Nothing) Then GetFolder = oFolder.Items.Item.Path
    
    Set oFolder = Nothing
    
End Function

Last edited by Jakster; 03-16-2025 at 05:53 PM.
Reply With Quote
  #2  
Old 03-16-2025, 08:06 AM
Jakster Jakster is offline Search for and replace merge fields in Word doc with plain text using VBA Windows 11 Search for and replace merge fields in Word doc with plain text using VBA Office 2021
Novice
Search for and replace merge fields in Word doc with plain text using VBA
 
Join Date: Mar 2025
Posts: 6
Jakster is on a distinguished road
Default

Just an update.... I think I may have found a way to make it work... I have used the following code (again, found online and modified) which seems to done the trick.

Code:
Sub ReplaceFields(ByVal rngStory As Word.Range, ByVal strSearch As String, ByVal strReplace As String)

    Dim oFld As Field
    Dim oRng As Range
    
    For Each oFld In ActiveDocument.Fields
        Set oRng = oFld.Code
        If InStr(1, oRng.Text, strSearch) > 0 Then
        oRng.MoveStart wdCharacter, -1
        oRng.Collapse
        oRng.InsertAfter strReplace
        oFld.Delete
        End If
    Next oFld
    
lbl_Exit:
    Set oFld = Nothing
    Set oRng = Nothing
    Exit Sub
    
End Sub

Last edited by Jakster; 03-16-2025 at 06:02 PM.
Reply With Quote
  #3  
Old 03-16-2025, 07:34 PM
macropod's Avatar
macropod macropod is offline Search for and replace merge fields in Word doc with plain text using VBA Windows 10 Search for and replace merge fields in Word doc with plain text using VBA Office 2016
Administrator
 
Join Date: Dec 2010
Location: Canberra, Australia
Posts: 22,363
macropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond repute
Default

Surely the simplest way would be to connect the documents to a data source containing all the required fields and, for each field, a record with whatever ouput text you want, then merge to a new document.

Still, if you're wedded to a VBA approach, you might find the macro titled Create Text Representations of Working Fields in the Mailmerge Tips & Tricks 'Sticky' thread at the top of the Mailmerge forum helpful. That code converts field codes to text representations of their content. See: https://www.msofficeforums.com/mail-...ps-tricks.html

PS: For mailmerges, you should be using mailmerge main documents, not templates.
__________________
Cheers,
Paul Edstein
[Fmr MS MVP - Word]
Reply With Quote
  #4  
Old 03-16-2025, 08:18 PM
Jakster Jakster is offline Search for and replace merge fields in Word doc with plain text using VBA Windows 11 Search for and replace merge fields in Word doc with plain text using VBA Office 2021
Novice
Search for and replace merge fields in Word doc with plain text using VBA
 
Join Date: Mar 2025
Posts: 6
Jakster is on a distinguished road
Default

Hi Paul,
Thanks so much for your reply and for the info..

Your idea regarding merging the documents is a very sensible one!! It would work for most fields however, I think it would fail for fields that didn't accept plain text (ie: date fields or fields formatted for numbers). It would probably be more time consuming as there are hundreds of documents I would need to merge and save.

Also, I note your point regarding mailmerges - however I need the files for a particular application which uses templates... we therefore are moving from mailmerges using documents with fields to templates that use simple codes within square brackets. Therefore, my need to convert the field codes to text and the documents to templates.

In any event, I think I am there now but thank you again for your assistance.
Reply With Quote
  #5  
Old 03-17-2025, 12:46 AM
macropod's Avatar
macropod macropod is offline Search for and replace merge fields in Word doc with plain text using VBA Windows 10 Search for and replace merge fields in Word doc with plain text using VBA Office 2016
Administrator
 
Join Date: Dec 2010
Location: Canberra, Australia
Posts: 22,363
macropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond repute
Default

I can't see why merging shouldn't work for mergefields outputting dates or formatted numbers. At most, if the fields are remaining in the documents post-merge, your commented-out line of code:
oWordDoc.Fields.Unlink
is all that's needed (the equivalent of Ctrl-A, Ctrl-Shift-F9). Indeed, you can even do that without doing any merging. Either way, having converted all your fields to plain text, replacing the text results with your "simple codes within square brackets" should be a breeze.
__________________
Cheers,
Paul Edstein
[Fmr MS MVP - Word]
Reply With Quote
Reply

Tags
mailmerge, ms-word, vba

Thread Tools
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
Search for and replace merge fields in Word doc with plain text using VBA Plain text help with returns - looking for marker to use when converting to plain text redzan Word 1 04-18-2017 06:17 PM
Macro to keep formatted form fields after mail merge or replace text with formatted form fields jer85 Word VBA 2 04-05-2015 10:00 PM
Searhc for Hyperlinked Word and replace with plain text or nothing somniloquist Word 3 10-04-2011 02:33 AM
Search for and replace merge fields in Word doc with plain text using VBA Replace all occurrences of one merge field with plain text blankenthorst Mail Merge 5 07-01-2011 05:18 AM
Replace All with plain text containing subscript DeaducK Word 0 06-24-2010 08:16 PM

Other Forums: Access Forums

All times are GMT -7. The time now is 05:22 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Search Engine Optimisation provided by DragonByte SEO (Lite) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
MSOfficeForums.com is not affiliated with Microsoft