4 Replies Latest reply on Feb 10, 2010 1:07 PM by RickWhitelaw

    A possible solution to Filemaker printing problems

    RickWhitelaw

      Title

      A possible solution to Filemaker printing problems

      Post

      Hi,

       

      I've been working to get around what I find to be a problem in Filemaker: scripting printing is convenient and simple, but the "Print" script step involves printer selection. The printer selection then becomes "hard-coded" in a given solution. When it's used on another computer with different printers the print scripts are no longer functional. 

      I'm a Mac user (10.6.2) and nearly certain this will work only on a Mac. As well, I've tried it out on only three printers . . . swapping jobs between them. 

      Error trapping is not implemented in the scripts yet.

      I'm a complete newbie as far as command line scripting is concerned, and the shell scripts below likely need more work, but they function.

      One final caveat: in the process of exploring various OS commands, I had to re-install the driver for one  printer. I don't believe any of the scripts below caused this.

       

      The basic idea: rather than scripting printer selection, script the "task". Users Assign printers to particular tasks in a preferences table. The Printer Preferences layout is  available via the menu in the event a user connects a new printer or disconnects one. If there's only one printer, the same printer name can be entered for all tasks. 

       

      Create a table, I call it PRINT_PREFS. I have a table called "User_Prefs" which stores info about the user. One way or the other, this table relates to virtually all tables in the solution, so I relate PRINT_PREFS to it and allow the creation of records by the User table. In this table are a Key field, plus a global text field for each anticipated printing task, i.e General, Forms/Cheques, Color, Envelopes and Labels which accept printer names. (Auto-enter calculation:  Substitute ( Self; [" " ; "_" ];["-";"_"]) to format as Unix compliant). As well, three global text fields: Color_Duplex, General_Duplex and Forms_Duplex. These three fields are either "Yes" or " " (blank). The user chooses "Yes" if the printer supports double-sided printing. This is used in a variable in the third script below. There are two other fields (text) presented as yes/no checkbox sets. In one the user decides whether or not to view standard print dialogs. If the user chooses "yes" all the print scripts will send him/her to the standard print dialog and exit the script (not implemented below). The other "yes/no" asks whether there are multiple printers connected. If "no" is selected, the remaining "task" fields will be populated by the General Printer name, a field which is not allowed to be empty(not implemented below).

      The user clicks a button to run the following script:

       

      Terminal printer Choosing

      Perform AppleScript [ Native AppleScript: tell application "Terminal" do script ("lpstat -a") end ]

      Show Custom Dialog [ Title: "Enter the names of your Printers"; Message: "Enter the printer names or or copy/paste them from the Terminal window. Press More to assign Envelopes and Labels. You can assign a printer to more than 1 task. Press done when finished."; Buttons: “Done”, “More”; Input #1: PRINT_PREFS:: Printer_General, "General purpose Printer"; Input #2: PRINT_PREFS::  Printer_Forms_Cheques, "Cheques/Forms Printer"; Input #3: PRINT_PREFS:: Printer_Color, "Color Printer" ]

      If [ Get ( LastMessageChoice ) = 2 ]

      Show Custom Dialog [ Title: "Room for only two more printers."; Message: "Please enter the remaining printer names and press Done when finished."; Buttons: “Done”; Input #1: PRINT_PREFS:: Printer_Labels, "Label Printer"; Input #2: PRINT_PREFS::  Printer_Envelopes, "Envelope printer" ]

      End If Commit Records/Requests

      [ No dialog ]

      Perform AppleScript [ Native AppleScript: tell application "Terminal" quit end ]

       

       

      Having Terminal display the printer names allows for the exact spelling (as seen by the OS) to be used. NOTE: the printers must already be set up in System Preferences for the OS or Terminal to "see" them.

       

      Here's a script that prints a contract form. Since pages 2-5 are basically portals and of fixed length, it's safe to hard-code the possible number of records per page. The Print Setup step, now that I look, is unnecessary because it's handled later by the shell script.

       

       

      PRINT_CONTRACT

      Go to Layout [ “CONTRACTS_INPUT” (CONTRACTS) ]

       # To check certain field content before printing. 

      If [ IsEmpty ( CONTRACTS:: Fee_Agreed_Upon ) ]

      Show Custom Dialog [ Title: "No Payroll!"; Message: "No payroll has been compiled for this engagement. Printing will now stop. Please create a payroll then print again."; Buttons: “OK” ]

      Exit Script [ ] 

      End If

      If [ IsEmpty ( Purpose:: PURPOSE ) or IsEmpty ( TIMES:: HOURS_PERFORMANCE ) or IsEmpty ( DATE_SIGN_PAY::  Payment_DATE ) or IsEmpty ( DATE_SIGN_PAY:: Date_signed ) ]

      Show Custom Dialog [ Title: "Missing information"; Message: "Some important fields are missing data. Please make sure all necessary fields are filled. Press return when finished."; Buttons: “OK” ]

      Pause/Resume Script [ Indefinitely ] 

      End If

      # The layout is a 6 page contract. Page 1 and 2 are always printed. Page 6 is always printed. All 6 pages would be printed only if 55 - 72 names were involved.

      Go to Layout [ “TMA Contract Print Complete” (CONTRACTS) ]

      # The records on this layout are all in portals of the same related table. (1-18,19-36 etc.)

      Print Setup [ Orientation: Portrait; Paper size: 8.5" x 11" ] [ Restore; No dialog ]

      #Set the printer assigned to this "task" by the User in Preferences.

      Set Variable [ $PRINTER; Value: PRINTERS:: Printer_General ] 

      #Set the PAGES variable to ranges of pages to be printed depending on how many people are on the Contract.

       If [ Production Info::NUM_PLAYERS ≤ 18 ]

      Set Variable [ $PAGES; Value:"1,2,6" ] 

      Else If [ Production Info:: NUM_PLAYERS > 18 and Production Info:: NUM_PLAYERS ≤ 36 ]

      Set Variable [ $PAGES; Value:"1-3,6" ]

       Else If [ Production Info:: NUM_PLAYERS > 36 and Production Info:: NUM_PLAYERS ≤ 54 ]

      Set Variable [ $PAGES; Value:"1-4,6" ]

       Else If [ Production Info:: NUM_PLAYERS > 54 and Production Info:: NUM_PLAYERS ≤ 72 ]

      Set Variable [ $PAGES; Value:"1-6" ] 

      End If

      #Save the job to a temporary PDF file on the Desktop.

      Save Records as PDF [ File Name: “file:../../../Desktop/contemp.pdf”; Current record ] [ Document - Compatibility: Acrobat 5 and later ] [ Pages - Number Pages From: 1; Include: All pages ] [ Security - Printing: High Resolution; Editing: Any except extracting pages; Enable copying; Enable Screen Reader ] [ Initial View - Show: Pages Panel and Page; Page Layout: Single Page; Magnification: 100% ]

      [ Restore; No dialog ]

      # Print the PDF two-sided in portrait orientation to Letter size paper, one copy, double-sided with the correct page ranges, then delete the PDF.

      Perform AppleScript [ Calculated AppleScript: "do shell script" &" "& "("&Quote("lpr"&" "&"-P"&$PRINTER&" "&"-o" &" "& "sides=two- sided-long-edge"&" "& "-o" &" "& "media=letter" &" "&"-o"&" "&"page-ranges="&$PAGES&" "&"-o"&" "&"orientation-requested=3"& " "& "-#1"&" "&"~/Desktop/contemp.pdf"&" "&" " &"-r")&")" ]

      Go to Layout [ “CONTRACTS_INPUT” (CONTRACTS) ]

       

      Here's a similar script. The main difference is that it prints a List View Layout. The Print Setup step IS necessary in this one to set the page orientation to capture the number of pages to set "$PAGES" before sending the print job. The disabled step works but depends on the body of the layout NEVER changing in size. I don't recommend it.

       

      Print: Print_AppSubs

      Go to Layout [ “Approved Subs” (SUB_APPROVAL) ]

      # Set the page orientation for the PDF and for the upcoming page count:

      Print Setup [ Orientation: Landscape; Paper size: 8.5" x 11" ] [ Restore; No dialog ]

      Save Records as PDF [ File Name: “file:../../../Desktop/appstemp.pdf”; Records being browsed ] [ Document - Compatibility: Acrobat 5 and later ] [ Pages - Number Pages From: 1; Include: All pages ] [ Security - Printing: High Resolution; Editing: Any except extracting pages; Enable copying; Enable Screen Reader ] [ Initial View - Show: Pages Panel and Page; Page Layout: Single Page; Magnification: 100% ]

      [ Restore; No dialog ]

      # The layout being printed is in List View, hence:

      Enter Preview Mode

      Go to Record/Request/Page [ Last ]

      Set Variable [ $LPAGE; Value:Get ( PageNumber ) ]

      # The following disabled step would set the page-range but is less flexible.

      // Set Variable [ $PAGES; Value:"1-"& If ( Mod (Get ( FoundCount ); 19 > 0 );Truncate ( (Get ( FoundCount ) / 19) + 1 ; 0 );Get ( FoundCount ) / 19 ) ]

      # Set the page-ranges variable for the shell script:

      Set Variable [ $PAGES; Value:"1-"& $LPAGE ]

      Enter Browse Mode 

      # Tell the shell script which printer to use: 

      Set Variable [ $PRINTER; Value: PRINT_PREFS:: Printer_General ] 

      # To set one or two sided printing in the shell script:

      Set Variable [ $DUPLEX; Value:If ( PRINT_PREFS:: General_Duplex = "YES";"two-sided-long-edge";"one-sided" ) ]

      # Print page range with options, two-sided-long-edge to be bound landscape, and delete the PDF:

      Perform AppleScript [ Calculated AppleScript: "do shell script" &" "& "("&Quote("lpr"&" "&"-P"&" "&$PRINTER&" "&"-o" &" "&"sides="& $DUPLEX&" "& "-o" &" "& "media=letter" &" "&"-o"&" "&"orientation-requested=4"& " "& "-#1"&" "&"-o"&" "&"page-ranges="& $PAGES&" "&"~/Desktop/appstemp.pdf"&" "&" " &"-r")&")" ]

       

      This system has a long way to go but begins to solve print scripting problems by making the scripts mobile and doesn't require a plugin. 

       

      RW.

      Edit: spaces added to prevent emoticons 

        • 1. Re: A possible solution to Filemaker printing problems
          RickWhitelaw
            

          Hi,

           

          I'm replying to my own post because I ran afoul of the "maximum characters" limit. The idea presented in my original post really does one significant thing. It obviates the need for the "Print" script step, a step I believe is not well implemented in FM.

          Some error trapping will be necessary of course. One error I'd like to be able to capture is "printer is offline". FM has error 600 (print error has occurred) and 603 (print connection lost), neither of which are reported when I try to print to an off-line computer, which is not a surprise. If anyone has a command-line CUPS method of capturing this error I'd like to see it.

          The other thing is that I sense the shell scripts could be expressed by custom functions and delivered to Applescript in the same manner that Printer Instances are saved to lpoptions files. Most of the lpr options could be expressed with the use of variables calculated by custom functions since the fields referenced in PRINT_PREFS are global.

          I don't mean to make this thread about CUPS or UNIX but these seem to be the tools available to work around a significant shortcoming of Filemaker.

           

          RW 

          • 2. Re: A possible solution to Filemaker printing problems
            deltatango
              

            Rick, I can't get the first apple script command to work. It says:

             

            tell application "Terminal" do script ("lpstat -a") end

             

            And I get this error:

             

            Expected end of line but found command name 

             

            ALSO, how would one set the records being browsed/vs. current record?

             

            I guess one has to export to PDF and then print the PDF correct? 

            • 3. Re: A possible solution to Filemaker printing problems
              RickWhitelaw
                

              DeltaTango,

               

              Here's exactly what I've copied and pasted from the perform Applescript (NATIVE) dialog box. It looks the same and works fine:

               

              tell application "Terminal"

              do script ("lpstat -a")

              end

               

              FM should enclose the entire shell script in quotes automatically for a native Applescript [as well as brackets]. The carriage returns, though invisible, are likely necessary.

               

              Rick. 

              • 4. Re: A possible solution to Filemaker printing problems
                RickWhitelaw
                  

                DeltaTango,

                 

                The "Save Records as PDF" step takes care of the "current record/records being browsed" issue, which is probably the only reason for saving as pdf. The PDF issue also necessitates the setting up of the "page-ranges" variable, since saving to pdf from a record containing a series of portals will save all pages of the layout to the pdf, and you don't want to print empty pages. You never see the pdf because it only exists for a brief instant, but using the debugger it's possible to pause and view the "temp" pdf. 

                 

                RW