Search code examples
vbams-worduserform

Userform to fill in bookmarks across multiple Word documents?


I've created a userform in Word that auto-fills a contract with a consultant's name, address, etc. However, I have multiple contracts that I send to each consultant and I would like to be able to input the information once and have it populate all the contracts.

I tried searching for how this would work but I've been unable to cobble the bits and pieces that I've learned into a successful execution.

Here's the code for my userform on a single document in case it's relevant -- if I could even have this exact form populating multiple documents it would be a huge time saver.

Private Sub CancelButton_Click()
    ConsultantInfo.Hide
End Sub

Private Sub FillButton_Click()
    Dim consultantName1 As Range
    Set consultantName1 = ActiveDocument.Bookmarks("ConsultantName1").Range
    Dim consultantName2 As Range
    Set consultantName2 = ActiveDocument.Bookmarks("ConsultantName2").Range
    Dim consultantName3 As Range
    Set consultantName3 = ActiveDocument.Bookmarks("ConsultantName3").Range
    Dim consultantNameCaps As Range
    Set consultantNameCaps = 
    ActiveDocument.Bookmarks("ConsultantNameCaps").Range
    consultantName1.Text = Me.TextName.Value
    consultantName2.Text = Me.TextName.Value
    consultantName3.Text = Me.TextName.Value
    consultantNameCaps.Text = Me.TextName.Value
    consultantNameCaps.Font.AllCaps = True
    Dim consultantTitle As Range
    Set consultantTitle = ActiveDocument.Bookmarks("ConsultantTitle").Range
    consultantTitle.Text = Me.TextTitle.Value
    Dim consultantAddress1 As Range
    Set consultantAddress1 = 
    ActiveDocument.Bookmarks("ConsultantAddress1").Range
    consultantAddress1.Text = Me.TextAddress1.Value
    Dim consultantAddress2 As Range
    Set consultantAddress2 = 
    ActiveDocument.Bookmarks("ConsultantAddress2").Range
    consultantAddress2.Text = Me.TextAddress2.Value
    Me.Repaint
    ConsultantInfo.Hide
End Sub

Private Sub FillSaveButton_Click()
    Dim consultantName1 As Range
    Set consultantName1 = ActiveDocument.Bookmarks("ConsultantName1").Range
    Dim consultantName2 As Range
    Set consultantName2 = ActiveDocument.Bookmarks("ConsultantName2").Range
    Dim consultantName3 As Range
    Set consultantName3 = ActiveDocument.Bookmarks("ConsultantName3").Range
    Dim consultantNameCaps As Range
    Set consultantNameCaps = 
    ActiveDocument.Bookmarks("ConsultantNameCaps").Range
    consultantName1.Text = Me.TextName.Value
    consultantName2.Text = Me.TextName.Value
    consultantName3.Text = Me.TextName.Value
    consultantNameCaps.Text = Me.TextName.Value
    consultantNameCaps.Font.AllCaps = True
    Dim consultantTitle As Range
    Set consultantTitle = ActiveDocument.Bookmarks("ConsultantTitle").Range
    consultantTitle.Text = Me.TextTitle.Value
    Dim consultantAddress1 As Range
    Set consultantAddress1 = 
    ActiveDocument.Bookmarks("ConsultantAddress1").Range
    consultantAddress1.Text = Me.TextAddress1.Value
    Dim consultantAddress2 As Range
    Set consultantAddress2 = 
    ActiveDocument.Bookmarks("ConsultantAddress2").Range
    consultantAddress2.Text = Me.TextAddress2.Value
    ActiveDocument.SaveAs2 FileName:=ActiveDocument.Path & "\Consulting 
    Agreement Master " & consultantName1, FileFormat:=wdFormatDocument
    ActiveDocument.SaveAs2 FileName:=ActiveDocument.Path & "\Consulting 
    Agreement Master " & consultantName1, FileFormat:=wdFormatPDF
    Me.Repaint
    ConsultantInfo.Hide
End Sub

Solution

  • It is possible to link Word documents to content within bookmarks of another document using IncludeText fields. But this means you need to retain the bookmarks in that "source" document. Your code, as it stands, is probably deleting the bookmarks. Example how you need to change your code to make sure the data is inside a bookmark after writing the data to the bookmark:

    Dim doc as Word.Document
    Set doc = ActiveDocument
    Dim rngConsultantNameCaps As Range
    Dim sConsultantNameCaps as String
    sConsultantNameCaps = "ConsultantNameCaps"
    Set rngConsultantNameCaps = doc.Bookmarks(sConsultantNameCaps).Range
    rngConsultantNameCaps.Text = Me.TextName.Value
    doc.Bookmarks.Add(sConsultantNameCaps, rngConsultantNameCaps)
    

    Open each document (except the "data template") and replace each bookmark with the field:

    { IncludeText "Path and filename" "bookmarkName" }
    

    (Remember that the { } brackets need to be inserted using Ctrl+F9 if you're doing it manually.)

    If all the documents are going to be saved in the same folder the entire path is not necessary - the file name of the source is enough. Word looks automatically in the same folder for the source file.

    The link will also bring across character formatting. If you don't want that, add the \* CharFormat switch to the field code to force it to keep the format applied to the first character of the field:

    { IncludeText "Path and filename" "bookmarkName" \* CharFormat }
    

    If there are a number of documents it would probably even make sense to write a macro to do this: just loop the bookmarks, save the bookmark name, insert the field at that range with the bookmark name.

    The documents would need to be opened individually at a later point and the fields updated (can also be done when printing them).

    Note that it's also possible to use a Link field, but that field type communicates using OLE, which is a bit "overkill" for mirroring "simple" text.