I found that globally changing tables is not something that Table and Cell Styles do very good. Apart from the ever-present problem that "cell styles just don't take" (something I've always wondered about), there are just too many things that you cannot do with Cell Styles. So I've relied on scripting to format my tables for a long time now.
I have a basic framework set up to handle different kinds of selections, and you can add just about any functionality you want to it. See the InDesignSecrets article Tackling Tables through Scripting I wrote on this for the full story, plus a couple of hints on what you can do with it!
Adding some space below odd rows only is a breeze – the first functions here are the "framework", the work on each table is done in the final function:
app.doScript(checkUserSelection, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Process Table");
function checkUserSelection ()
{
var a_table = checkWhichTable();
if (a_table == null)
{
if (confirm("No table selected. Do you want to process *all* tables?") == false)
return;
allTables = app.activeDocument.stories.everyItem().tables.everyItem().getElements();
for (aTable=0; aTable<allTables.length; aTable++)
{
processTable (allTables[aTable]);
}
} else
{
processTable (a_table);
}
}
function checkWhichTable()
{
// ensure the user made a selection
if (app.selection.length != 1)
return null;
var currentTable = app.selection[0];
if (currentTable.hasOwnProperty("baseline"))
{
currentTable = app.selection[0].parent;
}
while (currentTable instanceof Cell || currentTable instanceof Row || currentTable instanceof Column);
currentTable = currentTable.parent;
if (!(currentTable instanceof Table))
{
// No table selected
return null;
}
return currentTable;
}
function processTable(table)
{
// do something here!
var r;
for (r=2; r<table.rows.length; r+=3)
table.rows[r].cells.everyItem().bottomInset = "20pt";
}
The function processTable
is where the magic happens; in this case, I changed the bottom inset to 20pt
to add some white space below each cell in the selected rows. (The everyItem()
thingy is a trick where all cells in a row get addressed at the same time. Properly explaining it takes more knowledge than I have; I only know how to use it :) You can read Marc Autret's On ‘everyItem()’ – Part 1 if it interests you (and that's just Part 1!).)
If you want to only change the row height (which leads to a slightly different result with cells that contain more than a single line), you can do that as well:
function processTable(table)
{
// do something here!
var r;
for (r=2; r<table.rows.length; r+=3)
table.rows[r].height = "30pt";
}
Note that Javascript starts counting its rows at 0
and not at 1
. If I recall correctly, VBA starts by default with 1
; and so your own 3
would be 2
in Javascript.
Javascript does not like accessing items that do not exist. Your own loop goes up to 2000, and I guess that's a value of which you thought "surely that would be enough" (right up to when you encounter a table where it is not) but in Javascript, you'd get an error if a table is shorter than that. Thus the explicit test on length
inside my own loops.