DEVTOME.COM HOSTING COSTS HAVE BEGUN TO EXCEED 115$ MONTHLY. THE ADMINISTRATION IS NO LONGER ABLE TO HANDLE THE COST WITHOUT ASSISTANCE DUE TO THE RISING COST. THIS HAS BEEN OCCURRING FOR ALMOST A YEAR, BUT WE HAVE BEEN HANDLING IT FROM OUR OWN POCKETS. HOWEVER, WITH LITERALLY NO DONATIONS FOR THE PAST 2+ YEARS IT HAS DEPLETED THE BUDGET IN SHORT ORDER WITH THE INCREASE IN ACTIVITY ON THE SITE IN THE PAST 6 MONTHS. OUR CPU USAGE HAS BECOME TOO HIGH TO REMAIN ON A REASONABLE COSTING PLAN THAT WE COULD MAINTAIN. IF YOU WOULD LIKE TO SUPPORT THE DEVTOME PROJECT AND KEEP THE SITE UP/ALIVE PLEASE DONATE (EVEN IF ITS A SATOSHI) TO OUR DEVCOIN 1M4PCuMXvpWX6LHPkBEf3LJ2z1boZv4EQa OR OUR BTC WALLET 16eqEcqfw4zHUh2znvMcmRzGVwCn7CJLxR TO ALLOW US TO AFFORD THE HOSTING.

THE DEVCOIN AND DEVTOME PROJECTS ARE BOTH VERY IMPORTANT TO THE COMMUNITY. PLEASE CONTRIBUTE TO ITS FURTHER SUCCESS FOR ANOTHER 5 OR MORE YEARS!

Programming Microsoft Word - 08 - Populating a Word Document

What are we going to do in this tutorial?

In the previous tutorial, you tackled the topic of reusing code. This topic is not over by a long shot, but you covered some ground, enough to think about structuring your code to benefit from reusing code. In this tutorial, we move to the Word document itself. After all, the whole idea of this course is to automate the creation of Word documents.

This tutorial covers two methods to insert input programmatically into a Word document; by using bookmarks and by using the 'find and replace' function of Microsoft Word. You need to do two things for each method: prepare a suitable Word document and use specific code to fill in that Word document.

Because two methods will be shown including preparation of the related Word documents, this tutorial will be quite large compared to the other tutorials. Although overlapping previous tutorials a bit, we are going to start from scratch.

Step 1

First, we are going to prepare 2 Word documents. The Word documents will be prepared as .dotx documents, meaning as a 'template'. We can build the two templates from on Word document.

Start Word and open a new Word document. Type the following text in the Word document.

