Skip to main content
Known Participant
November 20, 2020
Question

Remove data merge placeholders with missing data

  • November 20, 2020
  • 1 reply
  • 1629 views

I have a data merge setup which uses csv data in like this:
text1,@image1,text2,@image2,text3,@image3

 

The data is output from a server which can set the number of "sub columns", so that an output also can look like this:
text1,@image1,text2,@image2

 

In reality there are more than one image and text field, this is just as an example. Sometimes I only want to use two "sub colums" per page and leave the other columns become empty. But when I input a csv like that into indesign I get an error that there is missing data for some placeholders. I could of course let the server output a csv with empty fields but that would complicate things a lot since I sometimes need data without the empty fields. Is there a way in Indesign to quickly select and delete all data merge fields that have missing data? If it is possible via scripting that would be awesome!

This topic has been closed for replies.

1 reply

brian_p_dts
Community Expert
Community Expert
November 20, 2020

Plain ol Data Merge has its limitations, as you have discovered. You might want to look into InData: http://emsoftware.com/products/emdata/

 

The alternative would be to put some kind of filler code into the blank fields that you can then remove via Find/Replace or simple script. 

 

 

Known Participant
December 14, 2020

If anyone is interested, I finally found a kindof hacky way to achieve this. If you got suggestions on how to improve, I am all ears. The principle is looping through all placeholders, comparing them to the contents of the csv and remove the pageItems that contains unused datamerge placeholders.

function removeUnusedDMPlaceholders() {
	var currentPath = app.activeDocument.filePath;
	var csvFile = new File(currentPath+"/"+CSV_FILE);
	csvFile.open('r');
    csvHeader = csvFile.read().split("\n")[0];
    tagsInCSV = csvHeader.split(",");
    itemsToRemove = [];
    storiesInDoc = [];
    
    for(var i=0;i<tagsInCSV.length;i++) {
    	tagsInCSV[i] = tagsInCSV[i].replace('#','').replace('@','');
    }
    
    var dataMergeTextPlaceholders = app.activeDocument.dataMergeTextPlaceholders;
    var dataMergeImagePlaceholders = app.activeDocument.dataMergeImagePlaceholders;
    var dataMergeQrcodePlaceholders = app.activeDocument.dataMergeQrcodePlaceholders;

	for(var i=0; i<dataMergeTextPlaceholders.length; i++) {		
		if(typeof dataMergeTextPlaceholders[i] != 'undefined') {
			if(dataMergeTextPlaceholders[i].isValid) {
				if(typeof dataMergeTextPlaceholders[i].field != 'undefined') {
					try {
						tagsInDoc.push(dataMergeTextPlaceholders[i].field.fieldName);
					} catch(error) {
					}
				}
			}
		}
	}
	for(var i=0; i<dataMergeImagePlaceholders.length; i++) {
		if(typeof dataMergeImagePlaceholders[i] != 'undefined') {
			if(dataMergeImagePlaceholders[i].isValid) {
				if(typeof dataMergeImagePlaceholders[i].field != 'undefined') {
					try {
						if(!contains(tagsInCSV,dataMergeImagePlaceholders[i].field.fieldName)) {
							itemsToRemove.push(dataMergeImagePlaceholders[i].placeholderPageItem);
						}
					} catch(error) {
					}
				}
			}
		}
	}
	for(var i=0; i<dataMergeQrcodePlaceholders.length; i++) {
		if(typeof dataMergeQrcodePlaceholders[i] != 'undefined') {
			if(dataMergeQrcodePlaceholders[i].isValid) {
				if(typeof dataMergeQrcodePlaceholders[i].field != 'undefined') {
					try {
						if(!contains(tagsInCSV,dataMergeQrcodePlaceholders[i].field.fieldName)) {
							itemsToRemove.push(dataMergeQrcodePlaceholders[i].placeholderPageItem);
						}
					} catch(error) {
					}
				}
			}
		}
	}

	var pages = app.activeDocument.pages;

	for(var i=0; i<pages.length; i++) {
		var textFrames = pages[i].textFrames;
		for(var j=0; j<textFrames.length; j++) {
			var textContents = textFrames[j].texts[0].contents;
			var result = textContents.match(/\<\<(.*?)>>/g);
			if(result != null) {
				result = result[0].replace("<<","").replace(">>","");
				if(!contains(tagsInCSV,result)) {
					try {
						textFrames[j].remove();
					} catch(error) {
					}
				}

			}
		}
		var pageItems = itemsToRemove;
		for(var j=0; j<pageItems.length; j++) {
			if(typeof pageItems[j] != 'undefined' && pageItems[j].isValid) {
				try {
					pageItems[j].remove();
				} catch(error) {
				}
			}
		}
	}
}

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}
Participating Frequently
October 2, 2023

Per, I have the same issue and I was wondering how you implemented the above code in indesign?