Skip to main content
Inspiring
January 8, 2019
Answered

Find change by queries replacement

  • January 8, 2019
  • 1 reply
  • 1785 views

I've been using the Find change by queries script for 'ages' to clean up all the word docs I have to import. It deletes double spaces, double hard returns, replaces soft returns with hard ones, etc. etc. etc. and all with ONE CLICK. I think it's a script I downloaded from the net at some time, not the basic one that comes with ID. I have 23 queries and it works like a charm.

However... it finds and changes everything in my entire document.... I think (?) I should have set the find option to Story only when I created the queries...? Anyway, I was thinking about creating new queries that ONLY finds and changes things in the selected text frame but while the script itself does its job when I press Run queries the Create queries option does nothing... I am using ID 2018 here btw.

So... what would be the best alternative for this? I read about a multi find/changer but 1. it costs money (not a real big problem) but 2. it also requires another program to install the script, which I don't like... What is my best option to replace all those common errors in Word docs with one click and in one text frame only?

This topic has been closed for replies.
Correct answer Manan Joshi

Yes! That worked like a charm! Thanks for the clever tip! This is exactly what I needed and this saves me a lot of valuable time.

One request though if you may have time for it: is there a way to make the 'Run on Selection' option ticked ON by default? It is quite important for me that this script ONLY runs on the selected frame and as it is now I have to tick that option otherwise things go terribly wrong.

In fact, it would be even better if the script wouldn't run at all if no frame was selected: as it is now it may run and screw up my document by accident if I forget to select a frame... But anyway, your edited script works like a charm already so I am happy with how it is too!


Try the following code, it does the following

  1. The "Run on selection" is selected by default
  2. The script runs query only when there is a textframe selected, even i case when the option of "Run on selection" is unchecked. I know i should have put in more checks to avoid this in case the selection checkbox is unchecked, but i am lazy

Try it and let me know if there are still issues that may land you in trouble.

#targetengine "session" 

CreatePalette(); 

 

 

function CreatePalette() { 

var myDialog = new Window('palette', 'Search-Replace by Queries'); 

if (app.extractLabel("KasQueryGetDialogLocation") != "") { 

myDialog.location = app.extractLabel("KasQueryGetDialogLocation").split(","); 

var myGroup = myDialog.add('group', undefined, ''); 

myGroup.orientation = 'row'; 

var myCreateQ = myGroup.add('button', undefined, 'Create Query', {name:'CreateQ'}); 

var mySaveQ = myGroup.add('button', undefined, 'Save Query', {name:'mySaveQ'}); 

var myRunQ = myGroup.add('button', undefined, 'Run Queries', {name:'myRunQ'}); 

var mySelectQ = myGroup.add('checkbox', undefined, 'Run on Selection', {name:'mySelectQ'}); 

mySelectQ.value = true

 

myDialog.show(); 

 

myCreateQ.onClick = function() { 

app.changeTextPreferences = app.findTextPreferences = NothingEnum.nothing; 

app.menuActions.item("Find/Change...").invoke(); 

 

 

mySaveQ.onClick = function() { 

app.activeDocument.undo(); 

var myDescription = GetDescription(); 

var myQuery = {}; 

myQuery.findTextPreferences = app.findTextPreferences.properties; 

myQuery.changeTextPreferences = app.changeTextPreferences.properties; 

myQuery.findChangeTextOptions = app.findChangeTextOptions.properties; 

myQuery.description = myDescription 

var mySerSettings = myQuery.toSource(); 

var myFolderPath = Folder.decode(app.filePath.absoluteURI) + "/Scripts/Scripts Panel/Queries"; 

var myFolder = Folder(myFolderPath); 

if (!myFolder.exists) myFolder.create(); 

//+++++++++++++++++++++++++++++++++++++++++++++ 

var myNum = []; 

var aFile; 

var num; 

 

 

var myFiles = myFolder.getFiles("*.txt"); 

for (i = 0; i < myFiles.length; i++) { 

aFile = myFiles.displayName; 

num = parseInt(aFile.split("_")[0]); 

myNum.push(num); 

var myLastNumber = FindLastNumber(myNum); 

var myNumber = myLastNumber+1; 

if (isNaN (myNumber)) myNumber = 1; 

var myPrefix = (myNumber < 10) ? ("0" + myNumber) : myNumber; 

var myFileName = myPrefix + "_" + myDescription.substr(0, 30) + ".txt"; 

var myPath = myFolderPath + "/" + myFileName; 

WriteToFile(mySerSettings, myPath); 

if (File(myPath).exists) { 

alert("Query has been created."); 

else { 

alert("Something went wrong."); 

} // END mySaveQ.onClick 

 

 

myRunQ.onClick = function() {

if(app.selection.length == 0 || app.selection[0].constructor.name != "TextFrame")

{

alert("A textframe selection is needed for the query to run")

exit()

}

var myDoc = app.activeDocument; 

var myFolder = Folder (Folder.decode(app.filePath.absoluteURI) + "/Scripts/Scripts Panel/Queries"); 

var myFiles = myFolder.getFiles("*.txt"); 

 

 

for (i = 0; i < myFiles.length; i++) { 

var myFile = myFiles

var mySettings = eval(ReadFile(myFile)); 

 

if (mySettings.changeTextPreferences.appliedCharacterStyle != "") { 

var myCharStyle = myDoc.characterStyles.itemByName(mySettings.changeTextPreferences.appliedCharacterStyle); 

if (!IsValidReference(myCharStyle)) { 

WriteError( "Error -- " + GetDate()  

+ "\rQuery: " + myFile.displayName  

+ "\rFile: " + myDoc.name  

+  "\rCharacter Style \"" + mySettings.changeTextPreferences.appliedCharacterStyle  

+ "\" doesn't exist\r------------------------------------------------\r" ); 

continue; 

app.findTextPreferences = app.changeTextPreferences = NothingEnum.nothing; 

app.findTextPreferences.properties = mySettings.findTextPreferences; 

app.changeTextPreferences.properties = mySettings.changeTextPreferences; 

app.findChangeTextOptions.properties = mySettings.findChangeTextOptions; 

 

try { 

if(mySelectQ.value && app.selection[0]) 

app.selection[0].changeText(); 

else 

myDoc.changeText(); 

catch(err) { 

WriteError( "Error -- " + GetDate() 

+ "\rFile: " +myFile.displayName + " -- " + err.message + "\r"); 

} // END myRunQ.onClick 

 

 

myDialog.onClose  = function() { 

app.insertLabel("KasQueryGetDialogLocation", String(myDialog.location)); 

} // END CreatePalette 

 

 

function WriteToFile(myText, myPath) { 

myFile = new File(myPath); 

myFile.open("w"); 

myFile.write(myText);  

myFile.close(); 

 

 

function ReadFile(myFile) { 

myFile.open("r"); 

var myText = myFile.read();  

myFile.close(); 

return myText; 

 

 

function GetDescription() { 

var myDialog = new Window("dialog", "Enter Description"); 

var btnPanel = myDialog.add("panel", undefined, "Enter a short description of the search-replace operation"); 

var editText = btnPanel.add("edittext"); 

editText.preferredSize = [360, 40]; 

editText.active = true; 

var myGroup = myDialog.add("group"); 

myGroup.orientation = "row"; 

var okBtn = myGroup.add("button", undefined, "OK"); 

var cancelBtn = myGroup.add("button", undefined, "Cancel"); 

var stText = btnPanel.add("statictext", undefined, "Don't use illegal characters: ? [ ] / \ = + < > : ; \" , * |"); 

var res = myDialog.show(); 

if (res == 1) { 

if (editText.text == "") { 

var myDescription = "unnamed"; 

else { 

var myDescription = editText.text; 

return myDescription; 

else { 

exit(); 

//-------------------------------------------------------------------------------------------------------------- 

function WriteError(myText) { 

myFile = new File("~/Desktop/Error Report.txt"); 

if ( myFile.exists ) { 

myFile.open("e"); 

myFile.seek(0, 2); 

else { 

myFile.open("w"); 

myFile.write(myText);  

myFile.close(); 

//-------------------------------------------------------------------------------------------------------------- 

function IsValidReference(ref) { 

try { 

ref.name; 

return true; 

catch (myError) { 

return false; 

//-------------------------------------------------------------------------------------------------------------- 

function GetDate() { 

var myDate = new Date(); 

if ((myDate.getYear() - 100) < 10) { 

var myYear = "0" + new String((myDate.getYear() - 100)); 

} else { 

var myYear = new String ((myDate.getYear() - 100)); 

var myDateString = (myDate.getMonth() + 1) + "/" + myDate.getDate() + "/" + myYear + " " + myDate.getHours() + ":" + myDate.getMinutes() + ":" + myDate.getSeconds(); 

return myDateString; 

//-------------------------------------------------------------------------------------------------------------- 

function FindLastNumber(myArr) { 

var myLastNumber = myArr[0]; 

for (i = 1; i < myArr.length; i++) { 

if (myArr > myLastNumber) { 

myLastNumber = myArr

return myLastNumber; 

1 reply

Community Expert
January 8, 2019

i suppose you are talking about the script by Kasyan, the one i got from the following link

Find change by queries

If it is the same, i did modify the script with an option to do its operation on the selection. If no selection is found the document is searched and replaced. Use the checkbox the allows to use selection or the document

#targetengine "session"

CreatePalette();

function CreatePalette() {

var myDialog = new Window('palette', 'Search-Replace by Queries');

if (app.extractLabel("KasQueryGetDialogLocation") != "") {

myDialog.location = app.extractLabel("KasQueryGetDialogLocation").split(",");

}

var myGroup = myDialog.add('group', undefined, '');

myGroup.orientation = 'row';

var myCreateQ = myGroup.add('button', undefined, 'Create Query', {name:'CreateQ'});

var mySaveQ = myGroup.add('button', undefined, 'Save Query', {name:'mySaveQ'});

var myRunQ = myGroup.add('button', undefined, 'Run Queries', {name:'myRunQ'});

var mySelectQ = myGroup.add('checkbox', undefined, 'Run on Selection', {name:'mySelectQ'});

myDialog.show();

myCreateQ.onClick = function() {

app.changeTextPreferences = app.findTextPreferences = NothingEnum.nothing;

app.menuActions.item("Find/Change...").invoke();

}

mySaveQ.onClick = function() {

app.activeDocument.undo();

var myDescription = GetDescription();

var myQuery = {};

myQuery.findTextPreferences = app.findTextPreferences.properties;

myQuery.changeTextPreferences = app.changeTextPreferences.properties;

myQuery.findChangeTextOptions = app.findChangeTextOptions.properties;

myQuery.description = myDescription

var mySerSettings = myQuery.toSource();

var myFolderPath = Folder.decode(app.filePath.absoluteURI) + "/Scripts/Scripts Panel/Queries";

var myFolder = Folder(myFolderPath);

if (!myFolder.exists) myFolder.create();

//+++++++++++++++++++++++++++++++++++++++++++++

var myNum = [];

var aFile;

var num;

var myFiles = myFolder.getFiles("*.txt");

for (i = 0; i < myFiles.length; i++) {

aFile = myFiles.displayName;

num = parseInt(aFile.split("_")[0]);

myNum.push(num);

}

var myLastNumber = FindLastNumber(myNum);

var myNumber = myLastNumber+1;

if (isNaN (myNumber)) myNumber = 1;

var myPrefix = (myNumber < 10) ? ("0" + myNumber) : myNumber;

var myFileName = myPrefix + "_" + myDescription.substr(0, 30) + ".txt";

var myPath = myFolderPath + "/" + myFileName;

WriteToFile(mySerSettings, myPath);

if (File(myPath).exists) {

alert("Query has been created.");

}

else {

alert("Something went wrong.");

}

} // END mySaveQ.onClick

myRunQ.onClick = function() {

var myDoc = app.activeDocument;

var myFolder = Folder (Folder.decode(app.filePath.absoluteURI) + "/Scripts/Scripts Panel/Queries");

var myFiles = myFolder.getFiles("*.txt");

for (i = 0; i < myFiles.length; i++) {

var myFile = myFiles;

var mySettings = eval(ReadFile(myFile));

if (mySettings.changeTextPreferences.appliedCharacterStyle != "") {

var myCharStyle = myDoc.characterStyles.itemByName(mySettings.changeTextPreferences.appliedCharacterStyle);

if (!IsValidReference(myCharStyle)) {

WriteError( "Error -- " + GetDate()

+ "\rQuery: " + myFile.displayName

+ "\rFile: " + myDoc.name

+  "\rCharacter Style \"" + mySettings.changeTextPreferences.appliedCharacterStyle

+ "\" doesn't exist\r------------------------------------------------\r" );

continue;

}

}

app.findTextPreferences = app.changeTextPreferences = NothingEnum.nothing;

app.findTextPreferences.properties = mySettings.findTextPreferences;

app.changeTextPreferences.properties = mySettings.changeTextPreferences;

app.findChangeTextOptions.properties = mySettings.findChangeTextOptions;

try {

if(mySelectQ.value && app.selection[0])

app.selection[0].changeText();

else

myDoc.changeText();

}

catch(err) {

WriteError( "Error -- " + GetDate()

+ "\rFile: " +myFile.displayName + " -- " + err.message + "\r");

}

}

} // END myRunQ.onClick

myDialog.onClose  = function() {

app.insertLabel("KasQueryGetDialogLocation", String(myDialog.location));

}

} // END CreatePalette

function WriteToFile(myText, myPath) {

myFile = new File(myPath);

myFile.open("w");

myFile.write(myText);

myFile.close();

}

function ReadFile(myFile) {

myFile.open("r");

var myText = myFile.read();

myFile.close();

return myText;

}

function GetDescription() {

var myDialog = new Window("dialog", "Enter Description");

var btnPanel = myDialog.add("panel", undefined, "Enter a short description of the search-replace operation");

var editText = btnPanel.add("edittext");

editText.preferredSize = [360, 40];

editText.active = true;

var myGroup = myDialog.add("group");

myGroup.orientation = "row";

var okBtn = myGroup.add("button", undefined, "OK");

var cancelBtn = myGroup.add("button", undefined, "Cancel");

var stText = btnPanel.add("statictext", undefined, "Don't use illegal characters: ? [ ] / \ = + < > : ; \" , * |");

var res = myDialog.show();

if (res == 1) {

if (editText.text == "") {

var myDescription = "unnamed";

}

else {

var myDescription = editText.text;

}

return myDescription;

}

else {

exit();

}

}

//--------------------------------------------------------------------------------------------------------------

function WriteError(myText) {

myFile = new File("~/Desktop/Error Report.txt");

if ( myFile.exists ) {

myFile.open("e");

myFile.seek(0, 2);

}

else {

myFile.open("w");

}

myFile.write(myText);

myFile.close();

}

//--------------------------------------------------------------------------------------------------------------

function IsValidReference(ref) {

try {

ref.name;

return true;

}

catch (myError) {

return false;

}

}

//--------------------------------------------------------------------------------------------------------------

function GetDate() {

var myDate = new Date();

if ((myDate.getYear() - 100) < 10) {

var myYear = "0" + new String((myDate.getYear() - 100));

} else {

var myYear = new String ((myDate.getYear() - 100));

}

var myDateString = (myDate.getMonth() + 1) + "/" + myDate.getDate() + "/" + myYear + " " + myDate.getHours() + ":" + myDate.getMinutes() + ":" + myDate.getSeconds();

return myDateString;

}

//--------------------------------------------------------------------------------------------------------------

function FindLastNumber(myArr) {

var myLastNumber = myArr[0];

for (i = 1; i < myArr.length; i++) {

if (myArr > myLastNumber) {

myLastNumber = myArr;

}

}

return myLastNumber;

}

-Manan

-Manan
J van EAuthor
Inspiring
January 8, 2019

Yes, that's the one indeed! But er... how do I save that script of yours...? Or how do I edit the one I've got? I have no experience with writing and editing scripts: I only use them. (I suppose the script is fully compatible with ID 2018 (and 2019)?

Community Expert
January 8, 2019

For saving and using the script i gave, look at the following link

https://indesignsecrets.com/how-to-install-a-script-in-indesign-that-you-found-in-a-forum-or-blog-post.php

As regards compatibility with CC2018/2019 i suppose it should be. I had access to CC2014, i did a quick run and it seemed to work, revert back if you have issues.

-Manan

-Manan