Skip to main content
4everJang
Legend
February 11, 2012
Question

Telling Find method NOT to wrap

  • February 11, 2012
  • 3 replies
  • 3792 views

Hello,

I cannot make sense of the parameters to use for the doc.Find() method. I have succesfully created an array of parameters, but it seems impossible to set the param for FS_FindWrap to 0. According to the ExtendScript documentation, this parameter is expected as a "flag" that tells the Find method whether or not to wrap when the end of the document is reached. But as the params array only allows PropVals and there is NO definition of FT_Boolean of FT_Flag or something similar, I tried to use FT_Integer and assign the value 0 to it. The point is that this value is simply refused. It does NOT get set and the resulting ival of the parameter shows "ssval does not have a value".

I REALLY need this parameter and I need the Find() method to do what it is supposed to do, but FM is making it impossible. Is this a bug or am I doing something wrong here ?

Help !!!

Jang

This topic has been closed for replies.

3 replies

Inspiring
February 13, 2020

Just to throw in my two cents, here is the syntax I prefer for declaring PropVals explicitly:

 

var myProps = new PropVals(
	new PropVal(
		new PropIdent(Constants.FS_FindWrap),
		new TypedVal(0)
	),
	new PropVal(
		new PropIdent(Constants.FS_FindText),
		new TypedVal('text')
	)
);
K.Daube
Community Expert
Community Expert
February 12, 2020

Jang, I run into the same problem when working with footnotes.

I had to remember the current location and stop the find process after traversing this again.

As Rick points out, i try to avoid the Find method, but it is the only method to get things in the order the user sees them. Other method present the order of creation.

function Fno_FindNextEnXref (oDoc, oUserLoc, sXRefFmt) { //=== Find next xref to endnote ===============
// Arguments  oDoc      Document receiving the XRef
//            oUserLoc   Current location where the user wants to place the EN reference
//            sXRefFmt  Cross reference format of xref to endnote
// Returns    XRef object or null
// Attention  NoWrap in the Find parameters has no effect - need to find wrap 'manually'
var IDcurrent, IDfound, jPgf = 1, jThis, jFound, k, 
    oFindParams, oPgf, oPgfEnd, oPgfStart, oTL, oTRfound, oXRef, oXRefTI;

  oTL = oUserLoc.txtRange.beg;                     // current cursor location
  oFindParams= Fno_GetFindParameters (8, sXRefFmt);  // find XRef forwards, NoWrap not working
  oTRfound = oDoc.Find(oTL, oFindParams);
  if (oTRfound.beg.obj.ObjectValid()) {
    oXRefTI  = oDoc.GetTextForRange (oTRfound, Constants.FTI_XRefBegin); // one 1 item in array
    for (k = 0; k < oXRefTI.length; k++) {        // k always 0 nevertheless loop necessary!
      oXRef = oXRefTI[k].obj;
      break;
    }
  }
  if (oXRef == undefined) {return null; }         // no XRefs at all in Doc
//                                            --- Check whether there was a wrap around
  IDcurrent = oTL.obj.id;                         // ¶ of current location
  IDfound   = oXRef.TextRange.beg.obj.id;         // ¶ of found XRef
  oPgfStart = oDoc.MainFlowInDoc.FirstTextFrameInFlow.FirstPgf;
  oPgfEnd = Fno_GetLastPgfInMainFlow (oDoc);
  oPgf = oPgfStart;
  while (oPgf.ObjectValid() ) {
    if (IDcurrent == oPgf.id) {jThis = jPgf;}
    if (IDfound == oPgf.id) {jFound = jPgf;}
    oPgf = oPgf.NextPgfInFlow;
    jPgf += 1;
    if (jThis != undefined && jFound != undefined) {break}
  }
  if (jFound >= jThis) { return oXRef;}           // Next XRef found after current location
  return undefined;                               // No XRef after the current location
} //--- end Fno_FindNextEnXref
Inspiring
February 12, 2012

Hi Jang,

I only did this in FDK. And it works like this

    F_PropValsT findParams ;
    findParams = F_ApiAllocatePropVals(1);
    findParams.val[0].propIdent.num = FS_FindWrap;
    findParams.val[0].propVal.valType = FT_Integer;
    findParams.val[0].propVal.u.ival = FALSE;

    F_TextRangeT trFound = F_ApiFind(m_docId, &textrange.beg, &findParams);

If end of document is reached and nothing is found, trFound is noch valid (all members are 0)

So in ExtendScript it shoud work something like this:

    var findParams = new PropVals();

    var findParam = new PropVal()
    findParam.propIdent.num = Constants.FS_FindWrap;
    findParam.propVal.valType = Constants.FT_Integer;
    findParam.propVal.u.ival = false;

    findParams.push(findParam) ;

    var trFound = app.ActiveDoc.Find(textrange.beg, findParams);

BTW: ssval is null or empty, because this is an integer value, which you could get and set at ival (boolean == integer 0 or 1, so there's no need for FT_Boolean)

Hope this helps

Markus

4everJang
4everJangAuthor
Legend
February 13, 2012

Hello Markus,

Thanks for the help but the problem is that there is NO object propVal.u let alone propVal.u.ival. And if I try to set propVal.ival = 0, nothing happens. So I am slowly getting to the belief that this is a bug in FM10's ExtendScript.

I have found a workaround though, with some help from Rick: I push all the found textranges into an array until I find a textrange that has the same textlocs as the first one found. At that point, I know I have wrapped around and I exit the loop. The important thing about pushing the textranges into an array is that making the change to the textrange potentially changes the offsets, which makes it impossible to find the wraparound item. I now process all the textranges after I break out of the find loop.

It is a hassle, though. It should be easier. It should work.

Ciao

Jang

Inspiring
February 13, 2012

Hi Jang,

this snippet works for me. propVal in ES has no u. it has ival  or sval directly.

var doc = app.ActiveDoc;
var range = doc.TextSelection;


var propVals = new PropVals() ;

var propVal = new PropVal() ;
propVal.propIdent.num = Constants.FS_FindWrap ;
propVal.propVal.valType = Constants.FT_Integer;
propVal.propVal.ival = 0 ;
propVals.push(propVal);

propVal = new PropVal() ;
propVal.propIdent.num = Constants.FS_FindText ;
propVal.propVal.valType = Constants.FT_String;
propVal.propVal.sval = "Test" ;
propVals.push(propVal);

for (var i=0 ; i < 5; i++)
{
    var findrange = doc.Find (range.end, propVals);
    if (findrange.beg.obj.ObjectValid() ==false)
    {
        alert("Text not found: " + i) ;
        break ;
    }
    else
        range = findrange ;
}

if I set FS_FindWrap to 1, it finds the word "Test" 5 times in my sample document.

If I set FS_FindWrap to 0, it finds the word "Test" once in my sample document

So i think this should work, at least in my small tests

Markus