Chapter 21. Working with Widely Used Objects in Word

In the previous chapter, you learned how to work with some of the main objects in the Word object model, such as Document objects, the Selection object, Range objects, and the Options object. This chapter shows you how to go further with VBA in Word by working with Find and Replace; with headers, footers, and page numbers; with sections, page setup, windows, and views; and with tables.

In this chapter you will learn to do the following:

  • Use Find and Replace via VBA

  • Work with headers, footers, and page numbers

  • Manage sections, page setup, windows, and views

  • Manipulate tables

Using Find and Replace via VBA

Word's Find and Replace feature can be very useful in your procedures. You can, for example, quickly adjust multiple styles throughout an entire document. Or you could automate the process of finalizing documents (spell checking, revising corporate information, looking for out-of-date references, or whatever routinely needs to be done before publication).

To access Word's Find and Replace features via VBA, you use the Find and Replacement objects. This section illustrates how to work with the Find object's Execute method, usually the best method to employ when working with Find. You usually specify the parameters for the Find operation as arguments in the Execute statement, but you can also specify them beforehand using properties if you prefer.

Table 21.1 describes the Find properties that are most useful for common search operations.

Table 21.1. Properties of the Find object

Find Property

Meaning

Font

Font formatting you're searching for (on either specified text or an empty string).

Forward

A Boolean argument specifying whether to search forward (True) or backward (False) through the document.

Found

A Boolean property that's True if the search finds a match and False if it doesn't.

Highlight

A Long argument controlling whether highlighting is included in the formatting for the replacement text (True) or not (False).

MatchAllWordForms

A Boolean property—True or False—corresponding to the Find All Word Forms check box.

MatchCase

A Boolean property corresponding to the Match Case check box. If the user has this option deselected, be sure your code deselects it after you're finished with any case-sensitive searching in your procedure. See the sidebar "Practical Searching: Remember to Clear Formatting" later in this chapter.

MatchSoundsLike

A Boolean property corresponding to the Sounds Like check box.

MatchWholeWord

A Boolean property corresponding to the Find Whole Words Only check box.

MatchWildcards

A Boolean property corresponding to the Use Wildcards check box.

ParagraphFormat

Paragraph formatting you're searching for (on either specified text or an empty string).

Replacement

Returns a Replacement object containing the criteria for a replace operation.

Style

The style for the search text. Usually, you'll want to use the name of a style in the current template, but you can also use one of the built-in Word constant style names, such as wdStyleHeading1 (Heading 1 style).

Text

The text you're searching for (what you'd enter in the Find What box in the Find And Replace dialog box). Use an empty string ("") to search only for formatting.

Wrap

A Long property that governs whether a search that starts anywhere other than the beginning of a document (for a forward search) or the end of a document (for a backward search), or a search that takes place in a range, wraps (continues) when it reaches the end or beginning of the document or the end or beginning of the selection.

You use the Replacement object to specify the replace criteria in a replacement operation. The Replacement object has the following properties, which correspond to the properties of the Find object (but pertain to the replacement operation instead): Font, Highlight, ParagraphFormat, Style, and Text.

Understanding the Syntax for the Execute Method

The syntax for the Execute method is as follows:

expression.Execute(FindText, MatchCase, MatchWholeWord, MatchWildcards,
   MatchSoundsLike, MatchAllWordForms, Forward, Wrap, Format,
   ReplaceWith, Replace, MatchKashida, MatchDiacritics, MatchAlefHamza,
   MatchControl, MatchPrefix, MatchSuffix, MatchPhrase, IgnoreSpace,
   IgnorePunct)

The most commonly used arguments for this method are explained here:

  • expression is a required expression that returns a Find object. Usually, it's easiest to use the Find object itself.

  • FindText is an optional Variant specifying the text for which to search. Although this argument is optional, you'll almost always want to specify it, even if you specify only an empty string ("") to allow you to search for formatting rather than text. (If you don't specify "" for FindText, you will inadvertently search for the previous text searched for, and the style you want to locate will never be found unless that text is also present.)

You can search for special characters by using special characters you use when working interactively (for example, ^p for a paragraph mark or ^t for a tab) and for wildcards by using the traditional Windows wildcards. For wildcards to work, you need to set MatchWildcards to True. You can search for a symbol by entering a caret and a zero followed by its character code. For example, to search for a smart double closing quote, you'd specify ^0148 because its character code is 148.

  • MatchCase is an optional Variant that you can set to True to make the search case sensitive.

  • MatchWholeWord is an optional Variant that you can set to True to restrict the search to finding whole words rather than words contained in other words.

  • MatchWildcards is an optional Variant that you can set to True to use wildcards in the search.

  • MatchSoundsLike is an optional Variant that you can set to True to have Word find words that it thinks sound similar to the Find item specified.

  • MatchAllWordForms is an optional Variant that you can set to True to have Word find all forms of the Find item specified (for example, different forms of the same verb or noun).

  • Forward is an optional Variant that you can set to True to have Word search forward (from the beginning of the document toward the end) or False to have Word search backward.

  • Wrap is an optional Variant that governs whether a search that begins anywhere other than the beginning of a document (for a forward search) or at the end of a document (for a backward search), or that takes place in a range, wraps (continues) when it reaches the end or beginning of the document. Word offers various options for Wrap, as detailed in Table 21.2.

    Table 21.2. Options for Wrap offered by word

    Constant

    Value

    Meaning

    wdFindAsk

    2

    Word searches the selection or range—or from the insertion point to the end or beginning of the document—and then displays a message box prompting the user to decide whether to search the rest of the document.

    wdFindContinue

    1

    Word continues to search after reaching the end or beginning of the search range or the end or beginning of the document.

    wdFindStop

    0

    Word stops the Find operation upon reaching the end or beginning of the search range or the end or beginning of the document.

  • Format is an optional Variant that you can set to True to have the search operation find formatting as well as (or instead of) any Find text you've specified.

  • ReplaceWith is an optional Variant specifying the replacement text. You can use an empty string for ReplaceWith to simply remove the FindText text; you can also use special characters for ReplaceWith as you can for the FindText argument. To use a graphic object, copy it to the Clipboard and then specify ^c (which stands for the contents of the Clipboard).

  • Replace is an optional Variant that controls how many replacements the Find operation makes: one (wdReplaceOne), all (wdReplaceAll), or none (wdReplaceNone).

  • MatchPrefix is an optional Variant that allows you to search for a string of characters at the start of words, but not if any other character(s) precede the string. Here's how it works: If you leave MatchPrefix and MatchWholeWord set to False, then search for real, you'll get results with any word that contains that string, such as real, surreal, realtime, boreal, and so on. Any word with real in it will be a hit. But set MatchWholeWord to True and only the string itself, real, will result in a hit. Leave MatchWholeWord set to False and set MatchPrefix to True and only words that begin with real will hit, such as real and realtime. Words like surreal fail to qualify because they don't begin with the target string.

  • MatchSuffix is an optional Variant that works the same way as MatchPrefix, except MatchSuffix allows you to search for a string of characters at the end of a word but not if any other characters follow the string. Using the example in the previous bullet, with MatchSuffix set to True, you would get hits on surreal and boreal but not realtime.

  • MatchPhrase is an optional Variant that when set to True ignores any control characters (such as paragraph or tab characters) or white space (one or more space characters) between words.

    This

    phrase

    becomes equivalent to:

    this phrase.

  • IgnoreSpace is an optional Variant that ignores any white space between words but that does not ignore control characters.

  • IgnorePunct is an optional Variant that ignores all punctuation characters between words in a search phrase.