Now, replace the text with '**' (2 instances in the text) with '[name]' without the quotes. The [name] tag is plain text and this can be helpful as I will show later on. Time to save this document as our first template (I named the document 'FandR.Template.dotx (Find and Replace)). Saving the document as template is shown in the picture below.

Office button → Save as → Save as template

You can build the 2nd template from the same document. We are going to insert bookmarks at the spots where the '[name]' tags are shown. Select the text of the first [name] tag with the cursor so that it is highlighted in blue. Under the Word Ribbon under Insert, there is a button 'bookmarks' under the 'links' section (see picture below).

When clicking the 'bookmark' button, the bookmarks windows that pops up shows a blank list of bookmarks. Just type the name of your first bookmark (I suggest 'Name1') and press the 'Add' button. Close the bookmarks window and select the 2nd instance of '[name]' in your Word document. Again, press the bookmark button, type the name of the 2nd bookmark and press 'Add' (I suggest 'Name2'). You could actually name the 2nd instance of '[name]' Name1 as well, but then the 1st bookmark you created will be deleted. This is particular behaviour of bookmarks and you do not get a warning.

Now that you have inserted 2 bookmarks in the Word document, save the document again as a template, but give it the name 'Bkm.Template.dotx'. You can close Word now.

Step 2

Time to fire up Visual Studio. I assume you already know your way around the Visual Studio Interface so we can quickly go through the first steps. Start a new project: File → new project → choose Windows Forms Application → give it the name 'InteropInsertTextinWordDoc'.

Step 3

You have to insert references to the Word object model (like you did in previous tutorials). Goto: Project → Add Reference → click the 'COM' tab → type 'Word' in the search field. In my occassion, the search results in, inter alia, a reference to the Microsoft Word 12.0 Object Library. Depending on the Office/Word version installed on your PC, the version number may vary. Select this library and add a reference to it by clicking 'OK'.

One more thing to do before we start with some real programming. On top of the form1 insert the line 'Imports Microsoft.Office.Interop' as shown in the picture below. You can get to the code of the form by double clicking the graphic presentation of form1 in the Visual Studio IDE.

Step 4

Add the 2 Word templates you just created to your project. To do so, right-click the project name and go through the menu that appears: Add → Existing Item.

In the resulting Dialog box, make sure to select 'All Files (*.*)' in the file name filter dialog box. Otherwise, your Word template documents won't show as selectable files.

Go and find the location of the 2 Word templates you created in step 1. Add those 2 files to your project. You can see that the two files have been added to your project. If you save your project, you can actually find the 2 files in the project's file folder. They were copied into your project.

Just to avoid any problems, make sure to set the properties for each file to 'Copy always' (see picture):

Step 5

Build Form 1 so it looks as shown below (1 textbox and 2 buttons).

I did not change the default names for the labels, textboxes and buttons when creating these controls on the form.

Step 6

Now for the coding, this will get a little intense. You will code two procedures; one for each button. The first procedure will insert text at bookmarks in a Word document and the second procedure will insert text at name tags in a Word Document.

Each procedure will use a separate procedure to open a Word template document. You will create this procedure in a separate class. The procedure to open this Word template (or better said: create a new Word document on the basis of a Word template) can subsequently be used by both main procedures. The strength of using a Word template is that the template itself is not opened, but instead, a new Word document will be opened (that the user can save, based on the chosen template).

You will have to use the code from the previous tutorial, but then slightly changed. You will have to code one block of code that opens a template. You can use that block of code for both main procedures.

Right click on your project in the Solution Explorer and go through the menu: Add → Class

Name your class 'WordActions.vb' and press 'OK'. In the Solution Explorer, you will see your WordActions class added to your project.

Double click the WordActions class in the Solution explorer to get to the code.

On top of this class (above the start line 'Public Class WordActions'), add a reference: 'Imports Microsoft.Office.Interop' (see picture below).

Create a new procedure in this class named 'OpenWordTemplate' (see picture below).

Specifically note that you are going to feed this procedure with a 'doc' variable, explaining to this code which Word template to open. The function will return a Word object as well (the 'Word.Document')', so you can continue to work with the Word document just opened once the code execution returns to your Form1. This is expressed by the final addition at the end of the Function's first line: ' Public Shared Function …… As Word.Document'). We are going to look into this a bit further below.

Enter the following code between the two lines 'Public Shared Function OpenWordTemplate( … ' and 'End Function'

      'Procedure OpenWordTemplate()
        '
        '1. check whether Word is running
        '2. if so, create a new document based on the supplied doc variable (a Word template)
        '3. if not, start word and then create a new document based on the supplied doc variable (a Word template)
        '
        '======================================
        'Code to check whether Word is running
        'courtesy of Cindy Meister, VSTO/Word MVP

