Skip to main content
Participant
August 1, 2019
Answered

Iterating over all of the tables in a document

  • August 1, 2019
  • 1 reply
  • 1278 views

Hello there. I have a document containing a lot (maybe 100?) similar tables. These tables are used as graphical aids by coloring in certain cells -- rather than the normal use of displaying values. I do not want to manually change each cell color so I wrote a basic script that takes a selected table, looks at the values in one column, and tints the cells in each row accordingly. But now, I don't want to select and run the code for each table manually so I thought I would add a bit extra to simply run the code for every table in the document. It somewhat works (it finds the values in the correct column and it does iterate through the table properly) but instead of only pulling a single cell's value, it pulls multiple values.

For example, if I have two tables and the values to read through in the first table are [1, 3, 1, 2, 2, 1] and are [2, 3, 1, 1, 1, 2] in the second table, I would expect my code to go through the first table and then go through the second table. Instead, it reads '1,2' and then '3,3' etc.

Here is the code:               Thank you for your help!

var tablelist = app.documents[0].stories.everyItem().tables;

alert("Edditing "+tablelist.length+" tables in document");

var t;

for (t=0; t<tablelist.length; t++){

var

table = tablelist,

len = table.cells.length,

i;

//alert(table);

//alert(table.cells);

for (i=3; i <= len;) {

var value = table.cells.contents;

alert(table.cells);

if (value == 1){

table.cells[i-1].fillTint = 0;

table.cells[i-2].fillTint = 0;

table.cells[i-3].fillTint = 100;

};

else if (value == 2){

table.cells[i-1].fillTint = 0;

table.cells[i-2].fillTint = 100;

table.cells[i-3].fillTint = 0;

};

else if (value == 3){

table.cells[i-1].fillTint = 100;

table.cells[i-2].fillTint = 0;

table.cells[i-3].fillTint = 0;

};

else {

alert("invalid fill " + value);

table.cells.fillColor = "Black";

};

i += 4;

};

};

This topic has been closed for replies.
Correct answer Marc Autret

Hi finnr,

This is a “plural specifier” problem. The reference app.documents[0].stories.everyItem().tables is not an array of Table instances, this is an unresolved collection based on multiple stories. When you read tablelist for some value of t, what you actually get is a plural specifier that points out to every t-indexed table in every story. For example, tablelist[0] represents in a single expression the first table of all stories. Then tablelist[0].cells represents the set of every i-indexed cell in the first table of all stories. Hence the weird fact that tablelist[0].cells.contents returns an Array of strings.

All you have to do is to convert the plural specifier into an actual array of tables at the very beginning:

var tablelist = app.documents[0].stories.everyItem().tables.everyItem().getElements();

// . . .

Suggested code:

(function(  a,t,i,v)

{

    a = app.documents[0].stories.everyItem().tables.everyItem().getElements();

    while( t=a.pop() ) for( t=t.cells, i=t.length-1 ; i >= 3 ; i -=4 )

    {

        v = parseInt(t.contents,10);

        if( isNaN(v) || 1 > v || v > 3 )

        {

            // alert("Invalid fill value: " + v);

            t.fillColor = "Black";

            continue;

        }

        t[i-1].fillTint = (3==v)*100;

        t[i-2].fillTint = (2==v)*100

        t[i-3].fillTint = (1==v)*100;

    }

})();

@+

Marc

1 reply

Marc Autret
Marc AutretCorrect answer
Legend
August 1, 2019

Hi finnr,

This is a “plural specifier” problem. The reference app.documents[0].stories.everyItem().tables is not an array of Table instances, this is an unresolved collection based on multiple stories. When you read tablelist for some value of t, what you actually get is a plural specifier that points out to every t-indexed table in every story. For example, tablelist[0] represents in a single expression the first table of all stories. Then tablelist[0].cells represents the set of every i-indexed cell in the first table of all stories. Hence the weird fact that tablelist[0].cells.contents returns an Array of strings.

All you have to do is to convert the plural specifier into an actual array of tables at the very beginning:

var tablelist = app.documents[0].stories.everyItem().tables.everyItem().getElements();

// . . .

Suggested code:

(function(  a,t,i,v)

{

    a = app.documents[0].stories.everyItem().tables.everyItem().getElements();

    while( t=a.pop() ) for( t=t.cells, i=t.length-1 ; i >= 3 ; i -=4 )

    {

        v = parseInt(t.contents,10);

        if( isNaN(v) || 1 > v || v > 3 )

        {

            // alert("Invalid fill value: " + v);

            t.fillColor = "Black";

            continue;

        }

        t[i-1].fillTint = (3==v)*100;

        t[i-2].fillTint = (2==v)*100

        t[i-3].fillTint = (1==v)*100;

    }

})();

@+

Marc

Participant
August 1, 2019

Excellent, Thank you so much! I knew the issue was something with everyItem() but I would never have found that solution on my own. This worked perfectly.