![]() |
|
![]() |
|
Thread Tools | Display Modes |
#1
|
|||
|
|||
![]()
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. |
#2
|
|||
|
|||
![]()
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. |
#3
|
||||
|
||||
![]()
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] |
#4
|
|||
|
|||
![]()
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. |
#5
|
||||
|
||||
![]()
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] |
![]() |
Tags |
mailmerge, ms-word, vba |
Thread Tools | |
Display Modes | |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
![]() |
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 |
![]() |
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 |