Results 1 to 8 of 8
  1. #1
    New Lounger
    Join Date
    Apr 2014
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Macro to Replace all red words in a document with a docvariable field

    I want to make preparing a dotx template simple for a typist.
    I say create the letter and format the font colour of all the variable bits to RED.
    Overtype the Red Words with a descriptive single word. ie Mrs Jones becomes GREETING
    repeats are fine so John Smith becomes AGENT wherever it occurs.
    Finally run the macro and save the dotx.

    I have the Access code to set the DOCVARIABLES to data from the database already written.

    So when the typist wants to write a letter from Access she just presses a button and ..........bingo.

    The typist doesnt have to know anything about bookmarks or docvariables and all that odd stuff.
    Trouble is its so weird I cant get it to work as I want!

    The Docvariable name is taken from the red word it replaces.

    I am sorry I dont know if you can post code here or not but here it is anyway

    ActiveDocument.Content.Select

    With Selection.Find
    .Font.Color = wdColorRed
    End With
    Do While Selection.Find

    If Selection.Find.Execute Then
    Selection.Select
    myVar = Selection.Text
    Debug.Print myVar
    Selection.Fields.Add Range:=Selection.Range, _
    Type:=wdFieldEmpty, _
    Text:="DOCVARIABLE " & myVar, _
    PreserveFormatting:=True

    End If
    Loop

    This does not work for me, I use WORD 2010. I get stuck in the loop putting in infinite docvariable lines.
    help please

  2. #2
    Super Moderator
    Join Date
    May 2002
    Location
    Canberra, Australian Capital Territory, Australia
    Posts
    3,979
    Thanks
    0
    Thanked 208 Times in 189 Posts
    You could use code like:
    Code:
    Sub Demo()
    Application.ScreenUpdating = False
    Dim Rng As Range
    With ActiveDocument.Range
      With .Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Text = ""
        .Font.Color = wdColorRed
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindStop
        .Format = True
        .Execute
      End With
      Do While .Find.Found
        Set Rng = .Duplicate
        .Font.ColorIndex = wdAuto
        .Fields.Add Rng, wdFieldEmpty, "DOCVARIABLE " & .Text, False
        .End = Rng.End + 1
        .Collapse wdCollapseEnd
        .Find.Execute
      Loop
    End With
    Application.ScreenUpdating = True
    End Sub
    PS: When posting code, please use the code tags. They're on the 'Go Advanced' tab at the bottom of this screen.
    Cheers,

    Paul Edstein
    [MS MVP - Word]

  3. #3
    Silver Lounger Charles Kenyon's Avatar
    Join Date
    Jan 2001
    Location
    Madison, Wisconsin, Wisconsin, USA
    Posts
    1,720
    Thanks
    59
    Thanked 66 Times in 64 Posts
    Paul, yours is better than mine. This is what I came up with. I had trouble with the .find.found and so had to use a substitute variable at the start.

    Code:
    Sub FindRedAddDocVariable()
    '
    '
    Dim strVar As String, bFound As Boolean
    bFound = True
    '
        Application.ScreenUpdating = False
        ActiveDocument.ActiveWindow.View.ShowFieldCodes = True
        Selection.Find.ClearFormatting
        Selection.Find.Font.Color = wdColorRed
        With Selection.Find
            .Text = ""
            .Replacement.Text = ""
            .Forward = True
            .Wrap = wdFindContinue
            .Format = True
            .MatchCase = False
            .MatchWholeWord = True
            .MatchWildcards = False
            .MatchSoundsLike = False
            .MatchAllWordForms = False
        End With
        ' LOOP FROM HERE
        '
        Do While bFound
        Selection.Find.Execute
        bFound = Selection.Find.Found
        If bFound = False Then GoTo ExitLoop
        Selection.Font.ColorIndex = wdAuto
        strVar = Selection.Text
    '    MsgBox strVar
        Application.ScreenUpdating = False
        '
        '   Insert DocVariable field with selected text
        With Selection
          .Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, _
            PreserveFormatting:=False, Text:="DocVariable " & strVar
          .Fields.Update
        End With
        Loop
    ExitLoop:
        ActiveDocument.ActiveWindow.View.ShowFieldCodes = False
        Application.ScreenUpdating = True
    
        '
        
    End Sub
    Charles Kyle Kenyon
    Madison, Wisconsin

  4. #4
    New Lounger
    Join Date
    Apr 2014
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Thanks Paul and Charles. I will see if I can incorporate this in my project and report back. Sorry about the lack of code tags in my virgin post. Regards Alan.

  5. #5
    Silver Lounger Charles Kenyon's Avatar
    Join Date
    Jan 2001
    Location
    Madison, Wisconsin, Wisconsin, USA
    Posts
    1,720
    Thanks
    59
    Thanked 66 Times in 64 Posts
    You are welcome. We are all learning. Paul's code is both cleaner and more elegant than mine. Especially with a long document, his is likely to be faster.
    Charles Kyle Kenyon
    Madison, Wisconsin

  6. The Following User Says Thank You to Charles Kenyon For This Useful Post:

    alan@flower-studio.com (2014-04-21)

  7. #6
    New Lounger
    Join Date
    Apr 2014
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Ok I have used Paul's code with a small change to put " at the start and end of the field names. That works fine for me.

    Code:
    Do While .Find.Found
        Set Rng = .Duplicate
        mystr = Chr(34) & .Text & Chr(34)
        .Font.ColorIndex = wdAuto
        .Fields.Add Rng, wdFieldEmpty, "DOCVARIABLE " & mystr, False
        ''''''''''''''''POINT'''''''''''''''''''''''
         .End = Rng.End + 1
        .Collapse wdCollapseEnd
        .Find.Execute
      Loop
    End With
    I then added, just for a test,

    Code:
    appWord.ActiveDocument.Variables.Item("ConsFullName").Value = Me.cmbConsultant.Column(0)
    appappWord.ActiveDocument.Variables.Item("Letterdate").Value = Me.txtDateforLetterWord.ActiveDocument.Variables.Item("ConsFirstName").Value = Me.cmbConsultant.Column(1)
    appWord.ActiveDocument.Variables.Item("AddressBlock").Value = Me.txtAddressBlock
    appWord.ActiveDocument.Variables.Item("SigBlock").Value = Me.cmbSig & vbCrLf & cmbSig.Column(1)
    appWord.ActiveDocument.Variables.Item("Greeting").Value = Me.txtGreeting

    My next plan is not to hard code the values like that but
    to put something like this in the loop above ' at the place marked 'POINT'

    Code:
    For Each ctl In Me.Controls
    IF Ctl.Type = vbtextBox or ctl.type = vbCombobox Then
      If Ctl.Tag = ? Then
        If ctl.name = "txt" & mystr then
          my val = ctl.name.value
          appWord.ActiveDocument.Variables.Item(myStr).Value = myVal
        End If
      End If
    End If
    Next

    Provided the text boxes and combo boxes are named right and have the tags set to ? it might work
    If it eventually works I will have a generic system to handle any letter.dotx chosen in a combo on the form.

    Finally I want to set the header and footer to match one of three letterhead templates. I have no idea how to do that

    Thanks for you kind help
    Regards Alan

  8. #7
    Super Moderator
    Join Date
    May 2002
    Location
    Canberra, Australian Capital Territory, Australia
    Posts
    3,979
    Thanks
    0
    Thanked 208 Times in 189 Posts
    I wonder if there is some sort of disconnect between your understanding of DOCVARIABLES and DOCVARIABLE fields?

    The code you use to update the DOCVARIABLES seems OK as far as it goes. However, there shouldn't be any need to modify the DOCVARIABLE fields in the document on that account. Those fields should point to a DOCVARIABLE; that's where they get their results from. For example, you have a DOCVARIABLE named "ConsFullName". In the document, you should also have a DOCVARIABLE field pointing to that DOCVARIABLE. The field would be coded as {DOCVARIABLE "ConsFullName"}. Then, whenever you update the DOCVARIABLE, all you need for updating the fields is 'Activedocument.Fields.Update' - an you need only do this once, after all the variables are updated. If there are DOCVARIABLE fields in the document header/footer, toggling Print Preview will update them.
    Cheers,

    Paul Edstein
    [MS MVP - Word]

  9. The Following User Says Thank You to macropod For This Useful Post:

    alan@flower-studio.com (2014-04-21)

  10. #8
    New Lounger
    Join Date
    Apr 2014
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Solved

    Of course you are correct Paul. I have a poor understanding of fields and bookmarks, better now mind you, since this project. I don't feel alone in this as I am sure many folk find the principle and syntax far from intuitive and there seem to be myriad gotchas. When I finally get my head around it all I might write A Dummies guide to Document Fields. Meanwhile thanks to you and Charles. I will now close this subject as SOLVED.
    Regards
    Alan

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •