6 Replies Latest reply: Apr 26, 2011 4:13 PM by scottbritt RSS

    Using regular expressions in "afpid"

    Brent_2310242 Community Member

      Hi -

       

      I'm testing an XFA form with several sections that can be added or removed.  These sections are implemented using subform "rows" containing various widgets, so my test object tree might contain:

      sfRow

           txtAmount

           ddlType

      sfRow_2

           txtAmount

           ddlType

      sfRow_3

           txtAmount

           ddlType

      where sfRow's afpid/SOM expression could be:     xfa[0].form[0].form1[0].sfCalendar[0].sfWeek[0].sfRow[0]

       

      I would like to use a regular expression for the afpid property for the test object "sfRow" (and its children) so that I do not need to maintain sfRow_2 and other siblings, then use an alternate way (such as an index ordinal) to find the unique row or widget I'm interested in.

       

      But as soon as I set the Test Object property "afpid" to any regular expression (apart from its original unescaped text), the object fails to match, eg. Highlight in application yields:

          The selected object could not be highlighted.

       

      In fact, some regular expressions, eg ".*sfRow\[\d\]" seem to cause my AcroQTP server (Adobe Reader) to enter a bad state and need restarting.

       

      Why doesn't regular-expression matching work for afpid ?

      Any suggestions how I can "collapse" all my row subforms?

       

      - Brent

        • 1. Re: Using regular expressions in "afpid"
          David Millman Community Member

          Hi Brad,

           

          Mike's request for help made it to me this morning.

           

          We fixed this back in March.  Which build are you using?

           

          Dave

          • 2. Re: Using regular expressions in "afpid"
            Brent_2310242 Community Member

            I installed APTT p2 042210 in May.

            From About Adobe Plug-ins, "Automation(.api)" has a version of "9.3.2.205".

             

            - Brent

            • 3. Re: Using regular expressions in "afpid"
              Brent_2310242 Community Member

              After further experimentation, I have reached the following conclusions:

              1) Yes, I can specify the "afpid" property as a regular expression in the object repository.  I think I was confused by other symptoms.

               

              2) I can use this regular expression to retrieve a count of the number of rows by calling the row's parent's ChildObjects():

              Set objRowParent =PdfDoc

              Set objRowHeader = objRowParent.AcroForm("sfHeader")

              Set objRow = objRowParent.AcroForm("sfRow") ' where "afpid is a regexp like ".*sfRow\[\d+\]"

              nChildren = objRowParent.ChildObjects().Count - 1

               

              3) I can use that ChildObjects() call to iterate through the list of rows.

              for i=1 to nChildren

                Set objRow = objRowParent.ChildObjects()(i)

                Set objRowChild = objRow.AcroField("SomeField")

                txtAfpid = objRowChild.getTOProperty("afpid")

                txtAfpid = MyRegexReplace( txtAfpid, "sfRow[\d+]",  "sfRow["&i&"]" )

                Call objRowChild.setTOProperty("afpid", txtAfpid )

                Call objRowChild.RefreshObject()

                Call objRowChild.setValue( "Blah" )

              next

               

              4) Once I change the afpid on a "sfRow" element to a hard-coded value, I cannot change it back to a regular expression.

               

              5) Even if I didn't change the afpid of "sfRow" away from its original regexp, it seems I cannot trust the results of ChildObjects() after I add or delete rows (programmatically or manually at a breakpoint).  Various RefreshObject()s did not help.

               

              6) If I want to get Reader into a bad state, all I need to do is reduce the number of rows (manually or programmatically), then try accessing the members of the ChildObjects() collection that were deleted but still returned as part of the ChildObjects() collection.

               

              7) Strangely, ChildObjects() does refresh its cached value if you ask for something beyond its collection.

              Set objRow = objRowParent.ChildObjects()( nChildren )

              objHeader.AcroButton("Add a row").Click

              objHeader.AcroButton("Add a row").Click

              print objRowParent.ChildObjects().Count-1   ' returns nChildren (wrong)

              Set objRow = objRowParent.ChildObjects()( nChildren+1 )

              print objRowParent.ChildObjects().Count-1   ' returns nChildren+2 (right)

               

              So, I'm left with a lot of hackery where I need to manage the number of rows internally.

               

              Could you please provide some guidance on how to programmatically count rows and access rows?

               

              (I've tried to be reasonably diligent in my VB scripting here, but caveat emptor on any snippets provided above.)

               

              Cheers,

              Brent

              • 4. Re: Using regular expressions in "afpid"
                David Millman Community Member

                I'm glad to hear that regexp matching is working for afpid!

                 

                I don't think that I can help you with the other problem.  Perhaps you should start a dedicated thread for it.  I don't understand what you mean by "change the afpid on a "sfRow" element ... back to a regular expression."

                 

                Dave

                • 5. Re: Using regular expressions in "afpid"
                  Community Member

                  Thanks for your reply and keep sharing.

                  • 6. Re: Using regular expressions in "afpid"
                    scottbritt Community Member

                    I am having the same trouble.  Any help available?  I have written code to simulate the OR highlight function.  I use this code to investigate the OR recognition.  I am curious why explicite strings work but regular expressions do not.  Here is the code for my highlight routine.

                     

                    ' Declare APIs
                    Extern.Declare micHwnd, "GetDesktopWindow", "User32.DLL", "GetDesktopWindow"
                    Extern.Declare micULong, "GetWindowDC", "User32.DLL", "GetWindowDC", micHwnd
                    Extern.Declare micInteger, "ReleaseDC", "User32.DLL", "ReleaseDC", micHwnd, micULong
                    Extern.Declare micULong, "CreatePen", "Gdi32.DLL", "CreatePen", micInteger, micInteger, micDword
                    Extern.Declare micInteger, "SetROP2", "Gdi32.DLL", "SetROP2", micULong, micInteger
                    Extern.Declare micULong, "SelectObject", "Gdi32.DLL", "SelectObject", micULong, micULong
                    Extern.Declare micULong, "DeleteObject", "Gdi32.DLL", "DeleteObject", micULong
                    Extern.Declare micULong, "GetStockObject", "Gdi32.DLL", "GetStockObject", micInteger
                    Extern.Declare micULong, "Rectangle", "Gdi32.DLL", "Rectangle", micULong, micInteger, micInteger, micInteger, micInteger

                    Public Sub Highlight (Obj, Times)

                       ' Get screen coordinates
                       X = eval(Obj.GetROProperty ("abs_x") )
                       Y = eval(Obj.GetROProperty ("abs_y") )
                       W = eval(Obj.GetROProperty ("width") )
                       H = eval(Obj.GetROProperty ("height") )

                       ' Get Desktop DC
                       hDC = Extern.GetWindowDC (Extern.GetDesktopWindow)
                       ' Create a three pixels wide Pen
                       hPen = Extern.CreatePen (6, 3, RGB(0, 0, 0)) ' PS_INSIDEFRAME, 3 , RGB(0, 0, 0)
                       Extern.SetROP2 hDC, 6 ' hDC, R2_NOT
                       Extern.SelectObject hDC, hPen
                       ' Use an empty fill
                       Extern.SelectObject hDC, Extern.GetStockObject (5) ' NULL_BRUSH

                       ' Execute
                       'msgbox X & ", " & Y & ", " & W & ", " & H,,"X, Y, W, H"
                       for i = 0 to Times * 2 + 1
                          Extern.Rectangle hDC, X, Y,X+W, Y+H
                          wait 0, 100
                       Next

                       ' CleanUp
                       Extern.ReleaseDC Extern.GetDesktopWindow, hDC
                       Extern.DeleteObject hPen

                    End Sub

                    ...

                    ...

                    Highlight Window("Windows Internet Explorer").WinObject("Shell DocObject View").PDFDoc("PDF").AcroXFAForm("form").AcroXFAForm("coventryHealthcare").AcroXFAForm("p age1").AcroXFAForm("sGHPMOHealthQuestionaire"), 15    'works because it references stored object in OR


                    Highlight Window("Windows Internet Explorer").WinObject("Shell DocObject View").PDFDoc("PDF").AcroXFAForm("form").AcroXFAForm("coventryHealthcare").AcroXFAForm("p age1").AcroXFAForm("name:=sGHPMOHealthQuestionnaire","afptype:=subform","afpid:=xfa[0].for m[0].coventryHealthcare[0].page1[0].sGHPMOHealthQuestionnaire[0]"),15     'doesn't work.  Actually removes recognition.  'Breaks' Object Spy  Why?