5.6 Working with existing documents

Working with existing documents

Once you ve created documents, there are various reasons why you might want to go through them to make changes or simply look at their contents. Word contains a number of tools that make it easy to go through a document and look inside. It s possible to examine both the contents of a document and the structure.

Search and replace

Search and replace is one of the killer features that made word processors a success when they were first introduced. The ability to go through a document and change every occurrence of "Big Company" to "MegaMonster Corporation" with just a few keystrokes made friends of secretaries throughout the civilized world. Word takes this ability much, much further.

You can search for either text or formatting, or some combination of the two. Searching can be case-sensitive or case-insensitive. You can search just to locate the search phrase, or find it and replace it with another phrase. When you replace, you can choose to replace all occurrences or check each occurrence as it s found and replace it or not. Figure 14 shows the Find and Replace dialog, accessed through the Edit menu in Word.

Figure 14. Find and Replace. Word s version of search and replace is extremely powerful. You can search for text only, formatting only, or text and formatting. You can replace all instances or check them out one at a time.

Searching is handled by the Find object, which is accessed through the Find property of a Range object. It has an assortment of properties, such as Text, MatchCase and MatchWholeWord, that determine what it s searching for. Some properties, like Font and ParagraphFormat, are references to other objects. The Format property determines whether formatting is considered in the search. Set it to .F. to search for the string specified by Text, regardless of format. Table 10 lists some commonly used properties of Find.

The Execute method actually performs the search. In its simplest form, it uses the current settings of the Find object. It can also accept a number of parameters, most of which duplicate properties of the Find object. More about that later.

Table 10. Setting up a search. The Find object s properties determine what to look for.

Property

Type

Description

Text

Character

The string to search for. If it s empty and Format is .T., the search is based on formatting only.

MatchCase

Logical

Indicates whether the search is case-sensitive. Defaults to .F. (case-insensitive).

MatchWholeWord

Logical

Indicates whether the search looks only for whole word matches. Defaults to .F. (matches within words).

MatchSoundsLike

Logical

Indicates whether the search looks for matches that sound like the search string. Defaults to .F. (actual matches only).

MatchWildcards

Logical

Indicates whether the search string contains wildcards that should be matched appropriately. This is an incredibly powerful setting that is, in our opinion, vastly underused by Word users (ourselves included). Defaults to .F. (no wildcards).

MatchAllWordForms

Logical

Indicates whether other forms of the search string should be replaced with corresponding forms of the replacement string. For example, if the search and replacement strings are singular nouns, and this setting is .T., plural versions of the search string would be replaced by plural versions of the replacement string. Defaults to .F. (match the string only as provided).

Format

Logical

Indicates whether to include formatting in the search. If .F., ignore the format-related properties of this object in the search.

Font

Object

Reference to a Font object, indicating the font to match if Format is .T.

ParagraphFormat

Object

Reference to a ParagraphFormat object, indicating the paragraph formatting to match if Format is .T.

Style

Object

Reference to a Style object, indicating the style to match if Format is .T.

Forward

Logical

Indicates the direction of the search. Set to .T. to search toward the end of the document, .F. to search toward the beginning.

Wrap

Numeric

Specifies what happens when a search begins in the middle of a document and reaches the end.

wdFindStop

0

Stop the search.

wdFindContinue

1

Continue the search at the other end of the document.

wdFindAsk

2

Ask the user what to do.

 

Found

Logical

Indicates the result of the last search.

Replacement

Object

Reference to a replacement object with information for replace. (See the text.)

As noted previously, Find is a member of Range (and Selection), but not of Document. The search begins at the beginning of the range, unless Forward is .F., in which case it starts at the end. The Wrap property determines what happens when it reaches the end (or beginning, when searching backward) of the range.

To search the whole document, create a range at the beginning of the document. When Execute finds a match, the range s boundaries are changed to cover only the matched item.

For example, to search for the first occurrence of the string "Visual FoxPro", regardless of case, in the current document, use the following code:

oRange = oWord.ActiveDocument.Range(0,0) && Start of document

WITH oRange.Find

.Text ="Visual FoxPro"

.MatchCase = .F.

.Format = .F.

lFound = .Execute()

ENDWITH

When this code is done, if lFound is .T., a match was found and oRange contains the matching text.

Things get a little more complex when you want to replace the found text. There are two ways to go about it. The last two parameters of Find s Execute method let you specify a replacement string and the number of replacements to perform (none, one, or all). Here s the syntax for Execute:

oRange.Execute( cText, lMatchCase, lMatchWholeWord, lMatchWildcards,

lMatchSoundsLike, lMatchAllWordForms, lForward, nWrap, lFormat,

cReplaceWith, nReplace)

cText

Character

Corresponds to the Text property.

lMatchCase

