8 Replies Latest reply on Feb 13, 2012 10:43 AM by Wiedenmaier

    Telling Find method NOT to wrap

    4everJang Level 3

      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

        • 1. Re: Telling Find method NOT to wrap
          Wiedenmaier Level 3

          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

          • 2. Re: Telling Find method NOT to wrap
            4everJang Level 3

            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

            • 3. Re: Telling Find method NOT to wrap
              Wiedenmaier Level 3

              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

              • 4. Re: Telling Find method NOT to wrap
                Wiedenmaier Level 3

                BTW:

                FS_FindWrap doesn't mean "Stop at the end of a document", it means "Stop if text range is reached, where search began":

                 

                That's what FDKref says:

                FS_FindWrap

                A BoolT flag that determines whether the find operation will

                wrap when it reaches the location where the search began. Default

                is True; the find operations wraps.

                If False, after reaching the location where the search began, the

                find operation returns an empty F_TextRangeT and

                FA_errno is set to FE_NotFound.

                 

                So if you don't want a document wrap, you have to get last Textrange in doc (i.e. end of last paragraph) and compare findresult with this and cancel search. But that's a little bit tricky.

                Markus

                • 5. Re: Telling Find method NOT to wrap
                  4everJang Level 3

                  Hi Markus,

                   

                  I have tried again by creating two new propVal items. I have been using AllocatePropVals ( 2 ). Same result: no value gets set for ival. Using FM 10.0.2.419. Which version of FM are you using ?

                   

                  Oh, and I do know that the find wraps around to where it started - I am setting the start location to the first Pgf in the document just so that I know what is going on when testing...

                   

                  Ciao from Uppsala - trying to make the customer happier...

                   

                  Jang

                  • 6. Re: Telling Find method NOT to wrap
                    Wiedenmaier Level 3

                    Hi Jang,

                    I run 10.0.2.419, too, in German version, but in my experiences language version doesn't matter at that point.

                     

                    I run exactly that code I posted here, without any modifications. But I used new PropVals() instead of AllocatePropVals().

                    Allocation is done with "new" in ExtendScript/JavaScript. May be that could be the problem.

                     

                    If that doesn't work please post your snippet and I'll go into that one.

                    Markus

                    • 7. Re: Telling Find method NOT to wrap
                      4everJang Level 3

                      Hi Markus,

                       

                      Here is the piece of code I tried. After these lines, the string value in params[0] is set, but the integer in params[1] not.

                       

                      var params = AllocatePropVals ( 2 );

                      params[0].propIdent.num = Constants.FS_FindMarkerOfType;

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

                      params[0].propVal.sval = "Conditional text";

                      params[1].propIdent.num = Constants.FS_FindWrap;

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

                      params[1].propVal.ival = 0;

                      • 8. Re: Telling Find method NOT to wrap
                        Wiedenmaier Level 3

                        Hi Jang,

                         

                        this code works for me. It's nearly the same than above. Because I've got a German FM running "Conditional text" is "Bedingter Text", and with that I tested it.

                        Don't use AllocatePropVals, use new PropVals() and new PropVal() instead.

                         

                        Hope this works for you

                        Markus

                         

                        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_FindMarkerOfType ;
                        propVal.propVal.valType = Constants.FT_String;
                        propVal.propVal.sval = "Conditional text" ;
                        propVals.push(propVal);


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