7 Replies Latest reply on Jul 27, 2010 8:37 AM by philmodjunk

    Perform Find 'invisibly' without having to change layouts?

    smashingly

      Title

      Perform Find 'invisibly' without having to change layouts?

      Post

      Hi,

      I'm trying to do the following, without the layout visibly changing:

      On a text field on a layout ("Scanner"), Script Trigger OnObjectSave detects entry of text from a USB passport scanner.  Essentially this is so the user can scan in a passport and it'll search the Personnel database, find a match, grab the foreign key for that Person record and do something with it (add it to a join table).  The script does the following:

      Show Custom Dialog [ Message: "I'm going to try and search for passport number " & Configuration::MRP_Passport_number & "..."; Buttons: “OK”, “Cancel” ]

      Set Variable [ $passnum; Value:Configuration::MRP_Passport_number ]

      Go to Layout [ “Personnel” (Person) ]

      Set Error Capture [ On ]

      Perform Find [ Specified Find Requests: Find Records; Criteria: Person::Passport Number: “$passnum” ] [ Restore ]

      Set Variable [ $errornum; Value:Get(LastError) ]

      Set Error Capture [ Off ]

      If [ $errornum <> 0 ]

      Show Custom Dialog [ Title: "Error"; Message: If ( $errornum = 401; "Passport number " & $passnum & " was not found in the personnel database. Click OK to be returned to the Trip window." ; "Some other error occurred when searching for passport number " & $passnum & ". The error code is " & $errornum & ". Please contact tech support with this error number." ); Buttons: “OK” ]

      Exit Script [ ]

      End If

      If [ Get(FoundCount) > 1 ]

      Show Custom Dialog [ Title: "More than one match"; Message: "There is more than one match for passport number " & $passnum & ". Please look through the " & Get(FoundCount) & " matches found and eliminate the duplicates. Then try the operation again."; Buttons: “OK” ]

      Exit Script [ ]

      End If

      Set Variable [ $foundPID; Value:Person::PersonID ]

      Set Variable [ $foundFullName; Value:Person::FullName ]

      Go to Layout [ original layout ]

      Show Custom Dialog [ Message: "Person ID: " & $foundPID & "¶" & "FullName: " & $foundFullName & "¶"; Buttons: “OK” ]   // the end-game will be to do something with the PID but for now, this dialog is all I need for debugging.

      So essentially it's running off to another layout, performing a find, getting the PersonID value that matches the passport number scanned, then returning to the original layout.  But it looks as though Filemaker quickly flicks to the Personnel layout to perform the find, then quickly flicks back to the original Scanner Input layout from which this script is run.  Is there any way to use this passport number to locate the person record's PersonID value, without such a visible (albeit very very brief) window change?  Would Freeze Window help here - if so, at what point would I use it in the script?  This is really more about good development practises - the user won't see the window flicker, but if the database was really big, they might do, as the Perform Find would take longer.  If there's a more "correct" way of doing this, I'd rather learn it now in this early(ish) stage in my Filemaker Pro learning!

      regards

      Ash

        • 1. Re: Perform Find 'invisibly' without having to change layouts?
          sunmoonstar.13

          Try Freeze Window as the first step of the script.

           

          Nick

          • 2. Re: Perform Find 'invisibly' without having to change layouts?
            mps1773

            Ash, when we encounter such a lag time from a large database that the screen flickers we have come to using a new window that is created outside of the normally expected screen space. In fact I use this ever more increasingly.  The following is an example:

            Set Variable [$WindowName; Value:"New Window's Name"]

            New Window [Name: $WindowName; Top: 10000; Left: 10000]

            ...

            ... code to navigate to a layout, perform a find or any other needful thing...

            ...

            Close Window [Name: $WindowName; Current file]

            This also perfectly preserves the state of the original layout.

            I habitually set a global variable, such as $$SkipTriggers, which I use at the beginning of all

            Script Trigger scripts to exit any scripts that are run when I layout loads or a record loads to

            help keep things a little speedier, as well.

            Good luck :)

            • 3. Re: Perform Find 'invisibly' without having to change layouts?
              smashingly

              Thanks to both of you!  Freeze Window did the trick nicely.  The only evidence that FMP was briefly changing layouts to do the Perform Find, was that the scroll bar twitched or changed colour briefly - but I felt it was good practise to find a better way of doing things.

              The idea of creating a new window off the screen is an interesting one!  The reason being, when my script finds two records with the same passport number (which only happens because the client has slightly sloppy data-quality habits and sometimes re-enters the same person twice), I'd like to actually open a new window with the two dupes as a found set, so he can then decide which one to keep, and delete the other one.  Currently my If statement which checks Get(FoundCount), opens a new window.  But I could easily have the new window already open at Top=10000, Left 10000 and if FoundCount > 1 then Move/Resize Window to a visible position.  Options options...

              mps1773, I didn't quite understand what you were saying about your global variable, can you elaborate?

              thanks for the speedy responses guys!

              Ash

              • 4. Re: Perform Find 'invisibly' without having to change layouts?
                smashingly

                PS: this DB dev is so much fun sometimes - it's way more creative than the regular IT break-fix work I do.  Example: I just got a huge buzz off coming up with the following smart dialog box text:

                "There is more than one match for passport number " & $passnum & ".  When you click OK, you will see the Personnel records filtered down to just these " & $foundcount & " records.  Please look through them and eliminate the duplicate" & If($foundcount>2;"s";"") & ".  Then go back to the original page and try the operation again."

                If there are 2 records with the same passport number the sentence reads "...eliminate the duplicate."  ... if there are 3 or more records then obviously there's more than one duplicate so it says "...eliminate the duplicates."  Trivial but nice touch and it put a smile on my face that I can make FMP do that :-)

                • 5. Re: Perform Find 'invisibly' without having to change layouts?
                  mps1773

                  One thing that can happen when there is a list of a lot of records being filter/sorted/autoformatted when first opening a layout, especially when there are a lot of relationships and calculated fields... all of which are true for our core system (my supervisors love the bell-and-whistles) ...opening a layout can be too slow of a process for quick bounces between layouts to performs finds.  When you open a new window FM doesn't give you the option of which layout to go directly to, it always opens the same one you have open in the original window.  When this happens it reloads the whole layout from scratch, performing all of the multitude of script triggers (OnLayoutLoad, OnRecordLoad, etc.) which can cause a rather large increase in the amount of time it takes to perform that find, for example.

                  What I have done is to create two scripts, "Set SkipNextTriggers" and "Clear SkipNextTriggers".  These simply set or clear a global variable ($$SkipNextTriggers) with a boolean value.

                  Then I add:

                  If ( $$SkipNextTriggers )

                  Exit Script[]

                  End If

                  to the beginning of each script that is called by a trigger throughout the database.

                  Now, when I want to open a new window for, say, an automated find on another layout, I call "Set SkipNextTriggers" before opening the window and then "Clear SkipNextTriggers" after opening it & navigating or even after closing the window altogether, depending on the need of the situation (perhaps navigating more than one layout in a window).  Having that global variable set will bypass all scripts that are triggered by navigating the layouts.

                  • 6. Re: Perform Find 'invisibly' without having to change layouts?
                    smashingly

                    Ah, NOW I get it!  That's a brilliant idea.  Thanks for explaining it - it'll come in handy for me not just for large databases like yours but for controlling other things globally.

                    regards

                    Ash

                    • 7. Re: Perform Find 'invisibly' without having to change layouts?
                      philmodjunk

                      Unfortunately, in a windows environment, the new window trick can trigger an unfortunate resize of the underlying window which can't be wholly eliminated if your solution is set up to work with maximized windows. Thus, switching layouts while freezing the window often can be done "less visibly" than using New Window on windows platforms.