Dim oWord As Word.Application
        Dim oDoc As Word.Document
        Dim appName As String = "Word.Application"
        Dim wdProcesses() As System.Diagnostics.Process = _
          System.Diagnostics.Process.GetProcessesByName("winword")
        Dim wdprocess As System.Diagnostics.Process

        For Each wdprocess In wdProcesses
            System.Diagnostics.Debug.Print(wdprocess.MainWindowTitle)
            System.Diagnostics.Debug.Print(wdprocess.StartInfo.Arguments.Length.ToString())
        Next

        'If Word is running, attach oWord to that instance of Word
        If wdProcesses.Length > 0 Then
            oWord = System.Runtime.InteropServices.Marshal.GetActiveObject(appName)
            'if Word is not running, start new instance of Word
        Else
            oWord = New Word.Application
        End If
        If Not oWord Is Nothing Then
            oWord.Visible = True
            oWord.Activate()
        End If
        oWord.Visible = True
        '======================================

        'open new Word document based on the basic template
        oDoc = oWord.Documents.Add(doc)

        Return oDoc
        oDoc = Nothing
        oWord = Nothing

The first part of this code (between the '====' characters) deals with checking whether an instance of Microsoft Word is already running. We covered this code in the previous tutorial. The next part of the code simply takes the value of the 'doc' variable specified (the location of your Word template file) and opens this template as a new Word document (the command 'oDoc = oWord.Documents.Add(doc)'). Note that the command 'Add' is used and not the command 'Open'. The command 'Open' would open the Word template file itself, which is not the behaviour we are looking for.

The line 'Return oDoc' is part of the cryptic explanation. As stated above, this Function is specified to 'return' a Word.Document. What this means is that the code in this function in the WordActions class creates a new instance of a Word document (a Word object). That Word object (which includes the just opened Word document, the 'Word.Document' object) is returned to the Form1 code during execution.

Step 7

Now that you got the internals set up, it is time to check whether those internals work. Switch back to the code of Form1 and insert the following code (see picture below).

Place the following code in the subroutine for Button1 (double click Button1 to get to the code section):

        Dim oDoc As Word.Document

        'open Word template based on the Bookmark Template
        oDoc = WordActions.OpenWordTemplate("Bkm.Template.dotx")


        'code to insert text at a bookmark in the opened Word template
        oDoc.Bookmarks("Name1").Range.Text = TextBox1.Text
        oDoc.Bookmarks("Name2").Range.Text = TextBox1.Text

Button 1 is associated with inserting text into bookmarks. First, you define the variable 'oDoc' as placeholder for the Word document to be created. The command to create a new Word document on the basis of the Bkm.Template.dotx template (the function called 'OpenWordTemplate') is the function we created in the WordActions class. To access this function, we refer to the WordActions class before specifying this function. The name of our template 'Bkm.Template.dotx' is fed into this function as parameter.

The code to insert text at the bookmarks in the Word template is simple. The command 'oDoc.Bookmarks(”[name_of_bookmark”).Range.Text' takes the text specified (the text element of our textbox1) and places it as text in the Word document at the specified bookmark.

