Data Merge + Object Styles. Possible? Or workaround with Script?
Copy link to clipboard
Copied
PART ONE: Data Merge capabilities
I have a couple thousand records in a spreadsheet I'm using to create signs. Name, description, picture, fine print, etc. One of the identifiers on each sign is a colored border to visually indicate which one of five categories the sign belongs in. There are two identical signs on each page.
Is it possible to specify a value in the Data Merge source file that would set the value of a specific object's border, whether specifiying in the spreadsheet "green", "C=75 M=0 Y=100 K=10", or some other HSB/HEX/LAB color?
My guess is no, since Data Merge is basically to pull info IN, not to set values within a doc. I realize I could create an image for each of the border colors and specify the path in the Data Merge, but I'd really rather avoid that route. It makes the spreadsheet pretty clunky. Which leads me to...
PART TWO: Solving by script
If the border color can't be set during the Data Merge, my next thought was to create a script. I could include an invisible/non-printing text box to hold an imported a string value when the data merge happens (Green, Red, Orange, etc.) Write a script that would read the value on each page and set the two border objects on that page to the corresponding already-defined object style. Step and repeat for all the pages in the generated document.
I've checked out several similar threads (Here and here from 2018, and this one from 2021) which leads me to believe it's possible. Unfortunately I'm not much of a code-person. While I've downloaded VS Code, I'm struggling to piece something together because... well, I'm not a coding savant.
Anyone care to help?
Copy link to clipboard
Copied
Datamerge can pull text data from a simple spreadsheet and it can also pull images from the images column of a spreadsheet. That being the case, you could make an artfile for just the background border (like an .AI file) and the datamerge would put in the right color for the background border.
https://helpx.adobe.com/indesign/using/data-merge.html#about_data_source_files
There is a subsection about how to put an @SIGN in the column header for the filenames.
Copy link to clipboard
Copied
I realize I could create an image for each of the border colors and specify the path in the Data Merge, but I'd really rather avoid that route. It makes the spreadsheet pretty clunky.
You can avoid having to put full paths in the spreadsheet if you put the images in the same folder as the data file. In that case, the field only needs to contain the name of the image file.
Copy link to clipboard
Copied
Did you know about Colecandoo website. The guy deeply twisted datamerge's arm and shows how to achieve what seems often non accessible with datamerge: https://colecandoo.com/2011/10/16/power-merging-adding-bar-graphs-and-changing-formats-in-data-merge...
Maybe you can find some hint there.
Loic
Copy link to clipboard
Copied
Hi @Plant Girl
i think this script will do the trick :
//Apply Object Style to TextFrame Based on Content
app.doScript(ApplyOSTextFrames, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Apply Object Style Based on Content");
function ApplyOSTextFrames(){
var myDoc = app.documents[0];
var myFrames = myDoc.textFrames.everyItem().getElements();
for (var n = 0; n < myFrames.length; n++) {
myFrames[n].applyObjectStyle(myDoc.objectStyles.item(myFrames[n].contents));
}
}
just make sure that object style names the same of text frame contents :
Object Style Palette
See in Action!:
Mohammad Hasanin
Copy link to clipboard
Copied
Is there a way to remove the "color-words" from the boxes after the object style has been applied?
Copy link to clipboard
Copied
Yes, just modify the code as following :
//Apply Object Style to TextFrame Based on Content
app.doScript(ApplyOSTextFrames, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Apply Object Style Based on Content");
function ApplyOSTextFrames(){
var myDoc = app.documents[0];
var myFrames = myDoc.textFrames.everyItem().getElements();
for (var n = 0; n < myFrames.length; n++) {
myFrames[n].applyObjectStyle(myDoc.objectStyles.item(myFrames[n].contents));
//Empty Text Frames
myFrames[n].contents = "";
}
}
Mohammad Hasanin
Copy link to clipboard
Copied
Hi, first of all, thank you for your script. I understand it, but I'm being not able to use it.
Whenever I run it, it returns an error: unvalid value for parameter 'using' of method 'applyObjectStyle', expected ObjectStyle, but received nothing. It is as if there weren't any object styles created 😞
Copy link to clipboard
Copied
Are you sure the ObjectStyle you want to apply - exists in your document?
Those scripts expect ObjectStyles to already exist in your document - they do not create them beforehand.
Copy link to clipboard
Copied
Hi! Yes, I created a few beforehand to test the script.
Thank you for your response.
Copy link to clipboard
Copied
I wasn't able to get the script @M.Hasanin (so very kindly!) provided when I originally posted. Due to a time crunch, I solved last year by clunkily using an image file/path. But this is a task I have to revisit every year. Here are some additional images to how I've set up the document based on the feedback I've received from this thread. As you can see, I have multiple text boxes and I only want one of them to have the frame style applied.
I imagine I need to somehow "name" the text/graphic box I'm trying to apply the border to. I know I can do that with Interactive > Buttons & Forms, then setting my desired text/graphic box to Type: text field so I can set Name:[my name]... but I'm not sure if DataMerge will interact with Buttons & Forms.
Suggestions appreciated. (And holy cow! @Loic.Aigon wasn't kidding about what amazing things Colin Flashman has done. If you're picking up this thread long after it's gone silent, def see if https://colecandoo.com/ is still around and maybe it'll give you ideas/hope too.)
Copy link to clipboard
Copied
But it looks like this object is part of your template - can't you just apply ObjectStyle from the start?
And if you want to "name" object for futere use in scripts - you should use "label" - Windows > Utilities > Scripting Label.
Copy link to clipboard
Copied
In my Excel file (::CSV) I have thousands of entries, each with one of five color designations. Because they're different, I'm trying to apply the appropriate object style (frame color) during the data merge. In all, I have tens of thousands of line items which have already been split across six Excel files. Splitting them further would complicate the workflow.
Copy link to clipboard
Copied
So now we know a little bit more - about your situation.
If you work on a PC - I can give you temporary access to the full version of my tool - it would be piece of cake to restyle what you want in any way you want...
You can do a lot even with a free version - but it would require a bit more clicking... Still much faster than without my tool...
If you are on a Mac - you'll have to find someone who will create custom script for you - and then hope he/she will have time to update it...
Or you could go through much more hardcore way - export as IDML and edit there...
Small example of what you can do with my tool:
1st Task - Load Files (result is already visible at the bottom) - loads all INDD files from a selected folder, pre-select them and sort.
2nd Task - Batch-ReLink-PDF-Export - automatically executed on all selected files from the bottom list - will update links, export PDF with selected profile, close and save document - and will do it on 1000+ files as requested by my friend.
Of course, as those are Tasks - user can add more options by himself - 1st Task can add files from multiple different folders, unselect files that should be ignored, etc. - 2nd Task can do some extra stuff - export by Layers or JPEG or whatever.
I'm only required in case of adding some new functionality. Otherwise - it's like playing with LEGO.
Copy link to clipboard
Copied
as i understand from you, you cant apply the previos script to your project, actually, to apply correctly the object styles , the old script assume that the exact content are inside the text frame and also object style name is exactly as content so if the textframe content is "RED" , also object style name must be "RED" but in the following new version of the script you can Apply the Object Style from the array if the script found any (Index of) content in the same array, this will much easier if the text frame loaded with many text :
//Apply Object Style to TextFrame Based on Content v2.0
//Created By M.Hasanin
app.doScript(ApplyOSTextFrames, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Apply Object Style Based on Content");
function ApplyOSTextFrames() {
var myDoc = app.documents[0];
var myFrames = myDoc.textFrames.everyItem().getElements();
for (var n = 0; n < myFrames.length; n++) {
var frameContent = myFrames[n].contents.toLowerCase(); // Convert the content to lowercase for case-insensitive matching
// Define the color keywords and their corresponding object style names
var colorStyles = {
"red": "RED",
"blue": "Blue",
"green": "GREEN"
// Add more color keywords and object style names as needed
};
// Iterate through the color keywords and check if the frame content contains any of them
for (var colorKeyword in colorStyles) {
if (frameContent.indexOf(colorKeyword) !== -1) {
var objectStyleName = colorStyles[colorKeyword];
// Check if the object style exists in the document
if (myDoc.objectStyles.itemByName(objectStyleName).isValid) {
myFrames[n].applyObjectStyle(myDoc.objectStyles.itemByName(objectStyleName));
}
}
}
}
}
so you have to add any keywords that are might to be contained in the text frames like (red, blue, green) as example then you can deterimine the Object Style Name, so as example if the text frame contains the statement "in the red" it will apply RED object style to the textframe and so on, so i think this version might solve your problem.
Mohammad Hasanin
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi Robert, no it just short name, my full name is Mohammed Hasanin, but i write it in shorten form M.Hasanin
Mohammad Hasanin
Copy link to clipboard
Copied
I know that - but please check the end of your nickname...
Copy link to clipboard
Copied
@Robert at ID-Tasker
Thanks a lot, i fix it now
Mohammad Hasanin

