Saturday, December 10, 2011

Straddling Table Cells

Table cells are said to be straddled if a rectangular group of cells is combined to form a single cell. When defining a straddle, you must identify the leftmost and uppermost cell and determine how many rows and columns are to be straddled.

Straddles are determined by a number of  cells to the right and below a specified cell. The FDK model is shown below with cellId referring to the second cell in the second row. 

F_ApiStraddleCells(docId, cellId, 2, 3);



Here is the ExtendScript code and the result of straddling the second cell in the second table row.

var doc, table, row, cell;

doc = app.ActiveDoc;
table = doc.SelectedTbl;
if (table.ObjectValid()) {
    row = table.FirstRowInTbl;
    row = row.NextRowInTbl; //second row
    if (row.ObjectValid()) {
        cell = row.FirstCellInRow; //first cell
        cell = cell.NextCellInRow; // second cell
        if (cell.ObjectValid()) {
            cell.StraddleCells(2, 3); // 2 down, 3 across
        }
    }
}

WARNING: If this table had a header, the first row would be a header row. So don't get confused when counting rows in order to do a straddle. Header cells cannot be straddled with body cells.

Friday, December 9, 2011

Getting Table Cells Column by Column

Traversing a table's cells column by column is a little tricky due to the fact that there is no column object. The following algorithm does the job:
  1. Get the first row in the table using the Tbl property FirstRowInTbl.
  2. Get the first cell in that row using the Row property FirstCellInRow.
  3. While there are additional cells in the column, get the next cell in that column using the Cell property CellBelowInCol.
  4. While there are additional cells in the first row, get the next cell in that row using the NextCellInRow property. 
  5. Go to step 3.
This cell traversal pattern is illustrated below.
The following script traverses the selected table using this algorithm.

var doc, table, row, topRowCell, cell, cellNum = 0;

doc = app.ActiveDoc;
table = doc.SelectedTbl;
row = table.FirstRowInTbl;
if (row.ObjectValid()) { //get first row
    topRowCell = row.FirstCellInRow;
    while (topRowCell.ObjectValid()) {//traverse cells in first row
        cell = topRowCell;
        while (cell.ObjectValid()) { //traverse cells in column
            cellNum = cellNum + 1;
            var tLoc = new TextLoc();  //create text location object
            tLoc.obj = cell; //make it a cell
            tLoc.offset = 0; // insert at the start of the cell
            doc.AddText(tLoc, "Cell "  + cellNum);
            cell = cell.CellBelowInCol;
        }
        topRowCell = topRowCell.NextCellInRow;
        cell = topRowCell;
    }
}

An example of the output produced by this script is shown below.


Thursday, December 8, 2011

Getting Table Cells Row by Row

Once you have a table identifier, you can access each of the cells within that table. This post focuses on accessing cells from left to right and top to bottom.

To do so:
  1. Get the first row in the table using the Tbl property FirstRowInTbl.
  2. Get the first cell in that row using the Row property FirstCellInRow.
  3. While there are additional cells, get each using the Cell property NextCellInRow.
  4. While there are additional rows, get each using the Row property NextRowInTbl.
Here is a script that does just that and writes to each cell in the order visited.

var doc, table, row, cell, cellNum = 0;

doc = app.ActiveDoc;
table = doc.SelectedTbl;
row = table.FirstRowInTbl;
while (row.ObjectValid()) { //traverse rows
    cell = row.FirstCellInRow;
    while (cell.ObjectValid()) { //traverse cells in row
        cellNum++;
        var tLoc = new TextLoc();  //create text location object
        tLoc.obj = cell; //make it a cell
        tLoc.offset = 0; // insert at the start of the cell
        doc.AddText(tLoc, "Cell "  + cellNum);
        cell = cell.NextCellInRow;
    }
    row = row.NextRowInTbl;
}

Note: The first row in a table can be a header row (as shown) or a body row if no header exists.

Monday, December 5, 2011

Adding Columns to a Table

Table columns differ from table rows because rows are object while columns are not. When adding a column you must specify the column number from which to start adding, the direction of the addition, and the number of coumns to add.

Columns are numbered from left to right with the first column being column 0.


The direction is either FV_Left or FV_Right.

The following script adds three columns after the second column in the selected table.

NOTE: A table is selected if any of its cells are selected or the insertion point is in any of its cells. 

var doc, table;

doc = app.ActiveDoc;
table = doc.SelectedTbl;
table.AddCols (1, Constants.FV_Right, 3);

Before running script


After running script

Sunday, December 4, 2011

Adding Rows to a Table

Adding rows to a table requires that you know the identifier of the table and that of the row you want to add before or after. You then specify the direction you want to add in and the number of rows to add.

You can specify:
  • Above (FV_Above)
  • Below  (FV_Below)
  • To the Footer (FV_Footing)
  • To the Header (FV_Heading)
  • At the bottom of existing body rows (FV_Body)

The following example adds two rows below the last body row in the table. In the case of the Portrait template, this turns out to be the bottom of the HTML Mapping Table on the third reference page and not the first table on the first body page. This reflects the fact that the script uses FirstTblInDoc, an unordered list.


NOTE: To get tables in flow order use GetText() with the flag FTI_TblAnchor.

NOTE: Rows are accessed via an ordered list. They can be navigated top to bottom (FirstRowInTbl, then NextRowInTbl) or bottom to top (LastRowInTbl, then PrevRowInTbl).

doc = app.ActiveDoc;
table = doc.FirstTblInDoc;
row = table.LastRowInTbl;    
row.AddRows(Constants.FV_Below, 2);     


Saturday, December 3, 2011

Creating a Table

Adding a table is a straight-forward task. You need to know the name of an existing table format, how many rows, columns, header rows, and footer rows to all and the location in text where the table is to be added.

The example below adds a table at the start of the current selection. It uses a table format found in the default Portrait template.

var doc, tRange, table;

doc = app.ActiveDoc;
tRange = doc.TextSelection;
table = doc.NewTable("Format A", 3, //number of rows
                                 2, //number of columns
                                 1,  //number of header rows
                                 0,  //number of footer rows
                                 tRange.beg);


Thursday, December 1, 2011

Tables

Tables are represented by the Tbl object. They consist of one or more Row objects with each row having one or more Cell objects.

NOTE: Table cells are a special type of text frame. They can contain text and almost anything that can be inserted into text with the exception that tables cannot be inserted directly into table cells. You can add a table inside a table cell by placing an anchored frame within the cell, a text frame within that anchored frame and then inserting the table.

Tables have a large number of the properties that reflect the choices a user might make table design dialog box.

There are two ways to find tables:
  • If you want all tables in any order, use the list of all tables in a document. Use the  FirstTblInDoc document property, NextTblInDoc table property.
  • If you want tables in flow order, use GetText() using the flag Constants.FTI_TblAnchor.