Search for text, replace with field

darsha
NewLounger
Posts: 19
Joined: 15 Mar 2010, 11:56

Search for text, replace with field

Post by darsha »

I have a document which contains delimited text instead of mergefields. I need to replace the text with proper mergefields. There are a number of similar documents that need to be 'fixed' and they all contain a couple of dozen 'fields'. I have almost managed to do this but the the end results are not quite as expected.

The first task is identify the text to be swapped out. All the 'fake' fields are surrounded by the double angle quotes. I'm searching for any text within brackets << >> and then adding unique strings to a dictionary.

Selection.HomeKey
With Selection.Find
    .ClearFormatting
    .Text = Chr(171) & "*" & Chr(187)
    .Forward = True
    .Wrap = wdFindContinue
    .Forward = True
    .Execute

    Do While .Found = True
        str = Selection.Range.Text
        If Not dict.Exists(str) Then
         i = i + 1
         dict.Add str, i
        End If
        Execute
    Loop

End with

Then, I loop through the dictionary and pass each text string in turn to another method.
This selects are instances of the text and adds the range of each selection to a collection.

Do While .Found = True
    intFindCounter = intFindCounter + 1
    colFoundItems.Add Selection.Range, CStr(intFindCounter)
    .Execute
Loop

I then loop the though the range collection and 'replace' the range with a mergefield
For Each rngCurrent In colFoundItems
    Range.Fields.Add Range:=rngCurrent, Type:=wdFieldMergeField, Text:=MyText
Next rngCurrent

Now, this all seems to be ok except in some instances the original text is not replaced by the mergefield but becomes part of it.
So I see this «Address1»«Address1» and when I toggle field codes I see this «Address1»{ MERGEFIELD Address1 \* MERGEFORMAT }

The first page of the document has address fields and these have been replaced ok. The last page also has address fields and these have gone awry as described above.
Some of the text (where the replace has gone wrong) has a paragraph mark immediately following, others are inline in the middle of parapraphs. Of the inline examples some of the original text is followed (or prefixed) immediately by another character, e.g. a period, comma or pound sign. I can't see any obvious pattern as to why this sometimes works and soemtimes doesn't.

Any ideas?

I'm guessingI'm identify the ranges wrong somehow

User avatar
HansV
Administrator
Posts: 78488
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: Search for text, replace with field

Post by HansV »

Hi Darsha,

It isn't really necessary to loop through the document twice. You can perform the replacements in one loop:

Code: Select all

Sub Convert2MergeFields()
  Dim strField As String
  ' Move to start of document
  Selection.HomeKey Unit:=wdStory
  With Selection.Find
    ' Set the Find parameters
    .ClearFormatting
    .Text = "«*»"
    .MatchWildcards = True
    .Forward = True
    .Wrap = wdFindStop
    ' Find all occurrences in a loop
    Do While .Execute
      ' Get selected text
      strField = Selection.Text
      ' Strip away « and »
      strField = Mid(strField, 2, Len(strField) - 2)
      ' Insert merge field
      ActiveDocument.Fields.Add _
        Range:=Selection.Range, Type:=wdFieldMergeField, _
        Text:=strField, PreserveFormatting:=True
      ' Move to the end of the field to continue searching
      Selection.Collapse Direction:=wdCollapseEnd
    Loop
  End With
End Sub
If that still produces the same problem, could you post a small sample document in which this happens? You can remove most of the text of the document.
Best wishes,
Hans

darsha
NewLounger
Posts: 19
Joined: 15 Mar 2010, 11:56

Re: Search for text, replace with field

Post by darsha »

See, I knew I should have come here first. Your code works perfectly on the document. Thankyou :cheers:

I knew what I had written was very long winded but, assuming I had a list of words to search for, can you see where in particular I'd gone wrong with the chunk of code below?
The Do While .Found=true seemed to loop too many times

Code: Select all

With Selection.Find
    .ClearFormatting
    .Forward = True
    .Wrap = wdFindContinue
    .Text = Chr(171) & MyText & Chr(187)
    .Execute
        
    Do While .Found = True
        intFindCounter = intFindCounter + 1
        colFoundItems.Add Selection.Range, CStr(intFindCounter)
        .Execute
    Loop
End With

User avatar
HansV
Administrator
Posts: 78488
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: Search for text, replace with field

Post by HansV »

You should set Wrap to wdFindStop, not to wdFindContinue. And I now see that the code will go on processing «...» text that has already been converted. To prevent this, you can temporarily display field codes:

Code: Select all

Sub Convert2MergeFields()
  Dim strField As String
  ' Move to start of document
  Selection.HomeKey Unit:=wdStory
  ' Display field codes
  ActiveWindow.View.ShowFieldCodes = True
  With Selection.Find
    ' Set the Find parameters
    .ClearFormatting
    .Text = "«*»"
    .MatchWildcards = True
    .Forward = True
    .Wrap = wdFindStop
    ' Find all occurrences in a loop
    Do While .Execute
      ' Get selected text
      strField = Selection.Text
      ' Strip away « and »
      strField = Mid(strField, 2, Len(strField) - 2)
      ' Insert merge field
      ActiveDocument.Fields.Add _
        Range:=Selection.Range, Type:=wdFieldMergeField, _
        Text:=strField, PreserveFormatting:=True
      ' Move to the end of the field to continue searching
      Selection.Collapse Direction:=wdCollapseEnd
    Loop
  End With
  ' Hide field codes
  ActiveWindow.View.ShowFieldCodes = False
End Sub
Best wishes,
Hans

darsha
NewLounger
Posts: 19
Joined: 15 Mar 2010, 11:56

Re: Search for text, replace with field

Post by darsha »

I was copying an example from msdn SearchAndReturnExample()

Must have missed somethign obvious when I tried to modify it.

Anyone, I've run your code on a couple of documents and it works ok (without the need for the field codes bit)

Thanks again