5.2 Tables

Tables

Word s tables seem like a natural fit for representing VFP data. A row can represent a record, with each column representing a field. What Word buys you is the ability to format the data and the table itself in sophisticated ways, well beyond the capabilities of FoxPro s Report Designer, as well as let users manipulate the results or produce output in alternative formats. A table can be formatted as a whole, but individual cells can be separately formatted, as well. Borders of tables and cells can be visible or invisible, and they can take on a range of sizes and styles. (See the section "Borders and shading" in Chapter 4 for details on formatting borders.) Both columns and rows can be individually sized.

The object hierarchy for tables is a little confusing. Each document has a Tables collection, which, in turn, contains individual Table objects. The Table object contains both Rows and Columns collections, which contain Row and Column objects, respectively. Those objects each have a Cells collection that references the individual cells in the row or column, each represented by a Cell object. While the Table object doesn t have a Cells collection, the individual Cell objects can be accessed by using the Cell method, which accepts row and column number parameters. Here are several ways to refer to the cell in the third row and fourth column of the first table in the active document:

oWord.ActiveDocument.Tables[1].Rows[3].Cells[4]

oWord.ActiveDocument.Tables[1].Columns[4].Cells[3]

oWord.ActiveDocument.Tables[1].Cell[3,4]

Interactively, you can add a table by choosing Table|Insert|Table from the menu, which brings up the dialog shown in Figure 3.

Figure 3. Adding a table. To add a table interactively, you specify the number of columns and rows and, if you want, whether the columns should resize automatically to fit their contents. You can also specify a predefined format for the table.

With Automation, since Tables is a collection, it s not surprising that the way to add a table to a document is to call the Add method of that collection. It takes several parameters:

oDocument.Tables.Add( oRange, nRows, nColumns, nTableBehavior, nAutoFit )

oRange

Object

Reference to a range that indicates where to insert the new table.

nRows

Numeric

The number of rows in the new table.

nColumns

Numeric

The number of columns in the new table.

nTableBehavior

Numeric

A constant that indicates whether the table automatically resizes to fit its contents.

wdWord8TableBehavior

0

Don t resize automatically.

wdWord9TableBehavior

1

Resize automatically.

 

nAutoFit

Numeric

If nTableBehavior is wdWord9TableBehavior, indicates which algorithm is used to resize the cells.

wdAutoFitFixed

0

Fixed column width.

wdAutoFitContent

1

Size cells to content.

wdAutoFitWindow

2

Size table to full width of window.

 

 

The last two parameters are optional. If you omit them, you get the older, Word 97 behavior of a table that doesn t resize as you fill it. However, you can change that behavior. The AllowAutoFit property and AutoFitBehavior method control this resizing capability.

Even if you re not allowing automatic resizing of columns, the AutoFit method of the Column object lets you resize individual columns based on their content. Rather than having cells change size as data is entered, you apply the changes once you ve put something into the table. Column s SetWidth method lets you set a column to a specific width, in points.

Once you ve added a table interactively, the Table Properties dialog on the Table menu allows you to adjust various characteristics of the table as a whole and of the individual rows, columns, and cells. Figure 4 shows the Row page of that dialog.

Figure 4. Formatting a table. The Table Properties dialog lets you resize rows and columns, as well as specify other characteristics of tables and their components.

Table 1 shows the most commonly used properties of the Table object.

Table 1. Defining tables. These properties of the Table object are the ones you re most likely to work with.

Property

Type

Description

Rows

Object

Pointer to the Rows collection for the table.

Columns

Object

Pointer to the Columns collection for the table.

Uniform

Logical

Indicates whether every row has the same number of columns. (Read-only)

Borders

Object

Pointer to the Borders collection for the table.

Shading

Object

Pointer to the Shading object for the table.

AllowAutoFit

Logical

Indicates whether columns are automatically resized as data is added to the table. Corresponds to the nTableBehavior parameter of the Tables.Add method.

AllowPageBreaks

Logical

Indicates whether the table can be split over multiple pages in the document.

AutoFormatType

Numeric

A constant indicating which, if any, of a set of predefined formats has been applied to the table. AutoFormats are applied with the AutoFormat method. Here's a sampling:

wdTableFormatNone

0

wdTableFormatSimple1

1

wdTableFormatClassic1

4

wdTableFormatColorful1

8

wdTableFormatContemporary

35

wdTableFormatElegant

36

wdTableFormatGrid1

16

 

Spacing

Numeric

Indicates the space between cells, in points. This is the space that actually separates the cells, not the boundary between the cell border and the text.

Row and Column, not surprisingly, have a number of properties in common, including Cells to point to a Cells collection and Shading to reference a Shading object. Row also has a Borders property that references a Borders collection, though Column does not. Both objects have logical IsFirst and IsLast properties that, as their names suggest, indicate whether the particular row or column is the first or last in the collection.

At this point, the two objects part company, though there are still similarities. The size of a Row is determined by HeightRule and Height, as indicated in Table 2. Column width also uses two properties PreferredWidth and PreferredWidthType, shown in Table 3.

