Copy link to clipboard
Copied
Greetings,
How can I update a single text variable that need to have the same value in multiple INDD files? I'm essnetially trying to do a text replace of a single text variable in a few dozen files. I only could find that syncing files in a book will completley replace ALL text variables with the values found in my Sync File, if I include text variables to be synced, but I really only want to adjust one text variable, and have that value update in all the other files, without effecting other text variables that ARE supposed to have different values.
Thanks for help on this 🙂
Copy link to clipboard
Copied
As far as I know, text variables are per the document. But what might happen if you copy a bit of textframe containing the updated text variable into the other document(s)? Will it update the text variable? (Just guessing with you.)
Copy link to clipboard
Copied
Hi Mike, if the text variable already exists in a document, pasting the text from an updated document will not have any effect on the actual text variable value I'm trying to upddate. But if I paste the text variable from one document to another document that does NOT have that text variable already, in that case, it will create the text variable and use the value from the document I copied it from.
Copy link to clipboard
Copied
Hi @TestriteVisual:
Did you try Type > Text Variables > Define > Load? You can check the variables you want to import into a file (and uncheck the ones you don't want).
~Barb
Copy link to clipboard
Copied
Barb, does that read defined variables in the target INDD, as with styles etc.?
That's useful. I've used the Book method for a few clunky projects and this would be an improvement.
Copy link to clipboard
Copied
Yes. It is just like loading styles from one document to another. You can pick and choose which ones you want to import.
~Barb
Copy link to clipboard
Copied
Hi Barb, never noticed this but this Load option sounds good for a updating a couple of files, but is there any way to batch update dozens of files to have the updated value of a single text variable? Thanks again.
Copy link to clipboard
Copied
Hi @TestriteVisual:
The only bulk-synchronization option is across files in a book, and that isn't going to work for you because it changes all variable definitions, where the Load option just changes the ones you select. Custom scripts solve all sorts of beyond-the-feature-set limitations, but that isn't my area. If you do this all the time, it may be worth the investment to write it or to hire someone to write it for you or to search for an existing third-party solution.
~Barb
Copy link to clipboard
Copied
Ok thank you for the insight.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
What about a GREP-based solution completely outside of ID? An applet or system script that could take a folder of files, open each in low-level form, and S/R or GREP the variable data? This would almost certainly be faster than an ID script, at least for more than perhaps 20 docs at a time.
Copy link to clipboard
Copied
Hi @TestriteVisual , It should be easy to script. Do you need to change custom variable Type and/or its Options? Could you share a sample file and indicate the changes you need to make?
Copy link to clipboard
Copied
Hi @TestriteVisual, I've written a script to change custom text variables values across open documents. See what you think. It can be modified if not quite what you had in mind.
- Mark
P.S. @rob day sorry I didn't see you were looking at this, too!
/**
* Update Text Variable In Open Documents
* @author m1b
* @version 2023-02-09
* @discussion https://community.adobe.com/t5/indesign-discussions/how-to-update-a-single-text-variable-with-same-value-in-multiple-indd-files/m-p/13564851
*/
function main() {
var showUI = true,
docs = app.documents;
if (docs.length == 0) {
alert('Please open document(s) with text variables and try again.');
return;
}
// get list of custom text variables
var tvs = [],
allTextVariables = docs.everyItem().textVariables.everyItem().getElements(),
tvNames = [],
uniqueNames = {};
for (var i = 0; i < allTextVariables.length; i++) {
if (
allTextVariables[i].variableType == VariableTypes.CUSTOM_TEXT_TYPE
&& uniqueNames[allTextVariables[i].name] != true
) {
tvs.push(allTextVariables[i]);
tvNames.push(allTextVariables[i].name);
uniqueNames[allTextVariables[i].name] = true;
}
}
if (tvs.length == 0) {
alert('No custom text variables found in open documents.');
return;
}
if (showUI)
dialogWithMenuAndValue({
menuItems: tvNames,
windowTitle: '',
menuLabel: 'Update Text Variable',
selectedIndex: 0,
menuChangeFunction: function (index, p, w) { p.selectedIndex = index; w.valueField.text = tvs[index].variableOptions.contents },
actionFunction: function (p) { updateTextVariables(allTextVariables, tvNames[p.selectedIndex], p.value) }
});
else
// if not using UI, then hand code the parameters here:
updateTextVariables(allTextVariables, 'My Text Variable', 'My new value here');
};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Update Text Variable');
/**
* Updates any text variables in `textVariables`
* parameter with name matching `targetName`.
* @author m1b
* @version 2023-02-09
* @param {Array<TextVariable>} textVariables - the text variables to search in.
* @param {String} targetName - the name to match.
* @param {String} newValue - the new value to apply.
* @param {Boolean} showResults - whether to show results alert (default: true).
*/
function updateTextVariables(textVariables, targetName, newValue, showResults) {
var counter = 0,
instanceCounter = 0;
for (var i = 0; i < textVariables.length; i++)
if (textVariables[i].name == targetName) {
textVariables[i].variableOptions.contents = newValue;
counter++;
instanceCounter += textVariables[i].associatedInstances.length;
}
if (showResults !== false)
alert('Updated "' + targetName + '"\n' + instanceCounter + ' instances in ' + counter + ' documents.');
};
/**
* Show UI with menu and value.
* It is expected that `menuChangeFunction`
* will update the `p` object and the
* `actionFunction` can use values from `p`.
* @param {Object} p
* @param {String} p.windowTitle - title of the window.
* @param {Array<String>} p.menuItems - array of strings to populate dropdown menu.
* @param {String} p.menuLabel - label for the dropdown menu.
* @param {Function} p.menuChangeFunction - a function executed when the dropdown menu is changed.
* @param {Function} p.actionFunction - a function executed when OK button is clicked.
* @param {Number} [p.selectedIndex] - the selection index of the dropdown menu (Default: 0).
*/
function dialogWithMenuAndValue(p) {
var dialog = makeUI(p)
dialog.center();
var result = dialog.show();
dialog = null;
if (result == 1) {
p.actionFunction(p);
}
function makeUI(p) {
var windowTitle = p.windowTitle || '',
menuItems = p.menuItems || [],
menuLabel = p.menuLabel || 'Choose:',
menuChangeFunction = p.menuChangeFunction || function (index) { alert('Menu item ' + index) },
w = new Window("dialog", windowTitle),
row = w.add("Group {orientation:'row', alignment:['fill','top']}"),
mainMenu = row.add("Dropdownlist {alignment:['left','center']}"),
valueGroup = row.add("Group {orientation:'row', alignment:['fill','top']}"),
valueField = valueGroup.add("edittext", undefined, ''),
buttonRow = w.add("Group {orientation:'row', alignment:['fill','top'], alignChildren:['right','top'] }"),
cancelButton = buttonRow.add("button", undefined, "Cancel", { name: "cancel", alignment: ['right', 'center'] }),
okButton = buttonRow.add("button", undefined, "Update", { name: "ok", alignment: ['right', 'center'] });
okButton.onClick = function () { p.value = valueField.text; w.close(1) };
w.valueField = valueField;
valueField.minimumSize.width = 300;
mainMenu.preferredSize.width = 250;
mainMenu.title = menuLabel;
for (var i = 0; i < menuItems.length; i++)
mainMenu.add('item', menuItems[i]);
mainMenu.onChange = menuOnChange;
var menuChangeFunction = p.menuChangeFunction || setMenuIndex;
mainMenu.selection = p.selectedIndex || 0;
return w;
function menuOnChange() {
var s = mainMenu.selection ? mainMenu.selection.index : 0;
menuChangeFunction(s, p, w);
}
function setMenuIndex(index, p, w) {
p.selectedIndex = index;
}
}
};
Find more inspiration, events, and resources on the new Adobe Community
Explore Now