Putting Find and Replace to Work

The simplest way to use Find and Replace is to specify only as many parameters as you need in an Execute statement, leaving out any optional parameters that are irrelevant to your search. For example, to replace all pairs of paragraph marks in the active document with single paragraph marks, you could search for ^p^p and replace it with ^p with the following statement:

ActiveDocument.Content.Find.Execute FindText:="^p^p",
  ReplaceWith:="^p", _
    Replace:=wdReplaceAll

By running this statement in a loop, you could replace all extra paragraph marks in the document. You would have to employ a loop here because the wdReplaceAll constant specifies that the find-and-replace activity should go through the entire document once.

It's necessary to loop because you might have multiple paragraph marks in clusters, such as four in a row: ^p^p^p^p. The first pass through the document would replace those four with two ^p^p, so you'd need to go through again to reduce these to the desired single ^p. In other words, in this case you must search and replace more than once.

You can also use a With statement to specify the properties for a Find and Replace operation. Listing 21.1 shows an example of this. The code changes all bold formatting in the open document named Example.docm to italic formatting.

Example 21.1. Using With to specify properties

1.  With Documents("Example.docm").Content.Find
 2.      .ClearFormatting
 3.      .Font.Bold = True
 4.      With .Replacement
 5.          .ClearFormatting
 6.          .Font.Bold = False
 7.          .Font.Italic = True
 8.      End With
 9.      .Execute FindText:="", ReplaceWith:="", _
             Format:=True, Replace:=wdReplaceAll
10.  End With

Here, line 1 identifies the Document object (Example.docm in the Documents collection) with which to work and begins a With statement with its Find object. Line 2 uses the ClearFormatting method to clear any formatting from the Find object, and line 3 then sets the Bold property of its Font object to True.

Lines 4 through 8 contain a nested With statement for the Replacement object. Line 5 uses the ClearFormatting method to clear formatting from the Replacement object; line 6 sets its Bold property to False, and line 7 sets its Italic property to True.

Line 9 then uses the Execute method to execute the replacement operation. Both FindText and ReplaceWith here are specified as empty strings to cause Word to work with formatting only; Format is set to True to activate the formatting set in the Find and Replacement objects, and Replace is set to wdReplaceAll to replace all instances of the bold formatting with the italic formatting.

Line 10 ends the outer With statement.

Working with Headers, Footers, and Page Numbers

The following sections show you how to work with headers and footers in Word documents. You'll also learn how to use VBA to manipulate page numbers, which are often included in headers and footers.

Understanding How VBA Implements Headers and Footers

You can create several types of headers and footers in a Word document: the primary header and footer, unique first-page-only headers and footers, special headers and footers that appear only on the even pages—even different sets of headers and footers for each of the sections in a document if need be.

Every document automatically gets an empty primary header and a primary footer, even if you don't put anything in them. You can then create different first-page and even-page headers by changing the Page Setup options for the section. (Click the Page Layout tab on the Ribbon, then click the small arrow in the lower-right corner of the Page Setup zone. This opens the Page Setup dialog box; click the Layout tab. Note, however, that the primary header and footer features are accessed from the Insert tab on the Ribbon.)

VBA uses the following objects for headers and footers:

  • Both headers and footers are contained in HeaderFooter objects. You access headers through the Headers property and footers through the Footers property.

  • The HeadersFooters collection contains all the HeaderFooter objects in a given section of a document. Because each section of a document can have different headers and footers than the other sections have, you reach any given header or footer by going through the section.

  • To return the HeadersFooters collection, you use the Headers property or the Footers property of the appropriate Section object in the appropriate Document object. Alternatively, you can use the HeaderFooter property of the Selection object to return a single HeaderFooter object, but this approach tends to be more limited in its use.

  • The HeaderFooter object gives access to the Range object, the Shapes collection, and the PageNumbers collection.

Getting to a Header or Footer

You access a header or footer through the appropriate section within the document. For example, the following statement displays a message box containing the text in the first-page footer in the second section of the open document Transfer.docm:

MsgBox Documents("Transfer.docm").Sections(2). _
    Footers(wdHeaderFooterFirstPage).Range.Text

The following statements declare the HeaderFooter object variable myHeader and assign to it the primary header in the first section in the active document:

Dim myHeader As HeaderFooter
Set myHeader = ActiveDocument.Sections(1).Headers _
    (wdHeaderFooterPrimary)

Checking to See If a Header or Footer Exists

Recall that Word automatically creates a primary header and primary footer for each document, so these objects always exist. To find out whether other types of headers or footers exist, check the Exists property of the application HeaderFooter object. The following statements check to see if the even-pages footer exists in each section in turn in the active document and create a generic header (containing the section number and the full name of the document) formatted with the style named Footer (which exists by default in most Word documents):

Dim cSection As Section
With ActiveDocument
    For Each cSection In .Sections
        cHeader = cSection.Headers(wdHeaderFooterEvenPages)
        If Not cSection.Headers(wdHeaderFooterEvenPages).Exists Then
            cSection.PageSetup.OddAndEvenPagesHeaderFooter = True
            cSection.Headers(wdHeaderFooterEvenPages).Range.Text _
                = "Section " & cSection.Index & " of " & .FullName
            cSection.Headers(wdHeaderFooterEvenPages).Range. _
                Style = "Even Footer"
        End If
    Next cSection
End With

Linking to the Header or Footer in the Previous Section

By default, Word links the header and footer in each section after the first to the header and footer in the previous section. To break the link, set the LinkToPrevious property of the header or footer to False; to create the link, set this property to True. The following statement unlinks the primary footer in the third section of the active document from the corresponding footer in the second section:

ActiveDocument.Sections(3).Footers _
(wdHeaderFooterPrimary).LinkToPrevious = False

Creating a Different First-Page Header

To create a different header on the first page of a section, set the DifferentFirstPageHeaderFooter property of the PageSetup object for the section to True. The following statements check to see if the 10th section of the active document contains a first-page header and create one if it doesn't:

With ActiveDocument.Sections(10)
    If .Headers(wdHeaderFooterFirstPage).Exists = False Then _
        .PageSetup.DifferentFirstPageHeaderFooter = True
End With

Creating Different Odd- and Even-Page Headers

To produce different headers for odd and even pages of your document (other than the first page), create an even-page header. The primary header by default appears on both odd and even pages until you create an even-page header, at which point the primary header becomes the odd-page header.

