In the previous chapter, you learned how to work with some of the fundamental 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.
Word's Find and Replace tool can be useful in some macros. You could use it, for example, to 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 approach when working with Find
. Typically, you will 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 that approach.
Table 21.1 describes the Find
properties that are useful for most search operations.
TABLE 21.1: Properties of the Find object
PROPERTY | MEANING |
Font |
Font formatting you're searching for (on either specified text or an empty string). |
Forward |
A Boolean variable-type 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 variable-type 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 Tip: 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 (fetches) 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. |
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
.
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 final five arguments, starting with MatchPrefix
, are not displayed in the Auto List Members tool in the Editor, nor in the MSDN parameter list. However, they can be used in code, as in, for example, IgnoreSpace:=True
.
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 the same special characters you use when using Word's Find dialog box 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 in a macro, 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 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.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. Depending on the Forward property, which governs the direction—forward or backward—of the search. |
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:
MatchPrefix
and MatchWholeWord
set to False
and 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.MatchWholeWord
to True
, and only the specific word itself, real, will result in a hit.MatchWholeWord
set to False
but 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.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. With long argument lists, it's always better for readability to use the named-argument approach, like this:
FindText:=“National Velvet”
This example replaces all pairs of paragraph marks (thereby removing empty lines) 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 executing this statement within 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 here 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.
This is how it works:
Document
object (Example.docm
in the Documents
collection) with which to work and begins a With
statement with its Find
object.ClearFormatting
method to clear any formatting from the Find
object.Bold
property of its Font
object to True
.With
statement for the Replacement
object.ClearFormatting
method to clear formatting from the Replacement
object.Bold
property to False
.Italic
property to True
.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.With
statement.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 when they're included in headers and footers.
You can create several types of headers and footers in a Word document: the primary header and footer, special headers and footers that appear only on the even pages, unique first-page-only headers and footers, and even different sets of headers and footers for each of the sections in a document if need be.
Every document automatically gets a 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 Layout tab on the Ribbon, and 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:
HeaderFooter
objects. You access headers through the Headers
property and footers through the Footers
property.HeadersFooters
collection contains all the HeaderFooter
objects in a given section of a document. Because each section of a document can have headers and footers unique to it, you reach any given header or footer by going through the section.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.HeaderFooter
object gives access to the Range
object, the Shapes
collection, and the PageNumbers
collection.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 that's in the second section of an open document named 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)
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
After running this macro, scroll your active document to see, on every other page, the new header.
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
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 tenth 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
To employ 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
A 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.
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 wdPageNumberAligment, 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: wdPageNumberAlignment 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
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
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
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
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
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) or 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
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.)
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.
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 breakwdSectionEvenPage
(3
) for an even-page breakwdSectionOddPage
(4
) for an odd-page breakwdSectionNewColumn
(1
) for a new-column breakwdSectionNewPage
(2
, the default) for a new-page breakThe 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 breakwdSectionBreakContinuous
(3
) for a continuous breakwdSectionBreakEvenPage
(4
) for an even-page breakwdSectionBreakOddPage
(5
) for an odd-page breakwdColumnBreak
(8
) for a new-column breakThe following statement inserts a continuous section break before the second paragraph in the active document:
ActiveDocument.Paragraphs(2).Range.InsertBreak _
Type:=wdSectionBreakContinuous
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
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))
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 except the first for the active document:
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
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
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
.
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 a thumb—the arrows at the top and bottom of the scroll bar). This scrolls the contents of the window by one entire “screen.” The SmallScroll
method is analogous to clicking a thumb. It 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
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
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
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
To change a document's view, set the Type
property of the View
object for the appropriate window to wdConflictView
, 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
Read mode hides the Ribbon, any markup, and nearly everything else except the text itself. Panes, however, such as Navigation and Thesaurus, do remain visible. The text itself is usually displayed as two pages or three (depending on your zoom level) side by side as in a book. You cannot edit in this view. Here's how to switch to Read mode:
ActiveDocument.ActiveWindow.View.Type = wdReadingView
Read mode is thoughtfully designed to make the content as easy to read and remember as possible. For example, the zoom feature (lower right) adjusts the font size but repaginates (reflows) so you never have the struggle with moving a horizontal scroll bar to show hidden text. There is a scroll bar, but it's never needed to display text that's out of view because of the zoom level. The zoom bar is strictly for global document navigation and as an indicator of your current position.
Read mode also gives you some control over column width. Most people find it easier to read shorter lines of text, so you can adjust line length in the View menu. The Esc key exits Read mode.
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
Many people need to work with tables in their Word documents, either creating them from scratch or manipulating existing tables.
VBA uses a Table
object to represent each individual 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.
Here is a sample of the collections and objects that are members of the Tables
collection and the Table
object:
Rows
collection contains the rows in the table. Each row is represented by a Row
object.Columns
collection contains the columns in the table. Each column is represented by a Column
object.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.Range
object provides access to ranges within the table.Borders
collection contains all the borders for the table.Shading
object contains all the shading for the table.For a complete list of the members of the Table
object, see this web page:
https://msdn.microsoft.com/en-us/library/office/ff195902.aspx
The members of the Tables
collection can be found here:
https://msdn.microsoft.com/en-us/library/office/ff822892.aspx
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
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
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.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:
ApplyBorders
to True
to apply the border formatting, or to False
not to apply it.ApplyShading
to True
to apply the shading, or to False
not to apply it.ApplyFont
to True
to apply the font formatting, or to False
not to apply it.ApplyColor
to True
to apply the color formatting, or to False
not to apply it.ApplyHeadingRows
to True
to apply any heading-row formatting, or to False
not to apply it.ApplyLastRow
to True
to apply any last-row formatting, or to False
not to apply it.ApplyFirstColumn
to True
to apply any first-column formatting, or to False
not to apply it.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 whatever contents are in the cells. When autofitting, Word doesn't increase the overall width of the table—it either reduces or retains it.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, delimiting (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)
Before running any procedure that is intended to manipulate a table, it's a good idea to make sure 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
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.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:
wdSortFieldAlphanumeric
, the default)wdSortFieldNumeric
)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
.BidiSort
, IgnoreThe
, IgnoreKashida
, IgnoreDiacritics
, 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.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 example uses the Count
property to check the number of columns in the first table in the active document. If this table contains fewer than five columns, one or more columns are added to bring the number of columns up to five. Each new column is added before (to the left of) 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
To delete a column, identify it (for example, use the number 1 as in the following statement), and then 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
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 that has the 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:
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:
Using 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 unspecified 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
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
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 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
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
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
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
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 it adds 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)
To return (fetch) 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.
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
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 macros 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
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
To convert an entire table or a row or number of rows to text, specify a table or row object, or a rows collection, then use their ConvertToText
method. This is frequently useful if you're copying and pasting from Internet pages. They often contain tables and you just want the text, not the table structure itself. Due to the limitations of the HTML language used to describe web page layout, HTML tables are sometimes used for spacing and other purposes unrelated to displaying actual tabular data. These faux “tables” can look bizarre when pasted as text into Word or other body text. To find out how to get rid of these annoying artifacts, see the example macro—Sub Untable ( )
—at the end of this section. It's a useful macro to add to your Normal project in Word's VBA Editor because you might find yourself using it often.
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.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), and then execute the macro. You may need to execute this macro more than once in the same location in your document to completely eliminate all the tabular formatting debris left over from the original HTML. The macro tells you when all table structures have been destroyed, and not only that—it calls you “dude.”
Window
object can be used to easily accomplish this task?Table
object to represent a single table. If there is more than one table, they are referenced by a collection of Table
objects.
Tables
collection or the Table
object.