Find/Replace behaving erratically

Advocate ,
Sep 25, 2018

Copy link to clipboard


Dear friends and experts

In my script FM-biblio the following is a key task:

  • An RTF file contains lines with the search and the replace strings:

  {Daube 1989 #9}»(Daube 1989)

  The » denotes a TAB

  • For every line in the RTF:
    •   Set up the Find parameters (using the search string)
    •   Find and replace as long as successful (Russ Ward method)

The whole script was developed in FM-13 times (and you find a lot of discussion about it in this forum). Now with FM-14 the Find/Replace loop turns out to be a vabanque game.

My test document is just two pages with 18 search items (some occur multiple times) and i have 11 replace items in the RTF.

The first item in the RTF is often not replaced in the FM doc.

I can repeat the find-replace step of the script multiple times. Sometimes I need to do so 3 times until also the first item is processed (revert to saved between the trials).

➔ What can be the reason for this behaviour? Timing?

For my extensive test series I did not change anything on the script. It is located in %UserProfile%\Docuemnts\Adobe Scripts\

Starting with FM-15 I saved the document as MIF and did the tests 3 times.

FM-15:  Of 3 trials 1 successful; FM-14 3/1; FM-13 3/1; FM-12 3/2; FM-11 3/3; FM-10 3/3

These tests 'mifed down' the document from FM-14 to FM-10, hence removing a lot of not used stuff. And now I repeted the tests:

In all FM-versions up to FM-15 success is 3 of 3!

➔ The more complex the FM file, the less reliable the Find/Change function.

But something else bothered me during the tests: sometimes I got error messages in the log:

"undefined is not an object" on script line 193, which reads

  var inputFile, prompt, docFile;

Then I just restarted FrameMaker and tried agian: No message then...

➔ ExtendScript is not reliable at all.

➔ How to conquer such obstacles?

I have added here only the find/replace function and the function setting up the find parameters:

function FindAndReplaceString (activeDoc, findString, replaceString, loopMax) { //=================

// Replace string by another

// Function returns replacemtCounter

// Since we have collected only in doc.MainFlowInDoc, we replace only in this flow

// loopMax used as emergency back door - twice the # of initially found citations

// We do not have an initial TextSelection, hence start directly at the first paragraph

// Source: Russ Ward in

  giFMbib_LvlTrace += 1; ZTrace ("FindAndReplaceString");

  var tr = new TextRange();

  var restoreTR, frame = 0, loopCounter = 0, replacementCounter = 0;

  var findParams = new PropVals();

  var firstPgf = activeDoc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;


  tr.beg.obj = tr.end.obj = firstPgf;             // set up the starting text range as the very beginning

  tr.beg.offset = tr.end.offset = 0;              // of the flow. We'll move straight from beginning to end.

  trSaved = tr                                    // to come back after work

//We don't need the find to wrap because we are controlling the flow from beginning to end.

  findParams = GetFindParams (findString);        // Get the find parameters for finding string, case sensitive

  InitFA_errno ();                                // reset - it is write protected

  tr = activeDoc.Find(tr.beg, findParams);        // and do an initial find to get started.


  while(FA_errno === Constants.FE_Success && loopCounter++ < 2*loopMax) { //find and replace loop as long as we keep finding

ZLog ("   Replacement = «" + replaceString + "»")

    activeDoc.TextSelection = tr;                 // set up the text range to clear the original text

    activeDoc.Clear(0);                           // clear it

    activeDoc.AddText(tr.beg, replaceString);     // insert the new text at the original beginning of the text range

    tr.beg.offset += replaceString.length;        // 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.

    if(FA_errno === Constants.FE_Success) {       // increment our return counter - does not work



    InitFA_errno ();                              // to be used to track the progress of the find and replace

    tr = activeDoc.Find(tr.beg, findParams);      // something screwy happened while we were replacing text.


  activeDoc.ScrollToText(trSaved);                // we're done. Restore the document to it's original area of display

  giFMbib_LvlTrace -= 1;

  return replacementCounter;

} // --- end FindAndReplaceString

function GetFindParams (string) { //===============================================================

// Get/set the find parameters

// Returns find parameters in the function

// Consider string, case;

// Source; Rick Quatro

  if (gbFMbib_Verbose) {giFMbib_LvlTrace += 1; ZTrace ("GetFindParams");}

  var findParams = AllocatePropVals (2); 

  findParams[0].propIdent.num = Constants.FS_FindText; 

  findParams[0].propVal.valType = Constants.FT_String; 

  findParams[0].propVal.sval = string; 

  findParams[1].propIdent.num = Constants.FS_FindCustomizationFlags;

  findParams[1].propVal.valType = Constants.FT_Integer;

  findParams[1].propVal.ival = Constants.FF_FIND_CONSIDER_CASE;

  if (gbFMbib_Verbose) {giFMbib_LvlTrace -= 1;}

  return findParams; 

} // --- end GetFindParams








Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Have something to add?

Join the conversation