As with the first-page header, you work through the PageSetup object to create a different even-page header, setting the OddAndEvenPagesHeaderFooter property to True, as in the following statement:

ActiveDocument.Sections(1).PageSetup.OddAndEvenPagesHeaderFooter = True

Adding Page Numbers to Your Headers and Footers

The header or footer of a document often contains a page number: either a simple number in a straightforward format (1, 2, 3, and so on) or a more complex number denoting the chapter and page within it, separated by a separator character.

VBA implements page numbers through a PageNumbers collection that you return by using the PageNumbers property of the appropriate HeaderFooter object within the appropriate section of the document.

Adding Page Numbers to One or More Sections of a Document

To add page numbers to a document, use the Add method with the PageNumbers collection for the appropriate section of the document.

The syntax for the Add method is as follows:

expression.Add PageNumberAligment, FirstPage

Here, expression is a required expression that returns a PageNumbers collection. Usually, you'll use the PageNumbers collection itself.

PageNumberAlignment is an optional Variant argument specifying the alignment for the page numbers being added. Table 21.3 lists the constants and values you can use.

Table 21.3. PageNumberAlignment constants and values

Constant

Value

Resulting Alignment

wdAlignPageNumberLeft

0

Left

wdAlignPageNumberCenter

1

Centered

wdAlignPageNumberRight

2

Right (default)

wdAlignPageNumberInside

3

Inside margin (right on left-hand pages, left on right-hand pages)

wdAlignPageNumberOutside

4

Outside margin (left on left-hand pages, right on right-hand pages)

FirstPage is an optional Variant argument that you can set to False to make the header and footer on the first page suppress the page number. If you omit the FirstPage argument, the DifferentFirstPageHeaderFooter property of the PageSetup object controls whether the header and footer on the first page are the same as or different than they are on the other pages in the section.

Both the PageNumberAlignment argument and the FirstPage argument are optional, but you'll usually want to specify at least the PageNumberAlignment argument.

The following subprocedure adds page numbers to all the headers in each section of a document by using two For Each... Next loops:

Sub AddPageNumbersToAllHeadersAndSections()
    Dim cHeader As HeaderFooter, cSection As Section
    With Documents("Headers and Footers.docm")
        For Each cSection In .Sections
            For Each cHeader In cSection.Headers
                cSection.Headers(wdHeaderFooterPrimary).PageNumbers.Add _
                PageNumberAlignment:=wdAlignPageNumberRight, FirstPage:=True
            Next cHeader
        Next cSection
    End With
End Sub

Removing Page Numbers from One or More Sections of a Document

To remove a page number from a page, specify the PageNumber object and use the Delete method. The following subprocedure removes each PageNumber object from the current section of the active document:

Sub RemovePageNumbersFromCurrentSection()
    Dim ThisHeader As HeaderFooter
    Dim ThisPageNumber As PageNumber
    With Selection.Sections(1)
        For Each ThisHeader In .Headers
            For Each ThisPageNumber In ThisHeader.PageNumbers
                ThisPageNumber.Delete
            Next ThisPageNumber
        Next ThisHeader
    End With
End Sub

Finding Out If a Section of a Document Has Page Numbers

The easiest way to find out if any given page number exists is to check the Count property for the PageNumbers collection for the appropriate section. For example, the following statement adds centered page numbers to the even-pages header in the current section if the header doesn't already have them:

If Selection.Sections(1).Headers(wdHeaderFooterEvenPages) _
    .PageNumbers.Count = 0 Then Selection.Sections(1) _
    .Headers(wdHeaderFooterEvenPages).PageNumbers.Add _
    PageNumberAlignment:=wdAlignPageNumberCenter

Changing the Page Numbering for a Section

To change the page numbering for a section, you work with the StartingNumber property, using the RestartNumberingAtSection property, the IncludeChapterNumber property, and the ChapterPageSeparator property as necessary.

The StartingNumber property is a Long property that contains the starting page number for the section when the RestartNumberingAtSection property is set to True. When the RestartNumberingAtSection property is set to False, StartingNumber returns 0 (zero). The following statements set the page numbering for the primary header in the fourth section of the active document to start at 55 if it doesn't currently have a starting number assigned:

With ActiveDocument.Sections(4).Headers(wdHeaderFooterPrimary)
    If .PageNumbers.StartingNumber = 0 Then
        .PageNumbers.RestartNumberingAtSection = True
        .PageNumbers.StartingNumber = 55
    End If
End With

To add the chapter number to the page numbers, use heading numbering in your document, set the IncludeChapterNumber property to True, and specify the separator to use (for example, wdSeparatorEnDash for an en dash):

With ActiveDocument.Sections(4).Headers(wdHeaderFooterPrimary) _
    .PageNumbers
    .IncludeChapterNumber = True
    .ChapterPageSeparator = wdSeparatorEnDash
End With

Suppressing the Page Number for the First Page

To suppress the page number for the first page in a section, set the ShowFirstPageNumber property for the appropriate HeaderFooter object in the appropriate section to False:

ActiveDocument.Sections(1).Footers(wdHeaderFooterPrimary).PageNumbers_
    .ShowFirstPageNumber = False

Formatting Page Numbers

You can format page numbers in two ways: by setting the format in which they're displayed (for instance, as regular Arabic numbers or as lowercase Roman numerals) and by formatting the font in which that format is displayed.

To choose the format in which the page numbers are displayed, set the NumberStyle property of the PageNumbers collection in question. For example, the following statement formats the page numbers in the primary header in the fourth section of the active document as lowercase letters:

ActiveDocument.Sections(4).Headers(wdHeaderFooterPrimary) _
    .PageNumbers.NumberStyle = wdPageNumberStyleLowercaseLetter

Once the page numbers are in the header or footer, you can format them in any of several ways. One easy way to set the font in which a given page number is formatted is to use the Select method to select the PageNumber object and then apply formatting to it as you would any other selection, as in the following statements:

ActiveDocument.Sections(4).Headers(wdHeaderFooterPrimary) _
    .PageNumbers(1).Select
    With Selection.Font
        .Name = "Impact"
        .Size = 22
        .Bold = True
    End With

Creating "Page X of Y" Type Page Numbers

You can also implement page numbering by using Word's field codes in the header or footer. This technique is especially useful when you want to number the pages with an "X of Y" numbering scheme—"Page 168 of 192" and so on. The following statements select the primary header for the final section of the active document, apply center alignment, and enter the text and fields to produce this type of numbering:

ActiveDocument.Sections(ActiveDocument.Sections.Count) _
    .Headers(wdHeaderFooterPrimary).Range.Select
With Selection
    .Paragraphs(1).Alignment = wdAlignParagraphCenter
    .TypeText Text:="Page "
    .Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
        "PAGE ", PreserveFormatting:=True
    .TypeText Text:=" of "
    .Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
        "NUMPAGES ", PreserveFormatting:=True