Logical

Corresponds to the MatchCase property.

lMatchWholeWord

Logical

Corresponds to the MatchWholeWord property.

lMatchWildcards

Logical

Corresponds to the MatchWildcards property.

lMatchSoundsLike

Logical

Corresponds to the MatchSoundsLike property.

lMatchAllWordForms

Logical

Corresponds to the MatchAllWordForms property.

lForward

Logical

Corresponds to the Forward property.

nWrap

Numeric

Corresponds to the Wrap property.

lFormat

Logical

Corresponds to the Format property.

cReplaceWith

Character

The replacement string.

nReplace

Numeric

Indicates whether to replace the search string with cReplaceWith every time it s found, just once, or not at all. Use these constants:

wdReplaceNone

0

wdReplaceOne

1

wdReplaceAll

2

 

 

Technically, cReplaceWith and nReplace aren t really the last two parameters. There are several more that may be accepted, depending on what language you re using. They relate to language-specific features. Check Help if you re working in a language other than English.

Going back to the previous example, we can replace every instance of "Visual FoxPro" with "Visual FoxPro!" by changing the Execute line to:

#DEFINE wdReplaceAll 2

lFound = .Execute( , , , , , , , , , "Visual FoxPro!", wdReplaceAll )

The alternative approach uses a Replacement object referenced through the Find object s Replacement property. Replacement is like a simpler version of Find it can format the Text property with Font, ParagraphFormat, and Style properties, among others. You can fill in Replacement s properties to specify exactly what should replace the found item, like this:

#DEFINE wdReplaceAll 2

WITH oRange.Find

* what to look for

.Text ="Visual FoxPro"

.MatchCase = .F.

.Format = .F.

* what to replace it with

.Replacement.Text = "Visual FoxPro!"

.Replacement.Font.Bold = .T.

.Replacement.ParagraphFormat.LeftIndent = 12

* go!

lFound = .Execute( , , , , , , , , , , wdReplaceAll )

ENDWITH

It s also possible to search for and replace only formatting. Both Find and Replacement have a method called ClearFormatting that resets all format-related properties to their defaults, so you can start from scratch.

To change every occurrence of 12-point Arial to 16-point Times New Roman, use code like this:

#DEFINE wdReplaceAll 2

oRange = oWord.ActiveDocument.Range(0,0)

WITH oRange.Find

* make sure to clean up from last search

.ClearFormatting

* what to look for

.Text =""

.Format = .T.

.Font.Name = "Arial"

.Font.Size = 12

* what to replace it with

WITH .Replacement

.ClearFormatting

.Text = ""

.Font.Name = "Times New Roman"

.Font.Size = 16

ENDWITH

* go!

lFound = .Execute( , , , , , , , , , , wdReplaceAll )

ENDWITH

Of course, with styles, you shouldn t often have to change fonts like that, but it s easy to search for and replace styles, too. Just use the Style property of the Find and Replacement objects.

With a little creativity, it s possible to find and replace pretty much anything you want in a document. You can also combine VFP s data-handling strength with VBA for power searching. Imagine putting a collection of search and replacement strings in a table, then using Automation to make all the changes without intervention.

Exploring document structure

Several properties and methods let you find out about such things as the number of words and pages in a document or range, the author of the document, its title, the template on which it s based, and so forth. You can also provide some of this information and other data about the document.

Statistics like the number of words and pages are available interactively through the Word Count item on the Tools menu. Choosing that option displays the dialog shown in Figure 15.

Figure 15. It s in there. The Word Count dialog actually shows a variety of statistics about the document or range. The same information is available through the ComputeStatistics method.

With Automation, you access the same information by using the ComputeStatistics method of the Document and Range objects. It accepts a parameter that indicates what statistic to compute and returns the appropriate value. Table 11 shows constants for the items you re most likely to want to compute.

Table 11. What do you want to compute today? The ComputeStatistics method takes one of these constants and tells you how many of the specified objects are in the document or range.

Constant

Value

Constant

Value

wdStatisticWords

0

wdStatisticCharacters

3

wdStatisticLines

1

wdStatisticParagraphs

4

wdStatisticPages

2

wdStatisticCharactersWithSpaces

5

For example, to see how many words are in the current document, use:

#DEFINE wdStatisticWords 0

nWords = oWord.ActiveDocument.ComputeStatistics( wdStatisticWords )

Note that some of these values are also available by checking the Count property of the appropriate collection. For example, you can determine the number of paragraphs in a range like this:

nParagraphs = oRange.Paragraphs.Count

Be forewarned. Calling ComputeStatistics sets the document s Saved property to .F. That s right even if you make no other changes to a document, computing the number of words or pages or whatever is enough for the document to think it s been changed.

