4.4 Accessing parts of a document

Accessing parts of a document

Most of what you want to do with Word involves adding to, modifying, or reading a document, whether it s a new document you re building or an existing document you re modifying. (There s actually a third possibility. You may be working on a new document that s based on a template that contains boilerplate text that you re customizing.) There are a variety of ways to do these things, but the key to just about all of them is the Range object and, to a lesser extent, the Selection object.

The Selection object represents the currently highlighted (that is, selected) portion in a document. If nothing is highlighted, Selection refers to the insertion point. There s only one Selection object, accessed directly from the Word Application object. For example, to find out how many paragraphs are in the current selection, you can use this code:

nParagraphs = oWord.Selection.Paragraphs.Count

A Range object can represent any portion of a document. Ranges are not the same as the Selection area. You can define or modify Ranges without affecting the current Selection. You can even define multiple ranges for a document, whereas only one Selection object is available for each document. Ranges are very useful for repeatedly referencing specific portions of a document.

Ranges can be obtained in many ways. Many Word objects, like Paragraph and Table, have a Range property that contains an object reference to a Range object for the original object. For example, to create a Range from the third paragraph of the active document, you can use the following:

oRange = oWord.ActiveDocument.Paragraphs[3].Range

The Document object has a Range method that lets you specify a range by character position. For example, to get a reference to a Range containing the 100th to 250th characters in the active document (probably not a particularly useful range), use:

oRange = oWord.ActiveDocument.Range(100,250)

The Document object s Content property contains a reference to a Range that consists of the entire main document (the body of the document without headers, footers, footnotes, and so on). So the next two commands are equivalent:

oRange = oWord.ActiveDocument.Range()

oRange = oWord.ActiveDocument.Content

Beware: for a large document, creating such a variable can take a significant amount of time.

It s easy to convert Range objects to a Selection, and vice versa. Like many other objects, Selection has a Range property, which provides a Range object from the Selection. Similarly, the Range object has a Select method that highlights the range s contents, turning it into the Selection. For example, to highlight the range from the previous example, use:

oRange.Select()

Selection and Range seem quite similar, and they are in many ways, but there are differences. The biggest, of course, is that you can have multiple Ranges but only one Selection. In addition, working with a Range is usually faster than working with a Selection. On the whole, Word VBA experts recommend using Range rather than Selection wherever possible. The main reason is that using Selection is essentially duplicating screen actions with code; Range lets you operate more directly. Word s macro recorder tends to use the Selection object; this is one thing to be aware of when converting Word macros to VFP code.

Manipulating text

The Text property of Range and Selection contains whatever text is in the specified area. To bring document contents into FoxPro, create an appropriate Range and read its Text property, like this:

oRange = oWord.ActiveDocument.Paragraphs[7].Range

cParagraph7 = oRange.Text

The Text property also lets you add or change the document contents. You can add text by assigning it to the Text property.

oRange.Text = "This is a new sentence."

You can also add text to whatever s already there. Simple text manipulation does the trick.

oRange.Text = oRange.Text + "Add text at the end."

Or you can do this:

oRange.Text = "Add text at the beginning " + oRange.Text

Another possibility is to read text into VFP, manipulate it in some way, and write it back:

cMakeUpper = oRange.Text

cMakeUpper = UPPER(cMakeUpper)

oRange.Text = cMakeUpper

That example can be shortened to a single line, like this:

oRange.Text = UPPER(oRange.Text)

Using this approach, we can send the data from a record to a new, blank document:

USE _SAMPLES + "TasTrade\Data\Customer"

LOCAL oDocument, oRange

oDocument = oWord.Documents.Add() && Use the Normal template

oRange = oDocument.Range()

oRange.Text = Customer_ID + ": " + Company_Name

oRange.Text = oRange.Text + "Attn: " + TRIM(Contact_Name) + ;

" - " + Contact_Title

