Community Pick: Many members of our community have endorsed this article.
Editor's Choice: This article has been selected by our editors as an exceptional contribution.

Macro code to convert text to fields in Microsoft Word

GrahamSkanRetired
CERTIFIED EXPERT
Published:
Updated:
It is often necessary in this forum and others to illustrate Word fields as text with the field delimiters replaced with the curly brackets that the delimiters resemble when field codes are being displayed on the document. This means that the text cannot be used by simply be copying and pasting into another Word document. Each field must be inserted individually.

Sometimes there can be a complex structure of nested fields, in which case the task can be quite tricky. Here is a relatively simple example from a recent question.

{ IF {Mergefield creditors) > 300 "Employee 1
Employee 2
Employee 3" "{IF {Mergefield creditors} > 200 "Employee 1
Employee 2" "Employee 1" }" }


This macro set converts such text into the fields that it tries to portray. There is no error checking, so the text would have to be well-formed.  
 
Sub CallTextToFields()
                          Dim rng As Range
                          Set rng = Selection.Range
                          TextToFields rng
                      End Sub
                      
                      Sub TextToFields(rng1 As Range)
                          Dim rng As Range
                          Dim fld As Field
                          
                          Set rng = GetField(rng1)
                          Do Until rng Is Nothing
                              rng.Characters.First.Delete 'remove the "{"
                              rng.Characters.Last.Delete 'and the '}'
                              rng.Copy
                              Set fld = ActiveDocument.Fields.Add(rng, wdFieldEmpty, rng.Text, False)
                              fld.Code.Paste 'VBA bug. The line above corrupts nested fields, so we replace the range
                              Set rng = GetField(rng1)
                          Loop
                      End Sub
                      
                      Function GetField(rng As Range) As Range
                          Dim rngStart As Long
                          Dim rng1 As Range
                          Dim bFound As Boolean
                          
                          'looks for a potential field i.e. text bracketed with "{" and "}", but no contained "{"
                          Set rng1 = rng.Duplicate
                          bFound = True
                          Do While bFound
                              With rng1.Find
                                  bFound = False
                                  .Text = "{"
                                  .MatchWildcards = False
                                  If .Execute Then
                                      bFound = True
                                      rngStart = rng1.Start
                                      rng1.Collapse wdCollapseEnd
                                      rng1.End = rng.End
                                      .MatchWildcards = True
                                      .Text = "[\{\}]{1}"
                                      If .Execute Then
                                          If rng1.Characters.First.Text = "}" Then
                                              rng1.Start = rngStart
                                              Set GetField = rng1.Duplicate
                                              Exit Function
                                          End If
                                      End If
                                      rng1.Start = rngStart + 1
                                      rng1.End = rng.End
                                  End If
                              End With
                          Loop
                      End Function
                      

Open in new window

As an adjunct, if you already have a worked-out field complex, and you want to show it outside of a Word document, this will do the rather simpler task of creating text from the fields.    
Sub CallFieldsToText()
                          Dim rng As Range
                          Set rng = Selection.Range
                          FieldsToText rng
                      End Sub
                      
                      Sub FieldsToText(rng As Range)
                          Dim fld As Field
                          Dim rnga As Range
                          Dim rnge As Range
                          
                          For Each fld In rng.Fields
                              Set rnga = fld.Code
                              rnga.Copy
                              fld.Delete
                              rnga.Paste
                              Set rnge = rnga.Duplicate
                              rnga.Collapse wdCollapseStart
                              rnga.Text = "{"
                              rnge.Collapse wdCollapseEnd
                              rnge.Text = "}"
                          Next fld
                      
                      End Sub
                      

Open in new window


To enter the macros into your Word template, switch to the VBA editor using Alt+F11.  The default top-left pane is the Project Explorer window. If you can’t see it, try using Ctrl+R to open it.

One of the projects will be the Normal project which holds the code for the Normal template. Use this project unless you have a reason to use another. All macros in the Normal template will be available to all documents. The code must go into a module, so if there are none in the project, add one via the Insert menu.

The code editor pane is the large one at the top-right. Paste or type your code in here.

While you have the VBA IDE open, you can easily run any macro that does not have any input parameters (aka arguments); macros which do have parameters have to be called from another macro. Simply place the text cursor somewhere in the macro code and press F5.

The two procedures to start here are the CallTextToFields and CallFieldsToText Subs. Set the document to show fields codes (Alt+F9). Select the text that you wish to convert and run the relevant procedure.
5
9,662 Views
GrahamSkanRetired
CERTIFIED EXPERT

Comments (3)

CERTIFIED EXPERT
Most Valuable Expert 2011
Awarded 2010

Commented:
Hello,

This sounds like a very useful and interesting concept. Unfortunately, neither of the above work with Word 2010. The first macro errors out on the line

   Debug.Print rng.Text

with the message "Object variable or With block variable not set".

The second macro errors out with "Wrong number of arguments or invalid property assignment" and highlights

FieldsToText

in the line

    FieldsToText rng

of the sub

Sub CallFieldsToText()

I've placed the code in a standard module in my Normal template. I open the document with the field codes, hit Alt-F9 to show field codes and select the field code block, then run either Sub CallTextToFields() or Sub CallFieldsToText()

What am I doing wrong?
GrahamSkanRetired
CERTIFIED EXPERT
Top Expert 2012

Author

Commented:
Thank you teylyn.

You did nothing wrong, and it's not the Word version.

I seem to have pasted test versions in at some time. I have now replaced them with newer versions.
CERTIFIED EXPERT
Most Valuable Expert 2011
Awarded 2010

Commented:
Wow! Very neat.

Thank you !!!

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.