Additional information about a document is available through the Properties dialog on the File menu. This multi-page dialog (shown in Figure 16) includes some of the same information as the Word Count dialog, but it also contains document properties like the author, title, subject, and many more. In addition to the properties built into the dialog, you can specify custom properties and provide values for them (using the Custom page). File properties can be displayed in the File|Open dialog and can be used to search for documents.

Figure 16. Document properties. This dialog shows you the information stored with a document. In addition to the pre-defined properties, you can add your own custom properties.

Two DocumentProperties collections contain all the properties. They re accessed through two properties of Document: BuiltinDocumentProperties and CustomDocumentProperties. DocumentProperties and DocumentProperty are Office objects, not Word-specific objects.

To check the value of a specific document property, you can look it up by name, then check its Value property. For example, to see the author of the active document:

? oWord.ActiveDocument.BuiltinDocumentProperties[ "Author" ].Value

See the DocumentProperty object in Help for a list of the built-in properties.

To add custom properties, use the Add method of the DocumentProperties collection. Here s the syntax:

oDocument.CustomDocumentProperties.Add( cPropertyName, lLinked, nPropertyType,

uValue )

cPropertyName

Character

The name for the new custom property.

lLinked

Logical

Indicates whether the new custom property is linked to the contents of the document. Pass .F. to simply provide a value. If .T., must pass the optional fifth parameter (not discussed here).

nPropertyType

Numeric

The data type for the new custom property. Use one of these constants:

msoPropertyTypeNumber

1

msoPropertyTypeBoolean

2

msoPropertyTypeDate

3

msoPropertyTypeString

4

msoPropertyTypeFloat

5

 

uValue

Depends on nPropertyType

The value to assign the new custom property.

This code adds a property called VFPVersion to the document and sets it to the version of Visual FoxPro used to create the document:

#DEFINE msoPropertyTypeString 4

oDocument.CustomDocumentProperties.Add( "VFPVersion", .F., ;

msoPropertyTypeString, VERSION() )

Before adding a custom property, check the list of built-in properties carefully. There are quite a few of them.

Traversing a document with the collections

It s possible to "walk" through a document in a number of different ways by using the collections of the Document object along with VFP s FOR EACH loop structure. While it can be slow, for some tasks, traversing a collection is the best approach.

We don t recommend using the collections as a replacement for Find. Searching for text or formatting is much faster with Word s native search mechanism. Nor is it better to measure the size of a document by manually counting its lines, paragraphs, or words (though the Count property of the collections can be quite informative). However, looping through a collection like InlineShapes or Tables shouldn t break the efficiency bank.

The routine in Listing 2 example checks every graphic in a document and checks whether it s linked, but not embedded. It creates a cursor listing those that break the rule. You ll find it as FindGraphics.PRG in the Developer Download files available at www.hentzenwerke.com.

Listing 2. Finding graphics. This program traverse the InlineShapes and Shapes to find every graphic in the active document and check whether it s linked or embedded.

#DEFINE wdInlineShapePicture 3

#DEFINE wdInlineShapeLinkedPicture 4

#DEFINE msoPicture 13

#DEFINE msoLinkedPicture 11

 

* Create the log file

IF NOT USED("Graphics")

CREATE CURSOR Graphics (cDocument C(100), cGraphic C(100), ;

lLinked L, lEmbedded L, tWhen T)

ENDIF

* Now find the graphics.

WITH oWord.ActiveDocument

* Do graphics in the text layer first.

FOR EACH oShape IN .InLineShapes

DO CASE

CASE oShape.Type = wdInlineShapeLinkedPicture

* Linked, may or may not be embedded

IF oShape.LinkFormat.SavePictureWithDocument

* It's embedded, so log it

INSERT INTO Graphics ;

VALUES (.FullName, oShape.LinkFormat.SourceFullName, ;

.T. , .T. , DATETIME())

ENDIF

CASE oShape.Type = wdInlineShapePicture

* Embedded!

INSERT INTO Graphics VALUES (.FullName, "", .F. , .T., DATETIME())

OTHERWISE

&& Not interested in these

ENDCASE

ENDFOR

* Now free-floating graphics

FOR EACH oShape in .Shapes

DO CASE

CASE oShape.Type = msoLinkedPicture

* Linked, may or may not be embedded

IF oShape.LinkFormat.SavePictureWithDocument

* It's embedded, so log it

INSERT INTO Graphics ;

VALUES (.FullName, oShape.LinkFormat.SourceFullName, ;

.T. , .T., DATETIME())

ENDIF

CASE oShape.Type = msoPicture

* Embedded!

INSERT INTO Graphics VALUES (.FullName, "", .F. , .T., DATETIME())

OTHERWISE

&& Not interested in these

ENDCASE

ENDFOR

ENDWITH

RETURN

 

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