End With

If you insert a page number by using a field in this way, you can still access the page number by using the appropriate PageNumber object. (In this case, the PageNumber object consists of the PAGE field, not of the NUMPAGES field.)

Working with Sections, Page Setup, Windows, and Views

Each Word document contains at least one section by default and can contain multiple sections as needed for its contents and layout. The section of the document controls the page layout so that different sections of a document can use different page layouts if necessary.

Adding a Section to a Document

You can add a section to a document either by using the Add method with the Sections collection or by using the InsertBreak method with a Range or Selection object.

The Add method has the following syntax:

expression.Add Range, Start

Here, expression is a required expression that returns a Sections collection. Range is an optional Variant argument specifying the range at the beginning of which to insert the break. (If you omit Range, VBA inserts the break at the end of the document.) Start is an optional Variant argument used to specify the type of section break to insert:

  • wdSectionContinuous (0) for a continuous break

  • wdSectionEvenPage (3) for an even-page break

  • wdSectionOddPage (4) for an odd-page break

  • wdSectionNewColumn (1) for a new-column break

  • wdSectionNewPage (2, the default) for a new-page break

The following statement adds a new-page section to the active document, placing it before the second paragraph:

ActiveDocument.Sections.Add _
Range:=.Range(Start:=.Paragraphs(2).Range.Start, _
        End:=.Paragraphs(2).Range.Start), Start:=wdSectionNewPage

The InsertBreak method takes the following syntax:

expression.InsertBreak Type

Here, expression is a required expression that returns a Selection or Range object. Type is an optional Variant argument specifying the type of section break to be inserted:

  • wdSectionBreakNextPage (2) for a new-page break

  • wdSectionBreakContinuous (3) for a continuous break

  • wdSectionBreakEvenPage (4) for an even-page break

  • wdSectionBreakOddPage (5) for an odd-page break

  • wdColumnBreak (8) for a new-column break

The following statement inserts a continuous section break before the second paragraph in the active document:

ActiveDocument.Paragraphs(2).Range.InsertBreak _
 Type:=wdSectionBreakContinuous

Changing the Page Setup

To change the page setup of a document or a section, you work with the PageSetup object of the application Document object or Section object. For example, the following statements work with the PageSetup object of the document named Planning.docm, setting letter-size paper, portrait orientation, mirror margins, and margin measurements (in points):

With Documents("Planning.docm").PageSetup
    .PaperSize = wdPaperLetter
    .Orientation = wdOrientPortrait
    .TopMargin = 1
    .BottomMargin = 1
.LeftMargin = 1
    .RightMargin = 1.5
    .MirrorMargins = True
End With

Opening a New Window Containing an Open Document

To open a new window containing an open document, use the Add method. Its syntax is straightforward:

expression.Add window

Here, expression is an expression that returns a Windows collection, and window is an optional Variant argument specifying the window containing the document for which you want to open a new window. If you omit window, VBA opens a new window for the active document.

For example, the following statements open a new window for the first window open for the active document, assigning the window to the variable myWindow:

Dim myWindow As Window
Set myWindow = Windows.Add(Window:=ActiveDocument.Windows(1))

Closing All Windows for a Document Except the First

Occasionally, it's useful to open one or more new windows for a document. If you do so, sooner or later you'll need to close all the secondary windows to give yourself more room to maneuver. The following statements close all windows for the active document except the first window:

Dim myWin As Window, myDoc As String
myDoc = ActiveDocument.Name
For Each myWin In Windows
    If myWin.Document = myDoc Then _
        If myWin.WindowNumber <> 1 Then myWin.Close
Next myWin

Splitting a Window

To split a window in two parts horizontally, set its Split property to True. To specify the split percentage (which controls how far down the window, measuring vertically, the split is placed), set the SplitVertical property. The following statements split the active window 70 percent of the way down the window:

With ActiveWindow
    .Split = True
    .SplitVertical = 70
End With

To remove the split from the window, set the Split property to False:

ActiveWindow.Split = False

Displaying the Document Map for a Window

To display the Document Map for a window at the Document Map's previous width percentage (of the entire window), set the DocumentMap property to True:

ActiveWindow.DocumentMap = True

To display the Document Map at a different width, or to change the width of the Document Map, set the DocumentMapPercentWidth property to a suitable percentage of the window's width:

ActiveWindow.DocumentMapPercentWidth = 25

To hide the Document Map again, set the DocumentMap property to False or set the DocumentMapPercentWidth property to 0.

Scrolling a Window

To scroll a window up, down, left, or right, use either the LargeScroll method or the SmallScroll method.

The LargeScroll method is analogous to clicking within the scroll bar (not on the thumb); this scrolls the contents of the window by one entire "screen." The SmallScroll method is analogous to clicking a thumb (the arrows at the top and bottom of the scroll bar); this scrolls the contents of the window up or down by one line. If you're working with a horizontal scroll bar, the contents move left or right by a small scroll increment.

The syntax for the LargeScroll method is as follows:

expression.LargeScroll(Down, Up, ToRight, ToLeft)

The syntax for the SmallScroll method is almost identical:

expression.SmallScroll(Down, Up, ToRight, ToLeft)

Here, expression is a required expression that returns a Window object. Down, Up, ToRight, and ToLeft are optional Variant arguments that specify the number of screens (for LargeScroll) or lines or horizontal movement units (for SmallScroll) to scroll the contents of the window in the directions their names indicate.

The following statement scrolls the active window up two screens:

ActiveWindow.LargeScroll Up:=2

Arranging Windows

To arrange a number of windows, use the Arrange method. The syntax for the Arrange method is as follows:

expression.Arrange ArrangeStyle

Here, expression is an expression that returns a Windows collection, and ArrangeStyle is an optional Variant argument that specifies how to arrange the windows: as icons (wdIcons, 1) or tiled (wdTiled, 0). The default is wdTiled.

For example, the following statement tiles the open windows:

Windows.Arrange ArrangeStyle:=wdTiled

Positioning and Sizing a Window

To position a window on the monitor, set its Left and Top properties, as in this example:

ActiveWindow.Left = 100
ActiveWindow.Top = 200

To size a window, set its Height and Width properties:

With ActiveWindow
    .Height = 300
    .Width = 400
End With

To maximize, minimize, or "restore" a window, set its WindowState property to wdWindowStateMaximize, wdWindowStateMinimize, or wdWindowStateNormal, respectively. The following statements maximize the window containing the document named Example.docm if the window is minimized:

With Documents("Example.docm").Windows(1)
    If .WindowState = wdWindowStateMinimize Then _
       .WindowState = wdWindowStateMaximize
End With

Making Sure an Item Is Displayed in the Window

After opening or arranging windows, you'll often need to make sure an item you want the user to see—a range, some text, a graphic or other shape, or a field—is displayed in the window. The easiest way to do so is to use the ScrollIntoView method of the Window object. This method moves the view but not the selection, so if you need the selection to move as well, you'll need to write additional code to move it there.