oRange.Text = oRange.Text + Address

oRange.Text = oRange.Text + TRIM(City) + " " + TRIM(Region) + Postal_Code

oRange.Text = oRange.Text + UPPER(Country)

Because Word always keeps a paragraph marker (CHR(13)) at the end of the document, it adds a paragraph marker after each addition to oRange.Text when executing this code. In other situations (including the examples that follow), you need to add the paragraph marker explicitly. The new document looks like Figure 2.

Figure 2. There s more than one way to skin a cat. The return address shown can be sent to Word in many different ways. In this case, with no special formatting involved, the fastest approach is to build the whole string in VFP, then send it to Word.

Of course, building a document by composing a single string doesn t take advantage of the special capabilities of Word. Range s InsertAfter and InsertBefore methods let you add text at the end or beginning, respectively, and expand the range to include the new text.

Here s an alternative, faster approach to creating the document shown in Figure 2:

#DEFINE CR CHR(13)

USE _SAMPLES + "TasTrade\Data\Customer"

LOCAL oDocument, oRange

oDocument = oWord.Documents.Add() && Use the Normal template

oRange = oDocument.Range()

oRange.InsertAfter(Customer_ID + ": " + Company_Name + CR)

oRange.InsertAfter("Attn: " + TRIM(Contact_Name) + " - " + Contact_Title + CR)

oRange.InsertAfter(Address + CR)

oRange.InsertAfter(TRIM(City) + " " + TRIM(Region) + Postal_Code + CR)

oRange.InsertAfter(UPPER(Country))

In our tests, the InsertAfter version was one-and-a-half times to twice as fast as the concatenation method.

Moving in a range or selection

Besides changing the content of a range or selection, you may need to modify its extent. A number of methods change the area covered by a range or selection. One of the simplest is the Move method, which changes the boundaries of the range or selection.

Move accepts two parameters. The first indicates the unit of movement you can move by characters, words, paragraphs, rows in a table, or the whole document. The second parameter tells how many of the specified units to move a positive number indicates forward movement (toward the end of the document), while a negative number means backward movement (toward the beginning of the document).

In all cases, the range or selection is reduced (or "collapsed," in Word VBA terms) to a single point before being moved. Although collapsing a range or selection sounds dire, it s not. The text contained in the range/selection remains in the document only the extent of the range or selection is changed. When moving forward, the range or selection is reduced to its end point, then moved; when moving backward, it s reduced to its beginning point before moving. You don t need to do anything special afterward. For the Automation programmer, the key issue is to understand where in the range movement begins.

Constants from the wdUnits group are used for the units of movement. Table 1 shows the values for this group that can be passed to the Move method.

Table 1. Word units. The constants in the wdUnits group represent portions of a document.

Constant

Value

Description

wdCharacter

1

One character.

wdWord

2

One word.

wdSentence

3

One sentence.

wdParagraph

4

One paragraph.

wdSection

8

One section of a document. (Word allows you to divide documents into multiple sections with different formatting.)

wdStory

6

The entire length of whichever part of the document you re in. Word considers the main body of the document to be one "story," the header to be another "story," the footnotes to be a third, and so forth.

wdCell

12

One cell of a table.

wdColumn

9

One column of a table.

wdRow

10

One row of a table.

wdTable

15

The entire space of a table.

To create a range at the end of the document, you can use the following:

oRange = oWord.ActiveDocument.Range()

oRange.Move( wdStory, 1)

Here s another way to create the document shown in Figure 2. It uses the Move method to move the Range object.

#DEFINE CR CHR(13)

#DEFINE wdStory 6

USE _SAMPLES + "TasTrade\Data\Customer"

LOCAL oDocument, oRange

oDocument = oWord.Documents.Add() && Use the Normal template

oRange = oDocument.Range()

oRange.Text = Customer_ID + ": " + Company_Name + CR

oRange.Move(wdStory)

