Skip to main content
Known Participant
December 4, 2023
Answered

Hiding Empty Objects After Data Merge

  • December 4, 2023
  • 1 reply
  • 5064 views

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. 

This topic has been closed for replies.
Correct answer m1b

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;
};

 

 

1 reply

Robert at ID-Tasker
Legend
December 5, 2023

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.

 

GiGiTexasAuthor
Known Participant
December 5, 2023

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.  

GiGiTexasAuthor
Known Participant
December 7, 2023

Not hard. What options would you want to see?


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.