The ScrollIntoView method takes the following syntax:

expression.ScrollIntoView(Obj, Start)

Here, expression is a required expression that returns a Window object. Obj is a required argument specifying a Range or Shape object. Start is an optional Boolean argument that you can set to True (the default) to have the upper-left corner of the range or shape displayed or False to have the lower-right corner displayed. Specify False for Start when you need to make sure the end of a range or shape that may be larger than the window is displayed.

The following statements position the selection at the end of the last paragraph in the first list in the active document, ready to add a new paragraph to the list:

Dim rngFirstList As Range
Set rngFirstList = ActiveDocument.Lists(1).Range
ActiveDocument.Windows(1).ScrollIntoView Obj:=rngFirstList,
   Start:=False
rngFirstList.Select
Selection.Collapse Direction:=wdCollapseEnd
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdMove

Changing a Document's View

To change a document's view, set the Type property of the View object for the appropriate window to wdMasterView, wdNormalView, wdOutlineView, wdPrintPreview, wdPrintView, wdReadingView, or wdWebView. For example, the following statement changes the view for Sample.docm to Print Layout view:

Documents("Sample.docm").Windows(1).View.Type = wdPrintView

Zooming the View to Display Multiple Pages

To zoom Print Layout view or Print Preview to display multiple pages, set the PageColumns and PageRows properties of the appropriate View object. (Change the view first if necessary.) The following statement displays Sample.docm in Print Layout view with six pages displayed (three across by two deep):

With Documents("Sample.docm").Windows(1).View
    .Type = wdPrintView
    With .Zoom
        .PageColumns = 3
        .PageRows = 2
    End With
End With

Working with Tables

Many people need to work with tables in their Word documents, either creating them from scratch or manipulating existing tables. VBA uses the Table object to represent a table. If there is more than one Table object, they are gathered together into the Tables collection. To work with tables, you use the Tables property to return the Tables collection for the Document, Range, or Selection object in question.

The Tables collection and the Table object contain the following collections and objects:

  • The Rows collection contains the rows in the table. Each row is represented by a Row object.

  • The Columns collection contains the columns in the table. Each column is represented by a Column object.

  • The Cell object provides access to a specified cell directly from the Table object. You can also reach the cells in the table by going through the row or column in which they reside.

  • The Range object provides access to ranges within the table.

  • The Borders collection contains all the borders for the table.

  • The Shading object contains all the shading for the table.

Creating a Table

To create a new table from scratch (rather than converting existing text to a table), use the Add method with the Tables collection. The Add method takes the following syntax for the Tables collection:

expression.Add(Range, NumRows, NumColumns, DefaultTableBehavior, AutoFitBehavior)

The arguments are as follows:

  • expression is a required expression that returns a Tables collection. Typically, you'll want to use the Tables collection for the appropriate document.

  • Range is a required argument supplying the range where you want to insert the table. If the range is a selection (rather than being a collapsed selection, or insertion point), the table replaces the range.

  • NumRows is a required Long argument specifying the number of rows the table is to have.

  • NumColumns is a required Long argument specifying the number of columns the table is to have.

  • DefaultTableBehavior is an optional Variant argument specifying whether the table autofits its columns to their contents or to the window when you change the contents or the window width. Use wdWord9TableBehavior to have the table autofit its columns or wdWord8TableBehavior (the default) to have the columns retain their width.

  • AutoFitBehavior is an optional Variant argument specifying the autofit behavior for the table. This argument applies only when DefaultTableBehavior is wdWord9TableBehavior. Use wdAutoFitContent to resize the columns to their contents, wddAutoFitWindow to resize the columns to the window width, or wdAutoFitFixed to use a fixed column width.

For example, the following statement inserts a new, blank, non-autofitting table containing 10 rows and 5 columns at the current position of the insertion point in the active document:

ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=10, _
    NumColumns:=5, DefaultTableBehavior:=wdWord8TableBehavior

Selecting a Table

To select a table, specify the Document, Range, or Selection object involved, and then identify the Table object and use the Select method. This method takes no arguments.

The following statement selects the first table in the active document:

ActiveDocument.Tables(1).Select

The following statements declare the variable tempTable and then select the first table in the document named Log.docm and assign its Range object to tempTable:

Dim tempTable
Documents("Log.docm").Tables(1).Select
Set tempTable = Selection.Tables(1).Range

The following statement selects the second table in the range named tempRange:

tempRange.Tables(2).Select

This statement selects the first table in the current selection:

Selection.Tables(1).Select

Converting Text to a Table

To convert ordinary text to a table (as opposed to inserting a new table from scratch), use the ConvertToTable method with an appropriate Range or Selection object. The ConvertToTable method takes the following syntax:

expression.ConvertToTable(Separator, NumRows, NumColumns,
   InitialColumnWidth, Format, ApplyBorders, ApplyShading, ApplyFont,
   ApplyColor, ApplyHeadingRows, ApplyLastRow, ApplyFirstColumn,
   ApplyLastColumn, AutoFit, AutoFitBehavior, DefaultTableBehavior)