Row has one other size-related property, SpaceBetweenColumns. It indicates the distance between the cell boundaries and the text. The value of the property is half what you set in Word itself because that one is measured from the text in one cell to the text in the next cell.

Row s AllowBreakAcrossRows property determines what happens when the contents of a row don t fit on the current page. If it s .T., the row can be split over two pages; if .F., a page break occurs before the row.

When a table is split over multiple pages, rows whose HeadingFormat property is set to .T. are repeated.

One big difference between Row and Column is that a Row can be a Range while a Column cannot.

Table 2. Determining row size. Two Row properties combine to let you indicate the height of the row.

Property

Type

Description

HeightRule

Numeric

Indicates the logic used to determine the height of this row. Use one of the following constants:

wdRowHeightAuto

0

wdRowHeightAtLeast

1

wdRowHeightExactly

2

 

Height

Numeric

The height for the row, if HeightRule is wdRowHeightExactly. The minimum height for the row, if HeightRule is wdRowHeightAtLeast. Ignored (and uninformative when queried) if HeightRule is wdRowHeightAuto; in that case, the row height is based on the row s contents.

Table 3. Specify column width. As with rows, two properties combine to indicate the size of a column.

Property

Type

Description

PreferredWidth

Numeric

Desired width for this column, either in points or as a percentage of the overall window width. Interpretation is determined by PreferredWidthType.

PreferredWidthType

Numeric

Indicates whether PreferredWidth is measured in points or percent, or is ignored.

wdPreferredWidthAuto

0

Size column by contents.

wdPreferredWidthPoints

1

Size column in points.

wdPreferredWidthPercent

2

Size column as percentage of total window.

 

 

Cell shares a number of properties with Table, Row, and Column, including Borders, Shading, HeightRule, Height, PreferredWidth, and PreferredWidthType. Table 4 shows some other properties that are unique to Cell.

Table 4. Cell holdings. At the bottom of the table hierarchy, cells have quite a few properties. Here are some you re likely to deal with.

Property

Type

Description

Width

Numeric

The width of the cell, in points.

WordWrap

Logical

Indicates whether the text is wrapped into multiple lines and the cell height is increased to fit the entire contents.

FitText

Logical

Indicates whether the display size of the text (but not the actual font size) is reduced in order to make the entire contents of the cell fit onto a single line.

VerticalAlignment

Numeric

Indicates the vertical position of the text in the cell.

wdAlignVerticalTop

0

wdAlignVerticalCenter

1

wdAlignVerticalBottom

3

 

 

Table, Row, and Cell all have Range properties, so an entire table, row, or cell can be easily converted to a range. This means that the same techniques work for inserting text into a table as for other parts of a document. However, a Range that s created from a cell contains a special end-of-cell marker. To access only the text in a cell, move the end of the range back one character. Either of the following does the trick:

oRange.End = oRange.End - 1

oRange.MoveEnd( wdCharacter, -1 )

The program shown in Listing 1 opens TasTrade s Order History view and creates a Word table that shows the order history for the current customer. It demonstrates a variety of features, including borders, shading, and auto-sizing of columns. The program is OrderTblFormat.PRG in the Developer Download files available at www.hentzenwerke.com.

Listing 1. Creating a table. This program generates a table that contains a customer s order history.

* Create a Word table with order information for one customer

* Set up the table with two rows, formatting the second row for

* the data. Then add rows as needed for each record.

 

#DEFINE wdStory 6

#DEFINE wdCollapseEnd 0

#DEFINE CR CHR(13)

#DEFINE wdBorderTop -1

#DEFINE wdLineStyleDouble 7

#DEFINE wdAlignParagraphLeft 0

#DEFINE wdAlignParagraphCenter 1

#DEFINE wdAlignParagraphRight 2

RELEASE ALL LIKE o*

PUBLIC oWord

LOCAL oRange, oTable, nRecCount, nTotalOrders

LOCAL nRow

oWord = CreateObject("Word.Application")

oWord.Documents.Add()

OPEN DATABASE (_SAMPLES + "Tastrade\Data\Tastrade")

USE CUSTOMER

GO RAND()*RECCOUNT() && pick a customer at random

* Open the Order History view, which contains

* a summary of orders for one customer.

SELECT 0

USE "Order History" ALIAS OrderHistory

* Find out how many records.

nRecCount = _TALLY

oRange = oWord.ActiveDocument.Range()

* Set up a font for the table

oRange.Font.Name = "Arial"

oRange.Font.Size = 12

* Move to the end of the document

* Leave two empty lines

oRange.MoveEnd( wdStory )

oRange.Collapse( wdCollapseEnd )

oRange.InsertAfter( CR + CR )

oRange.Collapse( wdCollapseEnd )

* Add a table with two rows

oTable = oWord.ActiveDocument.Tables.Add( oRange, 2, 4)

WITH oTable

* Set up borders and shading.

* First, remove all borders

.Borders.InsideLineStyle = .F.

