Copy link to clipboard
Copied
Looking for opinions on the best way to do this and possibly a tutorial or some guidance. Im running a data merge and there are options that are a little conditional. Right now I run the merge and manually hide the empties. Is there a way I could automate this?
I have another merge comng up and I would like to learn (I love to learn) and make the process a bit faster. Maybe run a script that hides and the deletes the hidden objects? I have attached screenshots that are similar. I dont mind reading or watching a tutorial as long as it is fairly similar in nature. I have files if that would help. I fund a post that was similar but even after reading it I was a little lost.
Thanks in advance.
Hi @GiGiTexas,
If you're willing to use a scripting approach, I've put together a demo—using your sample files—that does what (I think) you are asking. Feel free to modify to suit your needs. I wasn't sure if you were merging multiple records per page, etc.
It works by first labelling (see Indesign's ScriptLabel Panel) the placeholder text frames, then does the merge, then checks the merge document(s) and removes the containing groups of any empty text frames that match the label.
Let me k
...Copy link to clipboard
Copied
If those are a "real" examples - then you rather need custom tool that will load your "boxes" as InLine objects - don't think you can do it with a "vanilla" DataMerge - then, when those empty ones are deleted - which would be extremey simple to script - there rest will flow automatically.
Copy link to clipboard
Copied
I have attached a file here. There is more to the project but this is an section of it. I run the data merge fine and everything is where is should be. I then have to go in and turn off the groups that are empty.
I was hoping I could find a way to at a minimum automate the hiding empty groups. I was thinking maybe placeholder text "empty" or some vaugue charater that could be found and script would then hide the group. Its a bit beyond my skills hence asking and wanting to learn. Am I at least on the right track? Would a script be able to do this? Is that what I should should start diving into? Sure it couldnt hurt.
Copy link to clipboard
Copied
Hi @GiGiTexas,
If you're willing to use a scripting approach, I've put together a demo—using your sample files—that does what (I think) you are asking. Feel free to modify to suit your needs. I wasn't sure if you were merging multiple records per page, etc.
It works by first labelling (see Indesign's ScriptLabel Panel) the placeholder text frames, then does the merge, then checks the merge document(s) and removes the containing groups of any empty text frames that match the label.
Let me know if you end up using it. I've just written it now, so hasn't been tested much and might have bugs.
- Mark
/**
* Demonstration of one approach to "Cleaning up" after
* a datamerge by searches for empty placeholder stories.
* When customizing this script, look at:
* (a) `labelPlaceholder` function which labels the empty
* placeholder's textFrame, and
* (b) `processEmptyPlaceholder` function which targets that
* textFrame's containing group.
* @author m1b
* @discussion https://community.adobe.com/t5/indesign-discussions/hiding-empty-objects-after-data-merge/td-p/14277290
*/
// this identifies an empty text placeholder story
const IS_EMPTY_PLACE = /^[\s\uFEFF]*$/;
// labels are a convenient way to mark objects
var LABEL = 'checkMe';
/**
* Adds a label to the placeholder's textFrame.
* @note Adjust this function to suit your document.
* @param {DataMergeTextPlaceholder} placeholder - the placeholder to mark.
*/
var labelPlaceholder = function (placeholder) {
placeholder.storyOffset.parentTextFrames[0].label = LABEL;
};
/**
* Removes an empty placeholder's parent group.
* @note Adjust this function to suit your document.
* @param {Story} story - the empty placeholder Story.
*/
var processEmptyPlaceholder = function (story) {
if (story.textContainers[0].label === LABEL) {
story.textContainers[0].parent.remove();
// story.textContainers[0].parent.visible = false;
}
};
// adjust these to suit your data merge
var dataMergeOptions = {
createNewDocument: true,
};
// adjust these to suit your data merge
var dataMergePreferences = {
recordSelection: RecordSelection.RANGE,
recordsPerPage: RecordsPerPage.SINGLE_RECORD,
};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Remove Empty Placeholders');
function main() {
var doc = app.activeDocument,
startDocs = app.documents.everyItem().getElements(),
placeholders = doc.dataMergeTextPlaceholders,
dm = doc.dataMergeProperties;
if (placeholders.length === 0)
return alert('There are no datamerge placeholders in this document.');
// label all the datamerge text placeholders
// so we can process them after the merge
for (var i = placeholders.length - 1; i >= 0; i--)
if (placeholders[i].storyOffset.parentTextFrames.length > 0)
labelPlaceholder(placeholders[i]);
var range = prompt('Enter record range:', '1-3');
if (range == null)
return;
dataMergePreferences.recordRange = range;
// apply settings
doc.dataMergeOptions.properties = dataMergeOptions;
dm.dataMergePreferences.properties = dataMergePreferences;
// do the merge
dm.mergeRecords();
// get the merge document(s)
var docs = allExceptThese(app.documents.everyItem().getElements(), startDocs);
// process each new merged document
for (var d = 0; d < docs.length; d++) {
var newDoc = docs[d],
stories = newDoc.stories;
for (var i = stories.length - 1; i >= 0; i--)
if (IS_EMPTY_PLACE.test(stories[i].contents))
processEmptyPlaceholder(stories[i]);
}
};
/**
* Returns array of things excluding some things
* @param {Array<*>} all - array of things.
* @param {Array<*>} exceptThese - array of things to exclude.
* @returns {Array<*>}
*/
function allExceptThese(all, exceptThese) {
var things = [];
for (var i = 0, len = all.length; i < len; i++)
if (indexOf(all[i], exceptThese) === -1)
things.push(all[i]);
return things;
};
/**
* Returns index of obj in arr.
* Returns -1 if not found.
* @param {any} obj
* @param {Array} arr
* @returns {Number}
*/
function indexOf(obj, arr) {
for (var i = 0; i < arr.length; i++)
if (arr[i] === obj)
return i;
return -1;
};
Copy link to clipboard
Copied
Wow, I appreciate you going the extra mile to help! I wasnt sure what approch to take or learn about - thats kind of what I was trying to determine.
Now I need to see if I can pick it apart and understand what it is doing. On a quick read I am thinking I need to learn how to label the text frame so the script knows what to look for. So off to google. 🙂
Thank you again. Have a wonderful day!
Copy link to clipboard
Copied
Happy to help. By the way, the script starts by labelling every data merge text placeholder. So you don't need to do it manually. Maybe just run it as is, using your sample file first and see if it is doing what you expect.
- Mark
Copy link to clipboard
Copied
Wow, wow. Thank you! I changed it to SINGLE_RECORD and worked like a charm. Thank you very much, will have me a tons of time.
Copy link to clipboard
Copied
Any way to get a prompt for which records to choose? Or would I have to edit the script each time with a modification to the ALL.RECORDS line.
Copy link to clipboard
Copied
Not hard. What options would you want to see?
Copy link to clipboard
Copied
Simple solution: The Record Selection (ie. Run your script; Prompt: Record Selection; I choose 5-9) rince and repeat.
What I am doing: I have several different InDesign files that contain 3 page spec sheets (different layouts) I currently:
1. Run the data merge for a specfic model line (ie. Reords 5-9)
2. Go into each 3 pages for each record and hide the empties
3. Run a find and replace, as I can't get the data merge to import a specific Glyph they use, Unicode E514 a superscript registration mark that is in their data all over the place that gets stripped out (I have googled, it's on my "need a solution" list but for the time being that is not a huge time killer)
4. Fix any overset text.
5. Export the pages as seperate PDFs based on a merged field "FileName"
Your script does #2 but if I could figure out a way for it to do #1 either by me selecting the records and doing a manual rince and repeat running the script or figuring out how to tell the script to do that based on some import variable and then save individual files - it would be a big time saver.
I could then do #3 and I found a script for #4.
Copy link to clipboard
Copied
I've added a prompt to the script above. It asks for a range string where you can enter, for example, '5-9'.
- Mark
Copy link to clipboard
Copied
Just what I needed thank you!!!
Copy link to clipboard
Copied
Is this a real template? Or "out of context" mockup?
Copy link to clipboard
Copied
It's a mockup of a section of a real template, real job.
I'd be open to other approches or solutions if you want to point me in that direction. I am trying to learn to automate some things I encounter to broden my knowledge. I have been doing data merges for over 25 years on various software (started in direct mail in the 90s) but never learned how automate some of the shortcomings of InDesign and I am trying to expand my understanding of a few other features.
Copy link to clipboard
Copied
Right now, you need to make sure, that you don't have data in the same columns for Blue and Red.
Also, looks like you need to have Orange "alone" in the 1st row, right?
If your rectangles would have been placed as InLine Graphics - in the TextFrame - they could reflow after empty ones are removed.
And you could have "duplicates" of Red and Blue - where they right now overlap.
Copy link to clipboard
Copied
The way it was setup may not be the best way. I have a few different ideas of how I could have done it better given more time and after thought (hind sight is always 20/20) But even with the convoluted way I did it, it saved a ton of time.
Its one of those jobs that I wish after it was done, or before it started, I could discuss with someone who knows more than me, "how would you approach this". So I am kind of doing that here, as a learning experience, before I may ever have to do something similar.
Project pain points...
1) Datasheet needs 3 different UOM: Imperial, Metric, Both.
2) Each product has different data and different colors. The first orange row may have anywhere from 1-7 squares on a product and the second row has Blue, Red, and Green anywhere from 0-5 of any given color.
The way I approched it...
1) I created a 3 page template, one for each UOM.
2) created the above sample, each position (ie Blue Spot 1) has a bolumn in my datasheet. Then I went in and hid the blanks.
It worked, but here I am to learn more....
I get fustrated when I do these jobs as the data merge function seems so limited, and not much has changed in all the years I have used it.
Copy link to clipboard
Copied
Is it a catalogue-style document or separate leaflets?
Those square boxes - do you need them as a separate rows with specified colors - or one-after-another, no matter how many rows?
Copy link to clipboard
Copied
This was a 1 page sheet. Each record needed a one page sheet in 1) Imperial 2) Metric 3) Both
(In my pea brain why not use the both, but I am not the client) lol
The boxes...
File Setup:
Header (Constant)
Orange Row
Header 2 (Variable and Empty if nothing below)
Mix of Blue, Red, Green
Orange was one row, all alone, always orange anywhere from 1-7 boxes. (ie. A model might have 2, another 7)
Row two was a mix of blue, red, green depending on model. (ie. one model might have 3 blue, 1 red; one might be all blue; one might be just green.....)
Find more inspiration, events, and resources on the new Adobe Community
Explore Now