The arguments are as follows:

  • expression is a required argument specifying an expression that returns a Range object or a Selection object.

  • Separator is an optional Variant argument specifying the separator character (also known as the delimiter character) to use to mark where the column divisions were. You can use these values for Separator:

    • wdSeparateByCommas separates column information at commas.

    • wdSeparateByDefaultListSeparator separates column information at the currently specified Other list separator character (the character shown in the text box alongside the Other option button in the Convert Table to Text dialog box).

    • wdSeparateByParagraphs separates column information at the paragraph marks.

    • wdSeparateByTabs (the default separator if you don't specify one) separates column information at tabs.

    • Alternatively, you can specify a single separator character of your choice as a string or between double quotation marks. For example, enter Separator:="|" to use a vertical bar [|] as the separator.

  • NumRows is an optional Variant argument specifying the number of rows the table should have. If you omit the NumRows argument, Word decides the number of rows in the table based on the number of columns specified and/or the number of the chosen separator characters it finds.

  • NumColumns is an optional Variant argument specifying the number of columns the table should have. As with NumRows, if you omit the NumColumns argument, Word decides the number of columns in the table based on the number of rows specified and/or the number of the chosen separator characters it finds.

  • InitialColumnWidth is an optional Variant argument that you can use to specify the initial width (in points) of each column in the table. If you omit the InitialColumnWidth argument, Word uses the full width of the page—from margin to margin—and allocates an equal width to each column, regardless of the relative widths of the contents of the columns. The InitialColumnWidth argument is useful primarily for restraining tables from using the full width of the page automatically. In many cases, autofitting the columns provides a better solution.

  • Format is an optional Variant argument that you can use to specify one of Word's built-in autoformat styles for tables. To use the Format argument, specify the appropriate WdTableFormat constant (such as wdTableFormatElegant to specify the Elegant autoformat style). If you choose to apply a format, you can specify which properties of the autoformat style to apply to the table by using the following optional Variant arguments:

    • Set ApplyBorders to True to apply the border formatting or to False not to apply it.

    • Set ApplyShading to True to apply the shading or to False not to apply it.

    • Set ApplyFont to True to apply the font formatting or to False not to apply it.

    • Set ApplyColor to True to apply the color formatting or to False not to apply it.

    • Set ApplyHeadingRows to True to apply any heading-row formatting or to False not to apply it.

    • Set ApplyLastRow to True to apply any last-row formatting or to False not to apply it.

    • Set ApplyFirstColumn to True to apply any first-column formatting or to False not to apply it.

    • Set ApplyLastColumn to True to apply any last-column formatting or to False not to apply it.

  • AutoFit is an optional Variant argument you can set to True to have Word adjust the column width to best fit the contents of the cells. When autofitting, Word doesn't increase the overall width of the table—it either reduces the table or keeps it the same width.

  • AutoFitBehavior and DefaultTableBehavior are as described in the section "Creating a Table," earlier in the chapter.

The following statement converts the current selection to a five-column table, separating the information at commas. It applies autofitting to the table based on cell content and sets the cells to resize automatically:

Set myTable = Selection.ConvertToTable(wdSeparateByCommas, _
    Selection.Paragraphs.Count, 5, , , , , , , , , , , True, _
    wdAutoFitContent, wdWord9TableBehavior)

Making Sure the Selection Is within a Table

Before running any procedure that is intended to manipulate a table, it's a good idea to make sure that the current selection actually is within a table. Use the wdWithInTable argument of the Information property for the selection. wdWithInTable is Boolean, returning True if the selection is in a table and False if it isn't. Here's an example:

If Selection.Information(wdWithInTable) = True Then
    'take actions here
End If

Finding Out Where a Selection Is within a Table

In addition to establishing whether the selection is in a table, you can use the Information property to find out other information that can be useful when working with tables via a Range object or Selection object.

Once you've established that the selection is within a table (probably by using the wdWithinTable argument), check whether the selection is at an end-of-row marker rather than being in a cell. If the selection is at an end-of-row marker, certain actions fail. For example, attempting to select the current cell or column fails because the selection is outside any cell or column, but attempting to select the current row succeeds.

To check whether the selection is at the end-of-row marker, use the AtEndOfRowMarker argument for the Information property. The following statement moves the selection left one character (into the last cell in the same row) if the selection is at the end-of-row marker:

If Selection.Information(wdAtEndOfRowMarker) = True Then _
    Selection.MoveLeft Unit:=wdCharacter, Count:=1

If the selection contains the end-of-row marker rather than being a collapsed selection (an insertion point) before the marker, the wdAtEndOfRowMarker argument returns False. To avoid a selected end-of-row marker causing problems in your procedures, collapse the selection if it isn't collapsed before checking whether it's at the end-of-row marker. The following statements do this, using a variable named curSel to restore the selection it collapses unless collapsing the selection leaves the selection at an end-of-row marker:

Dim curSel
With Documents("Communications.docm")
    If Selection.Type <> wdSelectionIP Then
        Set curSel = Selection.Range
        Selection.Collapse Direction:=wdCollapseStart
    End If
    If Selection.Information(wdAtEndOfRowMarker) = True Then
        Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdMove
    Else
        If curSel <> "" Then curSel.Select
        Set curSel = Nothing
    End If
End With

After establishing that the selection is safely in a table, you can retrieve six useful pieces of information about the table:

  • wdStartOfRangeColumnNumber returns the number of the column in which the beginning of the selection or range falls. The following statement selects the column in which the current selection begins:

    Selection.Tables(1).Columns(Selection.Information _
        (wdStartOfRangeColumnNumber)).Select
  • wdEndOfRangeColumnNumber returns the number of the column in which the end of the selection or range falls. The following statements delete the column in which the range testRange ends if the range is more than one column wide:

    With testRange
        If .Information(wdStartOfRangeColumnNumber) <> _
    .Information(wdEndOfRangeColumnNumber) Then _
            .Tables(1).Columns(.Information _
            (wdEndOfRangeColumnNumber)).Delete
    End With
  • wdStartOfRangeRowNumber returns the number of the row in which the beginning of the selection or range falls.

  • wdEndOfRangeRowNumber returns the number of the row in which the end of the selection or range falls.

  • wdMaximumNumberOfColumns returns the highest number of columns in any row in the selection or range.

  • wdMaximumNumberOfRows returns the highest number of rows in the specified selection or range in the table.

Sorting a Table

To sort a table, identify the table and use the Sort method. Sort takes the following syntax with the Table object:

expression.Sort(ExcludeHeader, FieldNumber, SortFieldType, SortOrder,
   FieldNumber2, SortFieldType2, SortOrder2, FieldNumber3,
   SortFieldType3, SortOrder3, CaseSensitive, BidiSort, IgnoreThe,
   IgnoreKashida, IgnoreDiacritics, IgnoreHe, LanguageID)

The arguments are as follows:

  • expression is an expression that returns a Table object.

  • ExcludeHeader is an optional Variant argument that you can set to True to exclude the first row in the table (which is often the table header row) from the sort or to False to include the first row in the table.

  • FieldNumber, FieldNumber2, and FieldNumber3 are optional Variant arguments specifying the first, second, and third fields by which to sort (respectively). Usually you'll want to specify at least FieldNumber; if you don't, Word performs an alphanumeric sort on the table.

  • SortFieldType, SortFieldType2, and SortFieldType3 are optional Variant arguments specifying the type of sorting you want to use for FieldNumber, FieldNumber2, and FieldNumber3, respectively. For U.S. English, the options are alphanumeric sorting (wdSortFieldAlphanumeric, the default), numeric sorting (wdSortFieldNumeric), and date sorting (wdSortFieldDate).

  • SortOrder, SortOrder2, and SortOrder3 are optional Variant arguments specifying the sorting order for FieldNumber, FieldNumber2, and FieldNumber3. Use wdSortOrderAscending to specify an ascending sort (the default) or wdSortOrderDescending to specify a descending sort.

  • CaseSensitive is an optional Variant argument that you can set to True to specify case-sensitive sorting. The default setting is False.

  • The next five arguments (BidiSort, IgnoreThe, IgnoreDiacritics, IgnoreKashida, and IgnoreHe) are for specialized sorting (such as right-to-left languages, Arabic, and Hebrew).

  • LanguageID is an optional Variant argument that you can use to specify the language in which to sort. For example, to sort in Lithuanian, you could specify wdLithuanian for LanguageID. For sorting in your default language, you can omit this argument.

Adding a Column to a Table

To add a column to a table, use the Add method with the Columns collection for the appropriate Table object. The Add method takes the following syntax for the Columns collection:

expression.Add [BeforeColumn]

Here, expression is a required expression that returns a Columns collection, and BeforeColumn is an optional Variant argument specifying the column to the left of which you want to insert the new column.

The following statements use the Count property to check the number of columns in the first table in the active document and, if the table contains fewer than five columns, to add one or more columns to bring the number of columns up to five. Each new column is added before the existing last column in the table:

With ActiveDocument.Tables(1)
    .Select
    If .Columns.Count < 5 Then
        Do Until .Columns.Count = 5
            .Columns.Add BeforeColumn:=.Columns(.Columns.Count)
        Loop
     End If
End With

Deleting a Column from a Table

To delete a column, identify it and use the Delete method. Delete takes no arguments. The following statement deletes the first column in the table referenced by the object variable myTable:

myTable.Columns(1).Delete

Setting the Width of a Column

You can set the width of a column by using the AutoFit method, by using the SetWidth method, or by specifying the Width property for the column.

The AutoFit method resizes each column automatically to a width suitable to its contents. AutoFit takes no arguments. The following statement uses the AutoFit method to resize each column in the first table in the active document:

ActiveDocument.Tables(1).Columns.AutoFit

The SetWidth method allows you to set the width of one or more columns and specify how the other columns in the table should change as a result. The syntax for the SetWidth method is as follows:

expression.SetWidth ColumnWidth, RulerStyle

Here, expression is an expression that returns the Columns collection or Column object whose width you want to set. ColumnWidth is a required Single argument specifying the width of the column or columns, measured in points. RulerStyle is a required Long argument that specifies how Word should adjust the width of the columns:

  • The default value, wdAdjustNone, sets all the specified columns to the specified width, moving other columns to the left or right as necessary. This argument is analogous to Shift+dragging a column border when working interactively.

  • wdAdjustFirstColumn applies the specified width to the first specified column, adjusting only as many columns to the right of this column as necessary. For example, widening the first column in a table slightly causes Word to narrow the second column but leave the third and subsequent columns unchanged. Widening the first column significantly causes Word to narrow the second and third columns, leaving the fourth and subsequent columns unchanged. This argument is analogous to dragging a column border when working interactively.

  • wdAdjustProportional applies the specified width to the first specified column, keeping the right edge of the table in its previous position and adjusting all nonspecified columns proportionally to accommodate the change.

  • wdAdjustSameWidth applies the specified width to the first specified column, keeping the right edge of the table in its previous position and adjusting all the other columns to an identical width to accommodate the change. This argument is analogous to Ctrl+dragging a column border when working interactively.

The following statement sets the width of the second column in the first table in the active document to 50 points, adjusting the columns to the right of the second column proportionally:

ActiveDocument.Tables(1).Columns(2).SetWidth ColumnWidth:=50, _
    RulerStyle:=wdAdjustProportional

The Width property lets you change the width of a column without worrying about the effect on the other columns. Specify the width you want in points, as in this example:

ActiveDocument.Tables(11).Columns(44).Width = 100

Selecting a Column

To select a column, use the Select method with the appropriate Column object. Select takes no arguments. The following statement selects the second column in the third table in the document named Originals.docm:

Documents("Originals.docm").Tables(3).Columns(2).Select

Adding a Row to a Table

To add a row, use the Add method with the Rows collection for the table. The Add method takes the following syntax for the Rows collection:

expression.Add [BeforeRow]

Here, expression is a required expression that returns a Rows object, and BeforeRow is an optional Variant argument specifying the row before which you want to add the new row. If you omit BeforeRow, VBA adds the new row after the last existing row in the table.

The following statement adds a new first row to the table referenced by the object variable myTable:

myTable.Rows.Add BeforeRow:=1

You can also insert a row into a table at the current selection, using the InsertRowsBelow or InsertRowsAbove method. You specify how many rows. In this example, one row is inserted below the current selection:

Selection.InsertRowsBelow 1

Deleting a Row from a Table

To delete a row, use the Delete method with the appropriate Row object. The Delete method takes no arguments. The following statement deletes the first row in the table referenced by the object variable myTable:

myTable.Rows(1).Delete

Setting the Height of One or More Rows

You can set the height of rows by letting Word set the row height automatically, by using the SetHeight method to specify an exact height or a minimum height, or by setting the Height property of the row or rows directly.

To have Word set the height of a row automatically, set the row's HeightRule property to wdRowHeightAuto. Word then adjusts the height of the row to accommodate the cell with the tallest contents. The following statement sets the HeightRule property for the second row in the fourth table in the active document to wdRowHeightAuto:

ActiveDocument.Tables(4).Rows(2).HeightRule = wdRowHeightAuto

To specify an exact height or a minimum height for one or more rows, use the SetHeight method with the row or rows. The syntax for the SetHeight property is as follows:

expression.SetHeight RowHeight, [HeightRule]

Here, expression is an expression that returns a Row object or a Rows collection. HeightRule is a required Variant argument specifying the rule for setting the row height: use wdRowHeightAtLeast to specify a minimum height or wdRowHeightExactly to specify an exact height. (The third setting for HeightRule is wdRowHeightAuto, which specifies automatic row height and which you won't want to use in this case.)

Instead of using the SetHeight method, you can set the Height property of the row or rows in question by specifying the height in points:

Documents("Tables.docm").Tables(3).Rows(3).Height = 33

Selecting a Row

To select a row, use the Select method for the appropriate Row object. The Select method takes no arguments. The following statement selects the last row in the last table in the document named Tables.docm:

Documents("Tables.docm").Tables(.Tables.Count).Rows.Last.Select

Inserting a Cell

To insert a cell, use the Add method with the Cells collection. The Add method takes the following syntax for the Cells collection:

expression.Add [BeforeCell]

Here, expression is an expression that returns a Cells collection, and BeforeCell is an optional Variant argument that specifies the cell to the left of which the new cell should be inserted. (If you omit the BeforeCell argument, VBA adds a new row of cells to the end of the table if you're using the Cells collection of the Columns collection, or a new cell to the first row in the table if you're using the Cells collection of the Rows collection.)

The following statement inserts a cell before the second cell in the first row of the first table in the document named Tables.docm:

Documents("Tables.docm").Tables(1).Rows(1).Cells.Add _
    BeforeCell:=Documents("Tables.docm").Tables(1).Rows(1).Cells(2)

Returning the Text within a Cell

To return the contents of a cell, use the Text property of the Range object for the cell. The following statement returns the text in the first cell in the second row of the third table in the active document and assigns it to the variable strCellText:

strCellText = ActiveDocument.Tables(3).Rows(2).Cells(1).Range.Text

Because the Text property includes the end-of-cell marker (which takes up two characters), you'll usually want to strip off the last two characters when assigning the Text property to a string, like this:

strCellText = ActiveDocument.Tables(3).Rows(2).Cells(1).Range.Text
strCellText = Left(strCellText, Len(strCellText) - 2)

When using the Range object, you can work with any of the objects and collections it contains. For example, to work with the paragraphs in a cell, use the Paragraphs collection.

Entering Text in a Cell

To enter text in a cell, assign the text to the Text property of the Range object for the cell. The following statements enter text in the first three cells in the first row of the current selection:

With Selection.Tables(1).Rows(1)
    .Cells(1).Range.Text = "Sample text in first cell."
    .Cells(2).Range.Text = "Sample text in second cell."
    .Cells(3).Range.Text = "Sample text in third cell."
End With

Deleting Cells

To delete cells, use the Delete method with the appropriate Cell object or Cells collection. When you delete one or more cells, you must specify what happens to the rest of the table—whether the cells to the right of those you deleted move to the left or whether the cells below those you deleted move up.

The syntax for the Delete method for the Cells collection and the Cell object is as follows:

expression.Delete [ShiftCells]

Here, expression is an expression that returns a Cells collection or a Cell object. ShiftCells is an optional Variant argument that specifies how the cells below or to the right of the deleted cell or cells should move. Use these values:

  • wdDeleteCellsEntireColumn deletes the whole column in which the specified cell (or cells) is located.

  • wdDeleteCellsEntireRow deletes the whole row.

  • wdDeleteCellsShiftLeft moves cells across to the left to fill the gap.

  • wdDeleteCellsShiftUp moves cells up to fill the gap.

The following statement deletes the first cell in the first row of the first table in the active document and shifts the other cells in the first row to the left to fill the gap:

ActiveDocument.Tables(1).Rows(1).Cells(1).Delete _
    ShiftCells:=wdDeleteCellsShiftLeft

For procedures that rely on the user to make a selection within a table, you may want to determine how many rows or columns are in the selection before deciding how to shift the cells. The following example checks the number of rows and columns in a selection. If the selection is only one cell, or if the selection is all in one column, the code deletes the cell or cells and moves the other cells in the row to the left. If the selection is multiple cells in one column, the code deletes the cells and moves the other cells in the column up. If the selection spans columns and rows, the code displays a message box asking the user to make a selection in only one row or only one column:

With Selection
    If .Columns.Count > 1 And .Rows.Count > 1 Then
        MsgBox "Please select cells in only one row " _
            & "or only one column."
        End
    Else
        If .Cells.Count > 1 Then
            If .Columns.Count > 1 Then
                .Cells.Delete ShiftCells:=wdDeleteCellsShiftUp
            Else
                .Cells.Delete ShiftCells:=wdDeleteCellsShiftLeft
            End If
        Else
            .Cells.Delete ShiftCells:=wdDeleteCellsShiftLeft
        End If
    End If
End With

Selecting a Range of Cells

To select a range of cells within a table, declare a Range variable, assign to it the cells you want to select, and then select the range. The following example declares the Range variable myCells, assigns to it the first four cells in the first table in the active document, and then selects the range:

Dim myCells As Range
With ActiveDocument
    Set myCells = .Range(Start:=.Tables(1).Cell(1, 1).Range.Start, _
        End:=.Tables(1).Cell(1, 4).Range.End)
    myCells.Select
End With

Converting a Table or Rows to Text

To convert a table, a row, or a number of rows to text, specify the table, row, or rows and use the ConvertToText method. This is frequently useful if you're copying and pasting from Internet pages; they frequently contain tables that you're not interested in preserving. Due to limitations of the HTML language used to describe web page layout, HTML tables are used for spacing and other reasons unrelated to displaying actual tabular data. These faux "tables" can look bizarre when pasted as text into Word or other body text. To see how to get rid of these annoying artifacts, see the example macro at the end of this section. It's a useful macro to add to your copy of Word.

The ConvertToText method takes the following syntax:

expression.ConvertTotext(Separator, Nested Tables)

Here, expression is a required expression that returns a Table object, a Row object, or a Rows collection. Separator is an optional Variant argument specifying the separator character (also known as the delimiter character) to use to mark where the column divisions were. The possible values are as follows:

  • wdSeparateByCommas separates column information by commas.

  • wdSeparateByDefaultListSeparator separates column information by the currently specified Other list separator character (the character shown in the text box alongside the Other option button in the Convert Table To Text dialog box).

  • wdSeparateByParagraphs separates column information with paragraph marks.

  • wdSeparateByTabs (the default separator if you don't specify one) separates column information by tabs.

  • Alternatively, you can specify a separator character of your choice as a string or between double quotation marks. For example, enter Separator:="|" to use a vertical bar [|] as the separator. (Although you can supply more than one separator character here, Word uses only the first character.)

The following statement converts the first table in the current selection to text using an asterisk (*) as the separator character:

Selection.Tables(1).ConvertToText Separator:="*"

You can use the ConvertToText method with a Table object, a Row object, or a Rows collection. The following statement converts only the first row of the selected table to tab-delimited text:

Selection.Tables(1).Rows(1).ConvertToText Separator:=wdSeparateByTabs

If you need to continue working with the contents of the table once you've converted it, assign a range to the table as you convert it. You can then work with the Range object afterward to manipulate the information. For example, the following statements convert the first table in the document named Cleveland Report.docm to text separated by paragraphs and assign the range exTable to the converted information and then copy the range, create a new document, and paste in the information:

Dim exTable As Range
Set exTable = Documents("Cleveland Report.docm").Tables(1). _
    ConvertToText(Separator:=wdSeparateByParagraphs)
exTable.Copy
Documents.Add
Selection.Paste

Often when you copy and paste information from a web page, it's in a tabular format. If you paste such tables into Word, it usually doesn't look right, is too bulky, and can be difficult to edit or format. In other words, you want to remove the web page table definitions, but leave the data in a usable format within Word.

The following macro does just that:

Sub Untable()

On Error Resume Next

   Selection.Rows.ConvertToText Separator:=wdSeparateByCommas, NestedTables:= _
     True
   Selection.MoveDown Unit:=wdLine, Count:=1

If Err Then MsgBox "No table was detected, dude."

End Sub

To use this macro, click somewhere within the text you've pasted from the Internet to put the insertion cursor in a table (or a suspected table; they often don't look like tables, merely like an area of bizarre formatting), then execute the macro. You may need to execute this macro more than once to completely eliminate all the tabular formatting debris left over from the original HTML.

The Bottom Line

Use Find and Replace via VBA

Word's Find and Replace utilities are frequently valuable to the VBA programmer. You'll want to master them and also some subtleties associated with their use.

Master It

Sometimes when replacing, you need to go through a document more than once—using a loop structure. Why would you need to repeatedly search and replace the same document?

Work with headers, footers, and page numbers

All Word documents contain headers and footers, even if they are empty. In addition, you can insert various types of headers and footers.

Master It

Name two types of headers you can use in a Word document.

Manage sections, page setup, windows, and views

Among the various ways you can view a document, you sometimes want to have the document automatically scroll to a particular table, graphic, or other target.

Master It

What method of the Window object can be used to easily accomplish this task?

Manipulate tables

When you need to manage tables in Word documents, you can employ VBA to work with the Table object to represent a single table. If there is more than one table, they are referenced by a collection of Table objects.

Master It

Name two important and useful objects within the Tables collection or the Table object.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.51.246