Hi,
I had to search and replace more than 60 long numbers with other numbers. Would take time, error-prone.
Therefore I wrote a short ExtendScript script to do this.
I found a start here:
https://community.adobe.com/t5/framemaker-discussions/find-replace/m-p/3581679
(Russ Ward and Ian Prowdfood, thank you very much!)
(I just put the search and replace strings into an array and did not copy them from elsewhere. Easier with the help of Notepad++.)
However, I always get an error message that FA_errno would be read only.
I found another info here:
https://community.adobe.com/t5/framemaker-discussions/are-there-situations-where-you-can-not-override-the-fa-errno-s-code/m-p/3897361
Therefore I replaced the call to FA_errno with the function.
But why do I get this error message, when others obviously do not have any issues?
Best regards, Winfried
---
#target framemaker
"use strict";
#strict on
(function () {
var loDoc, loFlow, lsFindString, lsReplaceString, lsConsiderCase, lsReplacementCounter;
var laStrings = [];
var laStringSearchReplace = [];
loDoc = app.ActiveDoc;
if (!loDoc.ObjectValid ()) {
Alert ("Document required ", Constants.FF_ALERT_CONTINUE_NOTE);
return;
}
loFlow = loDoc.MainFlowInDoc;
CreateStringsArray (laStrings);
//$.writeln ("laStrings.length: " + laStrings.length);
//$.writeln ("laStrings [0]: " + laStrings [0]);
for (var li = 0; li < laStrings.length ; li += 1)
{
lsFindString = laStrings [li][0];
lsReplaceString = laStrings [li][1];
lsConsiderCase = 1;
lsReplacementCounter = FindAndReplaceString (loDoc, loFlow, lsFindString, lsReplaceString, lsConsiderCase)
$.writeln ("lsReplacementCounter: " + lsReplaceString + " " + lsReplacementCounter);
}
$.writeln ("Done");
function FindAndReplaceString (foDoc, foFlow, fsFindString, fsReplaceString, fsConsiderCase) {
// From Adobe forum:
// https://community.adobe.com/t5/framemaker-discussions/find-replace/m-p/3581679
var tr = new TextRange();
var restoreTR, frame = 0;
var loopCounter = 0, replacementCounter = 0;
var findParams = new PropVals();
// if the flow object is not valid, assume the main flow
if (foDoc.ObjectValid() && !foFlow.ObjectValid()) {
foFlow = foDoc.MainFlowInDoc;
}
// get the first text frame in the flow, a starting point to
// find the first paragraph
if (foFlow.ObjectValid()) {
frame = foFlow.FirstTextFrameInFlow;
}
// At this point, if we don't have a frame object, might as well abort.
if (!frame.ObjectValid()) {
Alert ("Could not find a starting point for the search. Cannot continue." , Constants.FF_ALERT_CONTINUE_WARN);
return replacementCounter;
}
// store the original text selection as an amenity to restore after the action.
restoreTR = foDoc.TextSelection;
// now, set up the starting text range as the very beginning
// of the flow. We'll move straight from beginning to end.
tr.beg.obj = tr.end.obj = frame.FirstPgf;
tr.beg.offset = tr.end.offset = 0;
// set up our find parameters. We want to configure it to look
// for a string and perhaps be case sensitive. We don't need
// the find to wrap because we are controlling the flow from
// beginning to end.
findParams = AllocatePropVals (2);
findParams [0].propIdent.num = Constants.FS_FindText;
findParams [0].propVal.valType = Constants.FT_String;
findParams [0].propVal.sval = fsFindString;
findParams [1].propIdent.num = Constants.FS_FindCustomizationFlags;
findParams [1].propVal.valType = Constants.FT_Integer;
if (fsConsiderCase) {
findParams [1].propVal.ival = Constants.FF_FIND_CONSIDER_CASE;
}
else {
findParams [1].propVal.ival = 0;
}
// initialize the errno global, which will be used to
// track the progress of the find and replace
initFA_errno ();
//FA_errno = Constants.FE_Success;
// and do an initial find to get started.
tr = foDoc.Find (tr.beg, findParams);
// now, run the find and replace loop as long as we keep finding things.
// The loop counter is just an emergency back door in case something
// goes critically wrong and causes an endless loop.
while (FA_errno === Constants.FE_Success && loopCounter++ < 1000) {
// set up the text range to clear the original text
foDoc.TextSelection = tr;
// clear it
foDoc.Clear (0);
// insert the new text. We should be able to use the
// original beginning of the text range where the old text was
// found.
foDoc.AddText (tr.beg, fsReplaceString);
// now, lets jimmy the text range in memory to place it directly
// after the string we just inserted, so the find picks back up after that.
tr.beg.offset += fsReplaceString.length;
// increment our return counter
if (FA_errno === Constants.FE_Success) {
replacementCounter++;
}
// ...and find the next instance. We'll reset FA_errno again just in case
// something screwy happened while we were replacing text.
initFA_errno ();
//FA_errno = Constants.FE_Success;
tr = foDoc.Find (tr.beg, findParams);
}
// we're done. Restore the document to it's original area of display
foDoc.TextSelection = restoreTR;
foDoc.ScrollToText (restoreTR);
return replacementCounter;
} // --- end FindAndReplaceString
function CreateStringsArray (laStrings) {
laStringSearchReplace = ["12345", "67890"];
laStrings.push (laStringSearchReplace);
} // --- end CreateStringsArray
function initFA_errno () {
app.GetNamedMenu("!MakerMainMenu"); //If this fails, you've got bigger problems
return;
}
})(); //--- end
... View more