Copy link to clipboard
Copied
Hi,
I am trying to find a way to insert a data field mapped to a record reference into a cell of an array. For example, in my cell I added manually a "<<mycolumn>>" mapped field related to a CSV with a column named "mycolumn" and it is working fine. Now I want to dynamically create an array with such references (<<mycolumn2>>, <<mycolumn3>> etc...) using a script. I can set some text directly with the "cell.contents" , not a problem, but if I insert a text like "<<mycolumn2>>" it is not working because not really mapped to the record. How can I do it ? I tried to debug but did not find. Not found also into the documentation or perhaps I do not search with the correct keyword.
Regards
Hi @Hugo290714246dr1, I was wondering how this works, and @Brito Haroldo is right on the money.
Here is a demonstration script, showing a function that inserts a DataMergeTextPlaceholder at an InsertionPoint of your choosing. I hope you can use the function, or adapt it to your needs.
I've put two example insertionPoints to try—for example 1, just put the text insertion cursor into a story somewhere, and for example 2, run it with a document containing a table.
You will have to set the fie
...Copy link to clipboard
Copied
Olá @Hugo290714246dr1, pelo que entendi você quer criar um documento, editar via script e criar o mapeamento para o CSV, correto? Não sei exatamente como gerar estes códigos mas com certeza o script precisa criar o mapeamento real para que a variável funcione na posterior etapa de importação dos dados variáveis. Simplesmente "digitar" via script algo como "<<nome>>" como texto não funciona mesmo. Estes links aqui não te ajudam com nada?
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMerge.html
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMergeField.html
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMergeImagePlaceholder.html
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMergeOption.html
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMergePreference.html
https://www.indesignjs.de/extendscriptAPI/indesign-latest/#DataMergeTextPlaceholder.html
Copy link to clipboard
Copied
Hi @Hugo290714246dr1, I was wondering how this works, and @Brito Haroldo is right on the money.
Here is a demonstration script, showing a function that inserts a DataMergeTextPlaceholder at an InsertionPoint of your choosing. I hope you can use the function, or adapt it to your needs.
I've put two example insertionPoints to try—for example 1, just put the text insertion cursor into a story somewhere, and for example 2, run it with a document containing a table.
You will have to set the field name you want. Because you want it dynamically, you will probably be generating the fieldNameOrIndex parameter elsewhere, for example:
myFieldName = "mycolumn" + i;
Or if it is easier in your case, you can use the numerical index instead of the field name—passing i to the function will insert data merge field i. Either of these approaches could sit in a loop.
- Mark
/**
* Demonstrates a function for adding a DataMergeTextPlaceholder.
* @author m1b
* @discussion https://community.adobe.com/t5/indesign-discussions/api-to-insert-a-reference-to-merge-data-field-into-a-cell/m-p/14273192
*/
function main() {
var doc = app.activeDocument;
// NOTE: the field name must match a data merge field in the document.
var myFieldName = 'mycolumn';
// example 1: the active insertion point:
var ip = doc.selection[0];
// example 2: an insertion point in the 3rd cell of the first table of the document:
// var ip = doc.stories.everyItem().tables.everyItem().getElements()[0].cells[2].insertionPoints[0];
var placeholder = insertDataMergeTextPlaceholder(doc, ip, myFieldName);
};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Add Data Merge Text Placeholder');
/**
* Inserts a DataMergeTextPlaceholder
* at the specified InsertionPoint.
* @author m1b
* @version 2023-12-03
* @param {Document} doc - an Indesign Document.
* @param {InsertionPoint} insertionPoint - the target InsertionPoint.
* @param {String|Number} fieldNameOrIndex - the name, or index, of a valid DataMergeField.
* @returns {DataMergeTextPlaceholder}
*/
function insertDataMergeTextPlaceholder(doc, insertionPoint, fieldNameOrIndex) {
if (
doc == undefined
|| doc.constructor.name !== 'Document'
)
throw Error('insertDataMergeTextField: bad `doc` supplied.');
if (
insertionPoint == undefined
|| insertionPoint.constructor.name !== 'InsertionPoint'
|| !insertionPoint.isValid
)
throw Error('insertDataMergeTextField: bad `insertionPoint` supplied.');
// datamerge objects
var dm = doc.dataMergeProperties,
dmFields = dm.dataMergeFields,
index = Number(fieldNameOrIndex);
if (fieldNameOrIndex.constructor.name == 'String') {
// get the index to the named field
for (index = 0, len = dmFields.length; index < len; index++)
if (dmFields[index].fieldName == fieldNameOrIndex)
break;
}
var field = dmFields[index];
if (!field.isValid)
throw Error('Did not find a valid data merge field "' + fieldNameOrIndex + '".');
// add the placeholder at the insertionPoint
var placeholder = doc.dataMergeTextPlaceholders.add(insertionPoint.parentStory, insertionPoint, field);
// refresh
insertionPoint.parentStory.recompose();
if (placeholder.isValid)
return placeholder;
};
Copy link to clipboard
Copied
Or create a webscraping script, save data into tab separated txt file and just update the data source?
Copy link to clipboard
Copied
@DTPtutorialyCZ-L.Zalesky could you please elaborate on this method? I'm not sure it addresses the OPs question, but maybe I don't understand it right.
- Mark
Copy link to clipboard
Copied
true, my mistake. I am using this with snippets (idms). Where the placeholder is already defined and InDesign take this fileld as Placeholder.
Copy link to clipboard
Copied
Interesting approach. Thanks.
Copy link to clipboard
Copied
Thanks a lot. I have finally found the way by reading another thread and it is exactly what you describe here. I have created my functions but it is the same.
//Get all document merge fields
function getFields (doc ) {
return doc.dataMergeProperties.dataMergeFields.everyItem().getElements();
}
//Get a merge field by its name
function getFieldByName(doc,fieldName) {
var allFields=getFields (doc);
for (var i = 0; i < allFields.length; i++){
if(allFields[i].fieldName==fieldName)
return allFields[i];
}
}
function addMergeFieldIntoCell(doc,cell, fieldName) {
var field=getFieldByName (doc, fieldName);
var ip=cell.insertionPoints[0];
doc.dataMergeTextPlaceholders.add( ip.parentStory, ip, field);
}
The rest of the program just consists of browsing the table cells and then applying the template built dynamically to all records from CSV. CSV columns have been prepared with a name including row/column to match each cells.