Skip to main content
Participant
August 21, 2023
Question

Help with a script

  • August 21, 2023
  • 3 replies
  • 655 views

Hi, can you please help me? I need a script that can detect when the cells in a table have content, if they have content the font inside the cell should be changed to white bold and the colour to red (specific tint that I can add later). If the cell doesn't have any content it should be coloured green (again on a specific tint I have).

 

 

This topic has been closed for replies.

3 replies

Peter Kahrel
Community Expert
Community Expert
August 22, 2023

And another tip for you, @Eugene Tyson -- you can grab all the table's cells in one go, no need to go through the rows:

 

var doc = app.activeDocument;
var cells = doc.selection[0].cells.everyItem().getElements();

 

Note the use of everyItem().getElements(). When you iterate over "doc.selection[0].cells", you refer to a collection of the cells and recreate the collection in each iteration. When you use "doc.selection[0].everyItem().getElements()" you create an array of cells, which is a one-off.

 

You should almost always avoid processing a collection, and convert the collection into an array. In a big table the difference can be quite dramatic.

Robert at ID-Tasker
Legend
August 22, 2023

And as an additional benefit - this will return ONLY selected Cells - not the whole table.

 

Community Expert
August 21, 2023

I'm not a great scripter - but I am trying

I can get so far and just giving up now

This creates the tint swatch - but duplicates the black swatch for me - and I can't fix it

And I can't get the white text - no matter if I try white, paper or [paper]

 

var doc = app.activeDocument;

var table = doc.selection[0];


var redColor = doc.colors.add({space: ColorSpace.RGB, colorValue: [255, 0, 0]});
var greenColor = doc.colors.add({space: ColorSpace.RGB, colorValue: [0, 255, 0]});
var whiteColor = doc.swatches.item("[Paper]"); // Use the [Paper] swatch for white


var boldCharacterStyle = doc.characterStyles.item("BoldStyle");
if (!boldCharacterStyle.isValid) {
    boldCharacterStyle = doc.characterStyles.add({name: "BoldStyle"});
    boldCharacterStyle.fontStyle = "Bold"; // Set the style to Bold
}


for (var r = 0; r < table.rows.length; r++) {
    var row = table.rows[r];
    

    for (var c = 0; c < row.cells.length; c++) {
        var cell = row.cells[c];
        var cellTexts = cell.texts; // Get all Text objects in the cell
        
        if (cellTexts.length > 0) {
            var cellText = cellTexts[0].contents;
            

            if (cellText !== "") {
                cell.fillColor = redColor;
                cellTexts[0].fillColor = [paper]Color;
                

                cellTexts[0].applyCharacterStyle(boldCharacterStyle);
            } else {
                cell.fillColor = greenColor;
            }
        } else {

            cell.fillColor = greenColor;
        }
    }
}
Community Expert
August 22, 2023

Hi @Eugene Tyson,

I did not understand the duplicate issue that you mentioned. The only thing I could reproduce is that if you execute the script while the Black color is selected in the swatches panel then the color that the script creates is named Back Copy etc, is this what you are referring to? If so then it can be resolved by setting the name of the created colors explicitly

 

var redColor = doc.colors.add({space: ColorSpace.RGB, colorValue: [255, 0, 0], name:"Red"});
var greenColor = doc.colors.add({space: ColorSpace.RGB, colorValue: [0, 255, 0], name:"Green"});

 

For the While color you should use the method itemByName and the color name would be Paper. Try the following

 

var whiteColor = doc.swatches.itemByName("Paper"); // Use the [Paper] swatch for white

 

The other issue in the code is the following

 

cellTexts[0].fillColor = [paper]Color;
It should be
cellTexts[0].fillColor = whiteColor;

 

Also, do note that its a good practice to check for the existence of the color before creating it else the script would crash if you try to create the same color again. So this script would crash on color creation if you run it twice on the same document,

Let me know if this resolves all the issues.

-Manan

 

-Manan
Community Expert
August 22, 2023

Thank you for the pointers

 

I've made edits - and it might be the best written script - it seems to work

 

var doc = app.activeDocument;
var table = doc.selection[0];

// Check for "Red" swatch
var redColor = doc.colors.itemByName("Red");
if (!redColor.isValid) {
    redColor = doc.colors.add({space: ColorSpace.RGB, colorValue: [255, 0, 0], name: "Red"});
}

// Check for "Green" swatch
var greenColor = doc.colors.itemByName("Green");
if (!greenColor.isValid) {
    greenColor = doc.colors.add({space: ColorSpace.RGB, colorValue: [0, 255, 0], name: "Green"});
}

// Paper swatch exists
var whiteColor = doc.swatches.itemByName("Paper");
if (!whiteColor.isValid) {
    whiteColor = doc.swatches.add({name: "Paper"});
}

var boldCharacterStyle = doc.characterStyles.item("BoldStyle");
if (!boldCharacterStyle.isValid) {
    boldCharacterStyle = doc.characterStyles.add({name: "BoldStyle"});
    boldCharacterStyle.fontStyle = "Bold"; // Set the style to Bold
}

for (var r = 0; r < table.rows.length; r++) {
    var row = table.rows[r];

    for (var c = 0; c < row.cells.length; c++) {
        var cell = row.cells[c];
        var cellTexts = cell.texts; // Get all Text objects in the cell

        if (cellTexts.length > 0) {
            var cellText = cellTexts[0].contents;

            if (cellText !== "") {
                cell.fillColor = redColor;
                cellTexts[0].fillColor = whiteColor;

                cellTexts[0].applyCharacterStyle(boldCharacterStyle);
            } else {
                cell.fillColor = greenColor;
            }
        } else {
            cell.fillColor = greenColor;
        }
    }
}
Robert at ID-Tasker
Legend
August 21, 2023

If you work on a PC - you don't need a dedicated script, you could use free version of my ID-Tasker and with few simple Rules build a Task that will do it for you. Then you can easily modify those Rules to get a different result.

 

In fact, you would need only one Rule:

 

There are also different rules if you want to process only specific Range of Cells, Rows or Columns. 

 

Robert at ID-Tasker
Legend
August 21, 2023

Fresh of the press - and still free:

 

First Rule is to let ID-Tasker know which Table should be processed - it checks what is selected and is pretty flexible.

Of course you can select "empty" Style on the list - if Cells should't be styled / modified.