oRange.Text = "Attn: " + TRIM(Contact_Name) + " - " + Contact_Title + CR

oRange.Move(wdStory)

oRange.Text = Address + CR

oRange.Move(wdStory)

oRange.Text = TRIM(City) + " " + TRIM(Region) + Postal_Code + CR

oRange.Move(wdStory)

oRange.Text = UPPER(Country)

Speedwise, this version ranks between the concatenation and insert versions.

The Collapse method lets you explicitly reduce a range or selection to a single point. It takes one parameter, indicating the direction of the collapse. Passing the constant wdCollapseEnd (with a value of 0) collapses the range or selection to its end point (the point closest to the end of the document). Passing wdCollapseStart (whose value is 1) reduces the range or selection to its starting point. (That is, Collapse moves either the starting point of the range to the endpoint or the endpoint to the starting point. The range then consists of just a single point at what was previously either the end or the beginning of the range.)

The example can be rewritten yet again to use Collapse to control the range:

#DEFINE CR CHR(13)

#DEFINE wdCollapseEnd 0

USE _SAMPLES + "TasTrade\Data\Customer"

LOCAL oDocument, oRange

oDocument = oWord.Documents.Add() && Use the Normal template

oRange = oDocument.Range()

oRange.Text = Customer_ID + ": " + Company_Name + CR

oRange.Collapse(wdCollapseEnd)

oRange.Text = "Attn: " + TRIM(Contact_Name) + " - " + Contact_Title + CR

oRange.Collapse(wdCollapseEnd)

oRange.Text = Address + CR

oRange.Collapse(wdCollapseEnd)

oRange.Text = TRIM(City) + " " + TRIM(Region) + Postal_Code + CR

oRange.Collapse(wdCollapseEnd)

oRange.Text = UPPER(Country)

In terms of timing, this version performs about the same as the Move version.

A number of other methods allow fine-tuning of movement. They include MoveEnd, MoveStart, MoveLeft, MoveRight, EndOf, and StartOf. Some methods apply only to the selection, not to ranges.

Finally, it s worth commenting that, for this particular task, the fastest approach of all is to concatenate all the strings in VFP, and then send one string to the document:

USE _SAMPLES + "TasTrade\Data\Customer"

LOCAL oDocument, oRange

oDocument = oWord.Documents.Add() && Use the Normal template

oRange = oDocument.Range()

LOCAL cText

cText = ""

cText = Customer_ID + ": " + Company_Name + CR

cText = cText + "Attn: " + TRIM(Contact_Name) + " - " + Contact_Title + CR

cText = cText + Address + CR

cText = cText + TRIM(City) + " " + TRIM(Region) + Postal_Code + CR

cText = cText + UPPER(Country) + CR

oRange.Text = ""

oRange.InsertAfter(cText)

With VFP s speed at constructing strings, this version takes only one-third to one-quarter as long as the other approaches. Although Collapse and Move aren t the best approach in this simple case, they are essential methods for working with Word.

Bookmarks

A bookmark is a way of naming a range or location. Word maintains a collection of bookmarks, naturally called Bookmarks. To create a Bookmark, call the Bookmarks collection s Add method, passing the name for the new bookmark and the range to which it refers. For example, this code creates a bookmark called Title for the first paragraph of the document:

oDocument.Bookmarks.Add("Title", oDocument.Paragraphs[1].Range )

Why use bookmarks? Because Word does the work of maintaining them. Rather than keeping track of a variable in VFP, we can simply ask Word to hang onto a range for us. More importantly, Word can remember the range between sessions, so that when we return to a document, the bookmark is still available, still pointing to the same location.

 

Copyright 2000 by Tamar E. Granor and Della Martin All Rights Reserved



Microsoft Office Automation with Visual FoxPro
Microsoft Office Automation with Visual FoxPro
ISBN: 0965509303
EAN: 2147483647
Year: 2000
Pages: 128

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net