• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1022
  • Last Modified:

Change Word Field Types in Documents

Microsoft Word VBA Code /macro needed

I'd like to loop thru Word documents in a directory, open each document and change each Word field's type (WdFieldType) in each document to a "Mergefield" type.

This is what fields are in a sample doc now as an example:


Here is the macro I wrote to tell what the supposed Boookmarks really were:

Sub IdentifyFields()

Dim f As Word.Field
Dim b As Word.Bookmark

For Each f In ActiveDocument.Fields
    Debug.Print ("Field Index: " & f.Index & " Field Code: " & f.Code & " Type: " & f.Type & " Kind: " & f.Kind & " ")
Next f

End Sub
Here is the result (The only bookmark was the one I added as a test):

Field Index: 1 Field Code:  OrdClosingDate_1_14_0  Type: 3 Kind: 2
Field Index: 2 Field Code:  OrdDPSell1.1_1_0_0  Type: -1 Kind: 0
Field Index: 3 Field Code:  SellVestTxt_2_0_2  Type: 3 Kind: 2
Field Index: 4 Field Code:  GrantorAddress_1_0_0  Type: 3 Kind: 2
Field Index: 5 Field Code:  SellNameFL_23_0_2  Type: 3 Kind: 2
Field Index: 6 Field Code:  SellNameFL_26_0_2  Type: 3 Kind: 2
Field Index: 7 Field Code:  OrdDPBuy1.1_1_0_0  Type: -1 Kind: 0
Field Index: 8 Field Code:  GranteeAddress_1_0_0  Type: 3 Kind: 2
Field Index: 9 Field Code:  BuyNameFL_24_0_2  Type: 3 Kind: 2
Field Index: 10 Field Code:  BuyNameFL_29_0_2  Type: 3 Kind: 2
Field Index: 11 Field Code:  OrdSalesPrice_1_1_0  Type: 3 Kind: 2
Field Index: 12 Field Code:  OrdSalesPrice_2_0_0  Type: 3 Kind: 2
Field Index: 13 Field Code:  SellNameFL_31_0_2  Type: 3 Kind: 2
Field Index: 14 Field Code:  SellNameFL_32_0_2  Type: 3 Kind: 2
Field Index: 15 Field Code:  OrdDPBuy1.1_2_0_0  Type: -1 Kind: 0
Field Index: 16 Field Code:  OtherTenancyLang_1_0_0  Type: 3 Kind: 2
Field Index: 17 Field Code:  DoYouWantLots_1_0_0  Type: 3 Kind: 2
Field Index: 18 Field Code:  OrdPrimCntyName_3_0_0  Type: 3 Kind: 2
Field Index: 19 Field Code:  Legal_1_0_0  Type: 3 Kind: 2
Field Index: 20 Field Code:  HomesteadLanguageY/N_1_0_0  Type: -1 Kind: 0
Field Index: 21 Field Code:  HomesteadLanguageY/N_2_0_0  Type: -1 Kind: 0
Field Index: 22 Field Code:  OwnerOccLangSoleY/N_2_0_0  Type: -1 Kind: 0
Field Index: 23 Field Code:  OwnerOccLang2MoreBwrrsY/N_2_0_0  Type: -1 Kind: 0
0
swendell
Asked:
swendell
  • 10
  • 5
1 Solution
 
GrahamSkanCommented:
At first glance, there seem to be a number of problems with what you are trying to do.

Firstly, a merge field needs to be of the general format

{ MERGEFIELD fieldname } where fieldname refers to a field name in a specified data source

Secondly, only Form Fields can have a bookmark to define their positions in a document, so the question is quite confusing
0
 
swendellAuthor Commented:
Here are the advanced field properties for one specific MERGEFIELD field code I wish to convert TO:
MERGEFIELD  RESWARE_SP_GetBuyerSellerCityStateZip_Buyer_1

Above you can see the debug.print of some fields and their .FieldTypes I am converting FROM.

So for the first one; I would like the field changed to be:
MERGEFIELD OrdClosingDate_1_14_0
It will work if I change the type to MERGEFIELD, a 3ed party module interprets and replaces these Word MergeFields.

Maybe cut the current Word Field while saving Word.Field.code then .add a new MergeField in the position with the saved Word.Field.code ?
0
 
swendellAuthor Commented:
One step closer,
This code successfully found and replaced the first field with a mergefield
Unfortunately it did not move onto the next field in the loop to continue replacing the remaining fields in the document, but a great start

Dim f As Word.Field
Dim MyRange As Object

For Each f In ActiveDocument.Fields
     Debug.Print ("Field Index: " & f.Index & " Field Code: " & f.Code & " Type: " & f.Type & " Kind: " & f.Kind & " ")
     
f.Select

Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
        "MERGEFIELD OrdClosingDate_1_14_0", PreserveFormatting:=False
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend

Next f

End Sub
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
GrahamSkanCommented:
Sorry. I thought that I posted some code last night. The way round that problem  is to use indexing instead of For Each. Modifying the field modifies the Fields collection, so the Next doesn't work. This is what I wrote last night:
Sub ChangeToMergeFields()
    Dim fld As Field
    Dim rng As Range
    Dim strWords() As String
    Dim strText As String
    
    Dim w As Integer
    Dim f As Integer
    
    For f = 1 To ActiveDocument.Fields.Count
        Set fld.Kind = ActiveDocument.Fields(f)
        Set rng = fld.Code
        strText = rng.Text
        strWords = Split(strText, " ")
        For w = 0 To UBound(strWords)
            If Len(Trim(strWords(w))) > 0 Then
                strWords(w) = "MERGEFIELD"
                Exit For
            End If
        Next w
        strText = Join(strWords, " ")
        fld.Delete
        ActiveDocument.Fields.Add rng, wdFieldEmpty, strText
    Next f