.Borders.OutsideLineStyle = .F.

* Shade first row for headings

.Rows[1].Shading.Texture = 100

* Put heading text in and set alignment

.Cell[1,1].Range.ParagraphFormat.Alignment = wdAlignParagraphRight

.Cell[1,1].Range.InsertAfter("Order Number")

.Cell[1,2].Range.ParagraphFormat.Alignment = wdAlignParagraphLeft

.Cell[1,2].Range.InsertAfter("Date")

.Cell[1,3].Range.ParagraphFormat.Alignment = wdAlignParagraphRight

.Cell[1,3].Range.InsertAfter("Total")

.Cell[1,4].Range.ParagraphFormat.Alignment = wdAlignParagraphCenter

.Cell[1,4].Range.InsertAfter("Paid?")

* Format data cells

.Cell[2,1].Range.ParagraphFormat.Alignment = wdAlignParagraphRight

.Cell[2,3].Range.ParagraphFormat.Alignment = wdAlignParagraphRight

.Cell[2,4].Range.ParagraphFormat.Alignment = wdAlignParagraphCenter

* Add data and format

* Compute total along the way

nTotalOrders = 0

FOR nRow = 1 TO nRecCount

WITH .Rows[nRow + 1]

.Cells[1].Range.InsertAfter( Order_Id )

.Cells[2].Range.InsertAfter( TRANSFORM(Order_Date, "@D") )

.Cells[3].Range.InsertAfter( TRANSFORM(Ord_Total, "$$$$$$$$$9.99") )

* Put an X in fourth column, if paid; blank otherwise

IF Paid

.Cells[4].Range.InsertAfter("X")

ENDIF

ENDWITH

* Add a new row

.Rows.Add()

* Running Total

nTotalOrders = nTotalOrders + Ord_Total

SKIP

ENDFOR

* Add a double line before the totals

.Rows[nRecCount + 2].Borders[ wdBorderTop ].LineStyle = wdLineStyleDouble

* Put total row in

WITH .Rows[ nRecCount + 2]

.Cells[1].Range.InsertAfter("Total")

.Cells[3].Range.InsertAfter(TRANSFORM(nTotalOrders, "$$$$$$$$$9.99"))

ENDWITH

* Size columns. For simplicity, let Word

* do the work.

.Columns.Autofit

ENDWITH

RETURN

The results are shown in Figure 5.

Figure 5. Using tables for data. A customer s order history looks good when poured into a Word table.

The code creates a two-row table, inserts the headings, then formats the cells in the second row. The loop then inserts the data and adds a new row. Each new row picks up the formatting of the previous one, so the formats only have to be applied once.

You can combine the code (removing the part that chooses a customer record) with Styles.PRG from Chapter 4, "Word Basics" (you can see the result in Figure 7 in that chapter), and you have a reasonably attractive order history report for a customer. Wrap that in a loop with a few more commands (such as InsertBreak to add page breaks), and you can produce order histories for all customers or a selected set.

Irregular tables

Tables don t have to consist of simple grids. Not every row has to have the same number of columns. The Merge and Split methods of Cell and Cells let you combine and take apart groups of cells to create irregular tables. The Uniform property of Table indicates whether a table is regular or not; be sure to check it before using nested FOR EACH loops to try to process every row and column in a table.

The Merge method works in two ways. You can either call it for one cell and pass it another to have those two merged, or you can call it with a range of cells to have those cells merged. Here are the two syntax formats:

oFirstCell.Merge( oSecondCell )

oCells.Merge()

For example, to combine the second and third cells in row 1 of table oTable, you can use this code (all of the following assume that oTable is a reference to the table you re working with):

oTable.Cell(1,2).Merge( oTable.Cell(1,3) )

To change the fourth row of a table into a single cell, use code like this:

oRange = oTable.Rows[4].Range()

oRange.Cells.Merge()

Figure 6 shows a table (that started out with five rows and seven columns) after making those two changes.

Figure 6. Irregular table. Tables don t have to have the same number of columns in each row. The Merge and Split methods let you create irregular tables.

Split takes a cell or collection of cells and divides it into one or more cells. It can optionally merge the cells before splitting them. Again, there are two different forms for the method, depending on whether you call it from a single cell or from a collection of cells:

oCell.Split( nRows, nColumns)

oCells.Split( nRows, nColumns [, lMergeFirst ] )

For example, to divide the first cell in row 3 into two cells in the same row, use this command:

oTable.Cell(3,1).Split(1,2)

This code takes the cells in the second row of a table, combines them, then splits them into three, resulting in just three cells in that row:

oTable.Rows[2].Cells.Split( 1, 3, .t.)

If you omit the third parameter from that call (.t.), each cell in the row would be split into three. If you pass something other than 1 as the first parameter, the single row would become multiple rows in the table.

Using Merge and Split, you can create extremely complex tables. While this provides for an attractive way to display data, keep in mind that it does make it harder to process the document. Simple FOR EACH loops through the Rows and Columns collections don t work when Uniform is .F.

 

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



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

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