This makes clear why it is important that the function to open the Word document (on the basis of the template returns that Word document to form1. Otherwise, the code in form1 does not now which oDoc variable is specified when issuing the command to insert text in a bookmark.

Run the code and press the first button (in my example named 'Insert @Bookmark'). Your Word template is opened as a new Word document. You can open more Word documents based on the same template by pressing the button again. The template remains untouched; instead a new Word document is opened that a user can edit and save.

As a final conclusion of this step, insert the following code for Button 2 (double click Button2 to get to the code section):

Dim oWord As Word.Application = Nothing

        'open Word template based on the Bookmark Template
        oWord = WordActions.OpenWordTemplate2("FandR.Template.dotx", oWord)


        'code to insert text at a bookmark in the opened Word template
        'Find and replace tag [name] with input from textbox1

        Dim FindObject As Word.Find = oWord.Application.Selection.Find
        With FindObject
            .ClearFormatting()
            .Text = "[name]"
            .Replacement.ClearFormatting()
            .Replacement.Text = TextBox1.Text
            .Execute(Replace:=Word.WdReplace.wdReplaceAll)
        End With

You will notice that now, oWord is specified as Word Application. This differs from the procedure of Button 1. The reason is that we need a Word.Application object in this procedure on Form1 for the 'Find and Replace' actions, and not necessarily a Word.Document object. Therefore, you need to code another function in the WordActions class. In the code above, I named this function 'OpenWordTemplate2' and specified both the name of the Word template (FandR.Template.dotx) as well as the oWord Application.

To make this work property, insert a new Function in the WordActions class:

Public Shared Function OpenWordTemplate2(doc As String, oWord As Word.Application) As Word.Application
        'Procedure OpenWordTemplate()
        '
        '1. check whether Word is running
        '2. if so, create a new document based on the supplied doc variable (a Word template)
        '3. if not, start word and then create a new document based on the supplied doc variable (a Word template)
        '
        '======================================
        'Code to check whether Word is running
        'courtesy of Cindy Meister, VSTO/Word MVP

        Dim oDoc As Word.Document
        Dim appName As String = "Word.Application"
        Dim wdProcesses() As System.Diagnostics.Process = _
          System.Diagnostics.Process.GetProcessesByName("winword")
        Dim wdprocess As System.Diagnostics.Process

        For Each wdprocess In wdProcesses
            System.Diagnostics.Debug.Print(wdprocess.MainWindowTitle)
            System.Diagnostics.Debug.Print(wdprocess.StartInfo.Arguments.Length.ToString())
        Next

        'If Word is running, attach oWord to that instance of Word
        If wdProcesses.Length > 0 Then
            oWord = System.Runtime.InteropServices.Marshal.GetActiveObject(appName)
            'if Word is not running, start new instance of Word
        Else
            oWord = New Word.Application
        End If
        If Not oWord Is Nothing Then
            oWord.Visible = True
            oWord.Activate()
        End If
        oWord.Visible = True
        '======================================

        'open new Word document based on the basic template

        Dim path As String = Application.StartupPath & "\"
        doc = path & doc
        oDoc = oWord.Documents.Add(doc)

        Return oWord
        oDoc = Nothing
        oWord = Nothing

    End Function

The code above for the new function 'OpenWordTemlate2' is almost similar to the original function 'OpenWordTemplate'. However, the changes are the addition of a Word Application object as parameter to the function ('oWord As Word.Application ') and the specification that the function returns a Word.Application object instead of a Word.Document object. The fact that a Word.Document is returned is reflected by the changes in the 'return' part of the code ('Return oWord').

These changes to the original function are needed, because otherwise the Find and Replace code on Form1 (at the Button2 code) won't run properly. I am sure that cloning this function is not best coding practice, but it will do for the moment.

Go back to the code at the Form1 code (for Button2) and look at the code to find and replace text. This part of the code is shown below again:

'code to insert text at a bookmark in the opened Word template
        'Find and replace tag [name] with input from textbox1

        Dim FindObject As Word.Find = oWord.Application.Selection.Find
        With FindObject
            .ClearFormatting()
            .Text = "[name]"
            .Replacement.ClearFormatting()
            .Replacement.Text = TextBox1.Text
            .Execute(Replace:=Word.WdReplace.wdReplaceAll)
        End With

The Find and Replace code requires an oWord object. Our new function 'OpenWordTemplate2' returns just that :).

Basically, this part of the code looks for the text ”[name]” and replaces it with the text in textbox1. Now try your program and notice how clicking both buttons end up with the same result, although using different methods. The bookmarks method is slightly more complicated, because to fill out two spots in the Word document with the same text string, you'll need 2 separate bookmarks. The find and replace method only requires one term between brackets to fill out 2 spots (or a lot more if necessary).

Conclusion

The road was complicated with a large tutorial, but you have successfully coded Word to insert text in a document at a spot you can designate. Let's increase this power in the next tutorial by linking your form to a simple database.

Computing A-Z | Programming | Software


QR Code
QR Code programming_microsoft_word_-_08_-_populating_a_word_document (generated for current page)
 

Advertise with Anonymous Ads