End Sub

Open in new window

0
 
swendellAuthor Commented:
Error: Invalid use of property - KIND
Set fld.Kind = ActiveDocument.Fields(f)
0
 
GrahamSkanCommented:
Yes that is not surprising.

I have no idea where that came from. The code worked 24 hours ago. It is trying to set a field property to the field object itself.

It should be:
Set fld = ActiveDocument.Fields(f)
0
 
swendellAuthor Commented:
It is inserting Mergefields without a field name where the old fields were. That is GREAT; Now we need to save the old field name then use it when adding this new MERGEFIELD so the MERGEFIELD name will not be empty  

It should look like: {MERGEFIELD OrdClosingDate_1_14_0}
Now it looks empty like this:  { MERGEFIELD \* MERGEFORMAT}
0
 
swendellAuthor Commented:
Maybe I should have attached this to begin with....
FM000391.doc
0
 
GrahamSkanCommented:
That certainly helps.

None of the fields in your document have a field type name in them. This makes them, by default, REF fields. REF fields display the text of the given bookmark name (the first word in the field, or the second if it us "REF").

When I said 'last night',  it was really so. I'm on GMT, so it's nearly midnight here. I'll try to get back in about eight hours' time
0
 
swendellAuthor Commented:
Thank you so much!!!!!!!!!!!
I was able to get the field name/code in my originally posted example so I guess you know what to do. The last piece is a loop that will:
- loop thru a directory of the docs to be converted. For example: C:\Input
- save each converted document with same name to a folder like C:\Output
0
 
GrahamSkanCommented:
Here is some code to loop through a folder and to save the modified document.
Some tweaks were necessary to the original procedure, so that is also here.
Sub ProcessFiles()
    Dim strFile As String
    Dim strInFolder As String
    Dim strOutFolder As String
    Dim doc As Document
    
    strInFolder = "C:\Input"
    strOutFolder = "C:\Output"
    
    strFile = Dir$(strInFolder & "\*.doc*")
    Do Until strFile = ""
        Set doc = Documents.Open(strInFolder & "\" & strFile)
        ChangeToMergeFields doc
        doc.SaveAs strFile & "\" & strOutFolder
        doc.Close
        strFile = Dir$()
    Loop
End Sub


Sub ChangeToMergeFields(doc As Document)
    Dim fld As Field
    Dim rng As Range
    Dim strWords() As String
    Dim strText As String
    
    Dim w As Integer
    Dim f As Integer
    
    For f = 1 To doc.Fields.Count
        Set fld = doc.Fields(f)
        Set rng = fld.Code
        strText = rng.Text
        strWords = Split(strText, " ")
        For w = 0 To UBound(strWords)
            If Len(Trim(strWords(w))) > 0 Then
                strWords(w) = "MERGEFIELD"
                Exit For
            End If
        Next w
        strText = Join(strWords, " ")
        fld.Delete
        doc.Fields.Add rng, wdFieldEmpty, strText
    Next f
End Sub

Open in new window

0
 
swendellAuthor Commented:
I am driving for the next day or two but will test it when I stop, thank you so much for all the help, I'd like to send you a gift of appreciation like an amazon gift card not just points,  just don't know where to send it...
0
 
swendellAuthor Commented:
Just at a glance I reversed the output file path but I do not think the new Mergefields have any field names...
0
 
swendellAuthor Commented:
OK , I fixed the output path and added Mergefield name, It 'seems' OK, but I will need to test to confirm:

Sub ProcessFiles()
    Dim strFile As String
    Dim strInFolder As String
    Dim strOutFolder As String
    Dim doc As Document
    
    strInFolder = "C:\AIMInput"
    strOutFolder = "C:\AIMOutput"
    
    strFile = Dir$(strInFolder & "\*.doc*")
    Do Until strFile = ""
        Set doc = Documents.Open(strInFolder & "\" & strFile)
        ChangeToMergeFields doc
        doc.SaveAs strOutFolder & "\" & strFile
        doc.Close
        strFile = Dir$()
    Loop
End Sub


Sub ChangeToMergeFields(doc As Document)
    Dim fld As Field
    Dim fldsave As String ' this is the field to store te old field name before we replce it
    
    Dim rng As Range
    Dim strWords() As String
    Dim strText As String
    
    Dim w As Integer
    Dim f As Integer
    
    For f = 1 To doc.Fields.Count
        Set fld = doc.Fields(f)
        Set rng = fld.Code
        fldsave = rng.Text
        strText = rng.Text
        strWords = Split(strText, " ")
        For w = 0 To UBound(strWords)
            If Len(Trim(strWords(w))) > 0 Then
                strWords(w) = "MERGEFIELD" & " " & fldsave ' added missing Mergefield name
                Exit For
            End If
        Next w
        strText = Join(strWords, " ")
        fld.Delete
        doc.Fields.Add rng, wdFieldEmpty, strText
    Next f
End Sub

Open in new window

0
 
swendellAuthor Commented:
Sorry I took so long to test over the holiday but you got the essence of it very well
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 10
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now