Copy link to clipboard
Copied
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).
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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;
}
}
}
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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;
}
}
}
Copy link to clipboard
Copied
Nice work.
But if I may suggest few things:
- instead of duplicating the same code - create a function that you can call that will return new color swatch - your code will look better and you can quickly use it in your other scripts,
- "Paper" color is ALWAYS present in the document, at the beginning of the collection, so you don't have to check for it - you can just refer to it by its index - I think in JS it will be "2" / third, where "0" / first is "[None]", then "[Registration]" - "1" / second.
And the correct name is "[Paper]".
Just my 2 cents.
Copy link to clipboard
Copied
Yeh I thought about that one - and thought what if they wanted another colour for the text instead of paper - so I just included it - but you're right it's probably not necessary.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
And as an additional benefit - this will return ONLY selected Cells - not the whole table.
Copy link to clipboard
Copied
Thank you very much. I was wondering if there a quicker way - seemed quite slow on my basic sample I created for myself.
Copy link to clipboard
Copied
Thank you all for your help. Eugene what should the final code look like now?
Copy link to clipboard
Copied
Code needs to work with selected cells in a table, not on the whole table as there is different info that shouldn't be modified!
Copy link to clipboard
Copied
Oh right - that might take me longer to figure out. Some good scripters here hopefully they can lend a hand.
Copy link to clipboard
Copied
As @Robert at ID-Tasker mentioned earlier, the sample code returns only the selected cells. So you'd get something like this:
var doc = app.activeDocument;
// Check swatches and styles
var cell;
var cells = doc.selection[0].cells.everyItem().getElements();
for (i = 0; i < cells.length; i++) {
cell = cells[i];
// The rest is the same
}
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more