Skip to main content
New Participant
January 24, 2023
Question

Data Merge + Object Styles. Possible? Or workaround with Script?

  • January 24, 2023
  • 5 replies
  • 4109 views

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?

This topic has been closed for replies.

5 replies

New Participant
January 31, 2024

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.)

M.Hasanin
Inspiring
February 3, 2024

Hi @Suburban L&G 

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.

BestMohammad Hasanin
Robert at ID-Tasker
Brainiac
February 3, 2024

@Robert at ID-Tasker 

Hi Robert, no it just short name, my full name is Mohammed Hasanin, but i write it in shorten form M.Hasanin


I know that - but please check the end of your nickname... 

 

M.Hasanin
Inspiring
January 26, 2023

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!:

BestMohammad Hasanin
New Participant
February 1, 2023

Is there a way to remove the "color-words" from the boxes after the object style has been applied?

M.Hasanin
Inspiring
February 2, 2023

@Plant Girl 

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 = "";
    }
}
BestMohammad Hasanin
Loic.Aigon
Brainiac
January 24, 2023

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

Community Expert
January 24, 2023
quote

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.
 

Mike Witherell
Community Expert
January 24, 2023

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 @971902 in the column header for the filenames.

Mike Witherell