15 Replies Latest reply on Dec 2, 2016 1:11 AM by Obi-wan Kenobi

    Change text color in tables! …

    Obi-wan Kenobi Adobe Community Professional

      Hi Scripters,

       

      I'm trying to change color of the text in some rows but not all! As:

       

      Capture d’écran 2016-11-30 à 22.35.13.png

       

      Capture d’écran 2016-11-30 à 22.37.07.png

       

      … with this code:

       

      var
      myDoc = app.activeDocument,  
      myTables = myDoc.stories.everyItem().tables.everyItem().getElements();  
        
      for ( var t = 0 ; t < myTables.length; t++ )  
      {  
              var myRows = myTables[t].rows;         
              for ( var r  = 1 ; r  < myRows.length; r += 2 )  
              {  
                         var myCells = myRows[r].cells;                    
                         for ( var c = 0 ; c < myCells.length; c++ )  
                         {  
                          myCells[c].contents.fillColor = myDoc.colors.itemByName("Blue");
                         }  
              }
      }
      

       

       

      … But, of course, it doesn't work!

       

      As usual, thanks for your help! 

       

      (^/)

        • 1. Re: Change text color in tables! …
          Obi-wan Kenobi Adobe Community Professional

          … Apparently, my error is at line 13. To be corrected as:

           

                              myCells[c].texts[0].fillColor = myDoc.colors.itemByName("Blue"); 
          

           

          … But I find this script very slow! 

           

          Is there a different writing to make it faster!

           

          Thanks again! 

           

          (^/)

          • 2. Re: Change text color in tables! …
            Peter Kahrel Adobe Community Professional & MVP

            This is probably quicker (it's certainly quicker to type):

             

            app.findGrepPreferences = app.changeGrepPreferences = null;
            app.findGrepPreferences.fillColor = 'Black';
            app.changeGrepPreferences.fillColor = 'Blue';
            app.documents[0].stories.everyItem().tables.everyItem().changeGrep();
            

             

            Peter

            • 3. Re: Change text color in tables! …
              Obi-wan Kenobi Adobe Community Professional

              Hi Peter,

               

              Totally right! [ ] … if I wanted to change all "Red" text in "Blue"! …

              But it's more complex: To simplify, I've not included a header row, but here I want to change only the "even" rows.

              That's why I used 3 "for" loops [see the second one especially]! … surely the reason of the script slowness.

               

              (^/)

              • 4. Re: Change text color in tables! …
                Laubender Adobe Community Professional & MVP

                Hi Obi-wan,

                what does slow mean? How many seconds for how many tables with how many rows?

                 

                There is an faster approach, but you'll need in advance to know the maximum number of rows of all the tables of your document.

                Getting that value needs some time for calculation. That would be the "overhead" so to speak. But from then on its much faster than looping every row of every table.

                 

                On an old MacBook Pro from late 2008 with only 4 GB of RAM and InDesign CS6 with about 1200 rows in total—maximum rows of one table was: 1000—the script below took about 34 seconds to finish:

                 

                var startTime = Date.now();
                var rowsMax = 0;
                app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
                app.doScript
                    (
                    
                    colorTextOfEverySecondRow, 
                    ScriptLanguage.JAVASCRIPT, 
                    [], 
                    UndoModes.ENTIRE_SCRIPT, 
                    "Color text of every second row in document"
                    
                    );
                
                var endTime = Date.now();
                var elapsedTimeInSeconds = ((endTime - startTime)/1000);
                
                $.writeln(elapsedTimeInSeconds+"\t"+"Sec."+" with rowsMax: "+rowsMax);
                
                function colorTextOfEverySecondRow()
                {
                
                    var doc = app.documents[0];
                    var color = doc.colors.itemByName("Blue");
                
                    // Some preprocessing of the maximum number of rows:
                    var tables = doc.stories.everyItem().tables.everyItem().getElements();
                    var tablesLength = tables.length;
                
                    for(var n=0;n<tablesLength;n++)
                    {
                        var currentRowsLength = tables[n].rows.length;
                        if(currentRowsLength > rowsMax){rowsMax = currentRowsLength};
                    };
                
                    // And here a demonstration of the power of everyItem()
                    tables = doc.stories.everyItem().tables.everyItem();
                
                    for(var n=1;n<rowsMax;n=n+2)
                    {
                        tables.rows[n].cells.everyItem().texts.everyItem().fillColor = color;
                    };
                    
                    return rowsMax;
                
                };
                

                 

                Note: No header or footer rows were defined in the tables.

                 

                I tested your code with my sample.

                It took about 192 seconds to finish.

                 

                See also Marc Autret on everyItem() :

                Indiscripts :: On ‘everyItem()’ – Part 1

                Indiscripts :: On ‘everyItem()’ – Part 2

                 

                Regards,
                Uwe

                • 5. Re: Change text color in tables! …
                  Peter Kahrel Adobe Community Professional & MVP

                  Uwe,

                   

                  To speed things up with everyItem() you'd do it on the rows as well -- something like this:

                   

                  tables = doc.stories.everyItem().tables.everyItem();
                  for (i = tables.length-1; i >= 0; i--) {
                    rows = tables[i].rows.everyItem().getElements();
                    for (j = rows.length-1; j >= 0; j--) {
                        cells = rows[j].cells.everyItem().getElements();
                        for (k = cells.length-1; k >= 0; k--) {
                          // do something
                        }
                    }
                  }
                  

                   

                  P.

                  • 6. Re: Change text color in tables! …
                    Laubender Adobe Community Professional & MVP

                    Hi Peter,

                    yes, that would benefit Obi Wan's version of the script.

                     

                    In my script I'd like to access the rows by index for every table in the document directly.
                    And by index I mean the individual index of the row in context with the individual table.

                     

                    If I'd used getElements() I needed to loop every table individually.


                    And since every second row of a single table should be accessed starting with the second row of every table—we cannot know if a table has an even or an odd number of rows—I cannot loop through an array like that:

                     

                    doc.stories.everyItem().tables.everyItem().rows.everyItem().getElements();
                    

                    Instead I do it with:

                     

                    doc.stories.everyItem().tables.everyItem().rows[ n ]
                    

                     

                    Example:

                    Have a document with three tables. One with 2 rows, one wih 7 rows and one with 5 rows.

                    I want to access the seventh row of all tables, I could do it like that:

                     

                    doc.stories.everyItem().tables.everyItem().rows[6]
                    

                     

                    Regardless if there are any tables in the document with less than 7 rows.

                     

                    Regards,

                    Uwe

                    • 7. Re: Change text color in tables! …
                      Peter Kahrel Adobe Community Professional & MVP

                      Yes, ok. Anyway, the message is to use everyItem().getElements() wherever you can, especially in tables.

                       

                      P.

                      • 8. Re: Change text color in tables! …
                        BEGINNER_X Level 3

                        Hi Obi,

                         

                        May the below code also useful for you,

                         

                        myDoc = app.activeDocument,    
                        
                        myTables = myDoc.stories.everyItem().tables.everyItem().getElements();    
                           
                         
                        
                        for ( var t = 0 ; t < myTables.length; t++ )    
                        
                        {    
                                
                        var myRows = myTables[t].rows;      
                         
                                
                        for ( var r  = 1 ; r  < myRows.length; r = r +2 )    
                                
                        {    
                                       
                        var myCells = myRows[r].cells;                 
                         
                                       
                        for ( var c = 0 ; c < myCells.length; c++ )    
                                       
                        {    
                                        
                        myCells[c].texts[0].fillColor = myDoc.colors.itemByName("Blue");  
                                       
                        }    
                                
                        }  
                        
                        }  
                        
                        
                        

                         

                        Thanks in Advance

                        Siraj

                        • 9. Re: Change text color in tables! …
                          Jump_Over Level 5

                          Hi Uwe,

                           

                          Laubender napisał(-a):

                           

                          ...

                          And since every second row of a single table should be accessed starting with the second row of every table—we cannot know if a table has an even or an odd number of rows—I cannot loop through an array like that:

                          1. doc.stories.everyItem().tables.everyItem().rows.everyItem().getElements();

                          ....

                           

                          I think you can ==> checking row's index which is related to a parent (table), so

                          mDoc = app.activeDocument,
                          mRows = mDoc.stories.everyItem().tables.everyItem().rows.everyItem().getElements(),
                          cRow, mColor = mDoc.swatches.item("Blue");
                          while (cRow = mRows.pop())
                               if(cRow.index%2)
                                    cRow.cells.everyItem().texts.everyItem().fillColor = mColor;
                          

                           

                          Jarek

                          1 person found this helpful
                          • 10. Re: Change text color in tables! …
                            Laubender Adobe Community Professional & MVP

                            Hi Jarek,

                            very good.

                             

                            Just tested your idea on my sample document.
                            Surprisingly it was a bit slower than my script, but not much:

                             

                            41 vs 37 seconds

                             

                            Did more than one test with both ideas.

                            The values are on average.

                             

                            Thanks,
                            Uwe

                            • 11. Re: Change text color in tables! …
                              Peter Kahrel Adobe Community Professional & MVP

                              > while (cRow = mRows.pop())

                               

                              This is one of the most expensive ways to go through an array. Really.

                              • 12. Re: Change text color in tables! …
                                Jump_Over Level 5

                                Hi all,

                                 

                                I made some test based on my code and Uwe's timer ==>  changing loops inside function.

                                A few tables in 1 story - total 2k rows, max 1500).

                                4 tests (repeated few times to average) where loops are alike:

                                1. while(cRow = mRows.pop())     ==> time ~8,3 s

                                2. while(len--)     //  ==>    time ~8,25 s

                                3. for (var k = 0; k < len; k++)     ==> time ~43 s

                                4. for (var k = len-1; k >=0; k--)     ==> time ~8,3 s

                                It looks like - in this case - most important is backward or forward direction of changes

                                 

                                Jarek

                                • 13. Re: Change text color in tables! …
                                  Laubender Adobe Community Professional & MVP

                                  Hi Jarek,

                                  interesting…

                                   

                                  I did my sample document with several stories and used a for loop with my first tests on your idea.

                                  Don't know if you did that, but I think it's important to restart InDesign before starting a new test.

                                   

                                  Unfortunately I did not do that with my first tests.

                                   

                                  I tested again on CS6 v8.1.0 on Mac OSX 10.6.8 with 4GB RAM.
                                  So here are some new figures:

                                   

                                  1. Direct accessing the rows with my script in answer # 4:

                                  ~31.0 s

                                   

                                  2. Your index method and a for-loop forward through the rows array gathered by getElements() :

                                  ~29.3 s

                                   

                                  3. Your index method and a for-loop backward through the rows array gathered by getElements() :

                                  ~27.8 s

                                   

                                  It's not as dramatic as your figures are showing, but the main difference in my tests is that I used several stories and not just one. We should exchange test documents to get better insight.

                                   

                                  And I should repeat my tests on a machine with more RAM.

                                   

                                  Thanks,
                                  Uwe

                                  • 14. Re: Change text color in tables! …
                                    Laubender Adobe Community Professional & MVP

                                    Forgot to mension the new figure with running Obi-Wan's script after restarting InDesign:

                                    ~182.8 s

                                     

                                    Speaking of Obi-Wan:

                                    How are your speed results, Obi-Wan?

                                    Are you still following?

                                     

                                    Regards,
                                    Uwe

                                    • 15. Re: Change text color in tables! …
                                      Obi-wan Kenobi Adobe Community Professional

                                      Aha! Of course I'm here and read all your comments!

                                      Too glad to see your answers and learn such a lot!

                                      As you see, i'm able to write scripts that work sometimes but the more interesting for me is to know and understand (so learn great) how you think and write and why my script time is x 5! 

                                      i'll test all your ways this afternoon!

                                       

                                      (^/)