==================================================================
     A COLLECTION OF ENTRY/EXIT PROCEDURES
     ==================================================================
     PRODUCT :  R:BASE                  VERSION    :  3.1 AND UP
     CATEGORY:  FORMS                   SUBCATEGORY:  PROGRAMMING, EEPS
     ==================================================================
 
 
     EEPs (field entry/exit procedures) are an easy way to increase the
     power and capabilities of your forms. You simply write an R:BASE command
     file and then tell the form through the Field Settings screen to run
     that program when you enter or exit the field.
 
     R:BASE suspends operation of the form when an EEP is run, so the EEP
     doesn't know anything about data you have entered into columns on the
     form. For the EEP to know about data from the form, you need to put that
     data into variables in the form, either by locating the variables or by
     using expressions.
 
     The EEPs shown below, drawn from Microrim Technical Support files,
     demonstrate many different techniques you can use in your  applications
     and illustrate the wide variety of features you can add to your forms.
 
 
     Conditional Multi-Column Pop-up Menu
     ====================================
 
     Single-column popups are easy to do with the Field Settings menu you
     can make them automatic or use the  Shift-F3 key to bring up the menu
     only when you want it. Chapter 11 of the R:BASE Users Manual has an
     example of how to use an EEP to do a multi-column popup. It's an entry
     procedure, which comes up automatically when you enter the field. What
     if you want a multi-column popup that comes up only when you press a
     key, a conditional popup like the single-column ones?
 
     You can leave a field in a form in three ways: TAB, ENTER, and F2.
     Typically, only ENTER or TAB are used to leave a field. F2, then,
     makes a perfect key for testing in an EEP to see whether the user
     wants to display the menu (remember, EEPs execute only as you enter
     or exit a field). Create the multi-column popup EEP , but make it an
     EXIT EEP instead of an ENTRY EEP. Then at the beginning of the EEP,
     use the LASTKEY function to trap the key used to exit the field. If
     that key is F2, display the popup; otherwise, return to the form to
     the next field. Include a help line in the Field Settings to tell the
     user to press F2 to display the menu.
 
     Locate a variable (VMODEL) on the form, assign the EXIT EEP to the
     variable field, and use a form expression to store the value to the
     table (MODEL=.VMODEL). Because a variable is located, the field retains
     its value from row to row unless you assign it a default value. This
     example uses a text variable and sets the default value in the Field
     Settings to _ (underscore).
 
     *( -- POPUP.EEP -- )
     *( -- Exit procedure to do a conditional multi-column popup menu-- )
     SET MESSAGES OFF
     SET ERROR MESSAGES OFF
     *( -- Check the key used to exit the field -- )
     SET VAR vkey=(LASTKEY(0)),vmodel TEXT
     *( -- If the user left the field with Enter or Tab, don't display
           the menu, just return to the form             --  )
     IF vkey < > '[F2]' THEN
       RETURN
     ENDIF
     *(  --  If user presses F2, display the menu  -- )
     CHOOSE vmodel FROM #VALUES FOR (LJS(model,8)+prodname+','+proddesc) +
      FROM  product AT 10,5
     *(  --  If user doesn't choose anything from the menu, set variable
             to default value and return to the form             --  )
     IF vmodel = '[Esc]' THEN
       SET VAR vmodel = '_'
     ENDIF
     RECALC
     RETURN
 
 
     Zoom Box for Editing Text and Note Fields
     =========================================
 
     Forms often don't have enough room on the page to fully locate a text
     or note field. You  end up locating a few lines and then can scroll
     through the field, but that's not enough space in which to edit the
     data easily. This exit procedure allows you to press the F2 key and
     display a zoom box on the screen for editing just as you can do when
     editing through the Info screen.
 
     You'll need a help line on the field, "Press F2 for ZOOM edit". Then
     add these two form expressions if the field is text:
 
     VCALLNOTE = CALLNOTE
     CALLNOTE=(.VCALLNOTE)
 
     Add these two expressions if the field to zoom is a note field:
 
     VCALLNOTE=CALLNOTE IN formtable WHERE indexcol=indexcol
     CALLNOTE=(.VCALLNOTE)
 
     Locate the field VCALLNOTE on the form (be sure it wraps at least 2
     lines) and assign the following as a exit procedure.
 
     *(  --  CALLZOOM.EEP  --  )
     *(  --  Exit procedure to display Zoom box for editing   --  )
     SET VAR vlastkey = (LASTKEY(0))
     IF vlastkey < > '[F2]' THEN
       RETURN
     ENDIF
     *(  --  Uses CLS to display a shadowed box on the screen   --  )
     CLS FROM 6,12 TO 21,72 BLACK
     CLS FROM 5,10 TO 20,70 CYAN
     CLS FROM 6,12 TO 19,12 GRAY
     WRITE 'Call Notes' AT 5 12 WHITE ON CYAN
     WRITE '[Esc] to abort' AT 5 54 LIGHT CYAN ON CYAN
     *(  --  Uses scrolling FILLIN box to edit the data. The third
             number, 1000, indicates the maximum number of characters
             to edit. Make this the length of your text field, longer
             if a note field.  --  )
     FILLIN vcallnote=55,14,1000 AT 6 13 EDIT BLACK ON GRAY
     SET VAR vlastkey=(LASTKEY(0))
     IF vlastkey = '[Esc]' THEN
       RETURN
     ENDIF
     RECALC
     RETURN
 
 
     Track Elapsed Time
     ==================
 
     As do many applications, on-line phone support systems need to track
     and record elapsed time. In the form you start the timer, enter
     information, and then stop the timer. To do this, use two entry EEPs:
     one to start the timer and one to stop it.
 
     In addition to the columns of information in the table, you need three
     columns to track the time: start_time TIME, stop_time TIME, and elapsed_
     time = (stop_time - start_time) INTEGER.
 
     The entry procedures create playback files that return the times to the
     form. In a multi-user system, unique playback files for each individual
     are needed. Capture the user's initials into the variable vINIT before
     starting the form and use that as the extension on the files.
 
     Locate the Start_Time column first on the form and run the EEP as an
     entry procedure on this field. The user is prompted to press F2 to start
     the timer. Then locate the other information to be entered so that while
     the timer is running, the data can be looked up and entered.
 
     To display the current elapsed time and stop the timer, use the EEP
     called STOPTIME below.This is an entry procedure on the Stop_Time
     field.
 
     *( --  STARTIME.EEP  --  )
     *( --  Starts the timer for tracking elapsed time.  It uses a
            temporary file called START.xxx where xxx is the  user's
            initials (VINIT).                                   --  )
     SET VAR vfill TEXT, vreturn TEXT
     LABEL retry
     CLS FROM 25 1 TO 25 79 CYAN
     WRITE 'PRESS [F2] TO START TIMER' AT 25 24 BLACK ON CYAN
     WRITE '[F2]' AT 25 30 BLACK ON CYAN BLINK
     *(  --  Traps the keystroke looking for [ESC] or [F2]   --  )
     FILLIN vfill=0 USING ' ' AT 25 50 CYAN
     SET VAR vstartit TIME = .#TIME
     *(  --  Improper keystroke pressed   --  )
     IF vfill IS NULL OR (vfill NE '[ESC]' AND vfill + NE '[F2]') THEN
       GOTO retry
     ENDIF
     *(  --  ESC leaves the form without adding a record  --  )
     IF vfill EQ '[ESC]' THEN
       SET VAR vreturn = (CHAR(0)+CHAR(92)+CHAR(0)+CHAR(18)+ +
        CHAR(13)+CHAR(0)+CHAR(95))
     ENDIF
     *(  --  F2 jumps to the next field starting the clock  --  )
     IF vfill EQ '[F2]' THEN
       SET VAR vreturn = (CHAR(0)+CHAR(92)+CTXT(.vSTARTIT)+CHAR(13)+ +
        CHAR(0)+CHAR(95))
     ENDIF
     SET VAR vfile TEXT = ('START.' + .vinit)
     OUTPUT &vfile
     SHOW VAR vreturn
     OUTPUT SCREEN
     PLAYBACK &vfile
     RETURN
 
     *(  --  STOPTIME.EEP  --  )
     *(  --  Checks for any key presses and stops the timer when
             a key is pressed. Uses a temporary file called STOP.xxx
             where xxx is the user's initials (VINIT)˙           --  )
     SET VAR vreturn TEXT
     CLS FROM 25 1 TO 25 79 CYAN
     WRITE 'PRESS [F2] TO STOP TIMER' AT 25 24 BLACK ON CYAN
     WRITE '[F2]' AT 25 30 BLACK ON CYAN BLINK
     *(  --  Loops until a BREAK is encountered   --  )
     WHILE #PI IS NOT NULL THEN
     *(  --  Checks to see if the buffer contains a keystroke   --  )
       SET VAR vcheck = (CHKKEY(0))
       IF vcheck = 1 THEN
     *(  --  If keystroke exists then grab the key  --  )
         SET VAR vkey = (GETKEY(0))
     *(  --  Stop timer if [F2] is pressed, otherwise, notify user of
             invalid key˙                                       --  )
         IF vkey = '[F2]' THEN
           SET VAR vendit = .#TIME
           BREAK
         ELSE
           CLS FROM 25 1 TO 25 79 CYAN
           WRITE 'Invalid Key ..... Press [F2] to stop timer' AT 25 16 +
            RED ON CYAN
           PAUSE FOR 1
           CLS FROM 25 1 TO 25 79 CYAN
           WRITE 'PRESS [F2] TO STOP TIMER' AT 25 24 BLACK ON CYAN
           WRITE '[F2]' AT 25 30 BLACK ON CYAN BLINK
         ENDIF
       ENDIF
     *(  --  Calculates and displays elapsed time. Variable VSTARTIT
             was set in EEP STARTIME         --  )
       SET VAR vdiff INTEGER=(.#TIME - .vstartit)
       SET VAR vtdiff TIME=(RTIME(0,0,.vdiff))
       WRITE 'ELAPSED TIME:',.vtdiff AT 24 10 WHITE ON BLUE
     ENDWHILE
     *(  --  Returns the ending time to the form    --  )
     SET VAR vreturn = (CHAR(0)+CHAR(92)+CTXT(.vendit)+CHAR(13)+
      CHAR(0)+CHAR(95))
     CLEAR VAR vdiff, vtdiff
     SET VAR vfile = ('STOP.' + .vinit)
     OUTPUT &vfile
     SHOW VAR vreturn
     OUTPUT SCREEN
     PLAYBACK &vfile
     RETURN>
 
 
     Conditional Next Row in a Region
     ================================
 
     When entering data in a region, pressing [Enter] on the last field 
     in a row takes you to the next row in a region, not to the menu. To 
     stop the form from automatically taking you to the next row in the 
     region, locate a dummy variable as the last field and then assign an 
     entry procedure to that field to prompt the user to add another row. 
     This prevents null rows being accidentally loaded to the table. If 
     the user answers negatively, the EEP automatically adds the current 
     row. If the user answers affirmatively, the EEP moves down to the 
     next row in the region.
 
     *(  --  MOREDATA.EEP  --  )
     *(  --  Prompts to enter another row in a region. Uses a 
             temporary file called DUMMY.xxx where xxx represents 
             user's initials VINT   -- 
     SET VAR vfill TEXT
     DIALOG 'Add Another Row? (ESC to return)'  vfill,vend,YES AT 5
     *(  --  if vEND equals ESC then return to the form  --  )
     IF vend = '[ESC]' THEN
     *(  --  Returns to the previous field on the form   --  )
       SKIP -1
       RETURN
     ENDIF
     IF vfill = 'YES' THEN
     *(  --  Goes to next row in the region that adds the current row  --  )
       SET VAR vreturn = (CHAR(0)+CHAR(92)+'Y'+CHAR(13)+CHAR(0)+CHAR(95))
     ELSE
     *(  --  Goes to add menu and executes first option  --)
       SET VAR vreturn = (CHAR(0)+CHAR(92)+'N'+CHAR(0)+CHAR(30)++
        CHAR(13)+CHAR(0)+CHAR(95))
     ENDIF
     SET VAR vfile TEXT = ('DUMMY.' + .vinit)
     OUTPUT &vfile
     SHOW VAR vreturn
     OUTPUT SCREEN
     PLAYBACK &vfile
     RETURN
 
 
     Extra Help in a Form
     ====================
 
     This EEP uses a variable location to place extra help text on your 
     form. You can use this to automatically display help for a field as 
     soon as the user moves onto that field. Locate the help varible on 
     the form immediately before the field you want to display help for. 
     The variable location (VEEPNOTE) must be wide enough to hold the 
     displayed message. The Field Settings must say YES to the question 
     "Can the user change the data displayed in the field?" even though 
     the cursor will not seem to land on the field. This is an entry 
     procedure on the variable VEEPNOTE.
 
     *(  --  XHELP.EEP  --  )
     *(  --  Displays extra help for fields in a form  --  )
     SET VAR vlkey = (LASTKEY(0))
     *(  --  The keys UP, LEFT, Shift-TAB mean that the user is moving 
             backwards through the form and the message will not be 
             displayed   -- )
     IF vlkey CONT 'u' OR vlkey CONT 'l' OR vlkey CONT 's' THEN
       SET VAR veepnote TEXT = '     '
       RECALC
     *(  --  Moves the cursor off the field in the direction
             the user is going  -- )
       SKIP -1
     ELSE
     *(  --  Displays the help message  --  )
       SET VAR veepnote TEXT = 'This is the message'
       RECALC
       SKIP 1
     ENDIF
     RETURN
 
 
     
     Conditional Default Value
     =========================
 
     This EEP sets a default value for a field, depending on the value 
     entered into a previous field. For example, a default freight 
     charge is displayed if the user answers "Y" to a "Charge Freight? 
     [Y/N]" question. The procedure is an entry procedure on the next 
     field (vFREIGHT). It sets a fixed default value or can look up the 
     default freight charge for the customer. Additionally, the EEP will 
     not change the freight when entered into by an up- or left-arrow or 
     a Shift-Tab. In other words, the user must be moving down through the
     form and not backward. You need a form expression to store the freight 
     amount back into the table: FREIGHT = .VFREIGHT
 
     *(  --  DEFAULT.EEP  --  )
     *(  --  Assigns a default value to a field based on data entered 
             in a previous field on the form            --  )
     SET VAR vlastkey = (LASTKEY(0))
     IF vlastkey = '[UP]' OR vlastkey='[SHIFT][TAB]' OR +
      vlastkey='[LEFT]' THEN
       SKIP TO vfreight
     ENDIF
     *(  --  If a default value is stored for each customer, use the 
             following command to retrieve it. The variable vcustid is 
             set to equal the custid in a form expression. --  )
     SELECT freight INTO vfreight IND vi1 FROM customer WHERE custid = +
      .vcustid
     *(  --  If a fixed default value is desired, use the following
             instead.  --  )
     SET VAR vfreight = 10.00
     *(  --  The freight value appears in the field, vfreight, and can 
             be overwritten by the user.  --  )
     RECALC
     RETURN
 
 
     Print from an EEP
     =================
     
     REPRINT.EEP is an exit procedure that allows printing reports from 
     inside a form. It uses the LASTKEY function to check a specific 
     keystroke (Alt-R in this case) to see whether the user wants to 
     print reports. If the user presses Alt-R, he or she is prompted to 
     verify that he or she wants to print a report. If the answer is YES, 
     the user is given a list of reports to print. Once a report is chosen, 
     another menu appears to give a choice of output devices. The EEP can 
     be placed on either a column or a variable.
 
     NOTE: This EEP requires the menu file PRNOUT.MNU.
 
     *(  --  REPRINT.EEP  --  )
     *(  --  Prompts the user for report to print while using a form.
             Requires the file prnout.mnu˙                       --  )
     SET VAR vkey = (LASTKEY(0))
     *(  --  If [ALT]R was not pressed, return to the form  --  )
     IF vkey << >> '[ALT]R' THEN
       RETURN
     ENDIF
     *(  --  Brings up menus of reports to print and verifies that the 
             user really wants to print something  --  )
     DIALOG 'Would you like this information printed ? ' vanswer vend +
      yes  AT 8
     *(  --  If the user does not want to print, returns to form  --  )
     IF vend = '[Esc]' OR vanswer = 'no' THEN
       RETURN
     ENDIF
     *(  --  Pick a report to print from the menu of reports  -- )
     CHOOSE vrept FROM #REPORTS AT 4,40
     *(  --  If don't choose a report then return to the form  --  )
     IF vrept = '[Esc]' THEN
       RETURN
     ENDIF
     CHOOSE voutput FROM prnout.mnu AT 4,55
     IF voutput = '[Esc]' THEN
       RETURN
     ENDIF
     IF voutput = 'FILE...' THEN
       SET VAR voutput = ' '
       DIALOG 'Enter filename:' voutput vresp 1
       IF vresp = '[Esc]' THEN
         RETURN
       ENDIF
     ELSE
       SET VAR voutput = 'LPT1'
     ENDIF
     CLS
     OUTPUT &voutput
     PRINT .vrept
     OUTPUT SCREEN
     WRITE '                       Print completed.               +
         ' at 24,1 gray on red
     PAUSE 1
     CLE VAR voutput, vrept
     RETURN
 
     File:  PRNOUT.MNU
     $MENU
     PRNOUT
     POPUP||
     |Printer|
     |File...|
     ENDC
 
 
     Add A Sixth Table to the Form
     =============================
 
     Forms are limited to five tables, but by using an EEP you can prompt 
     the user to enter data to be loaded into a sixth table. Assign the EEP 
     as an exit procedure on the last field of a table. Then the user will 
     be prompted to enter the values for the sixth table upon leaving that 
     field.
 
     *(  --  NEWTBL.EEP  --  )     
     *(  --  Adds extra tables to a form for data entry  --  )
     SET ERROR MESS OFF
     SET MESSAGES OFF
     SET VAR v1 TEXT
     CLS
     *(  --  Places an entry box on the screen and displays field 
             prompts. Alternatively, you can DISPLAY a file that has 
             the prompts in it  -- )
     CLS FROM 5 7 TO 20 75 BLACK
     CLS FROM 4 5 TO 19 75 RED
     WRITE '[Esc] to abort.' at 5 50 black on cyan
     WRITE 'First Name: ' AT 7 6 black ON red
     WRITE 'MI:' AT 7 32 black ON red
     WRITE '.' AT 7 37 black ON red
     WRITE 'Last name: ' At 7 40 black ON red
     WRITE 'Address: ' AT 8 6 black ON red
     WRITE 'Address: ' AT 9 6 black ON red
     WRITE 'Apt#: ' At 9 53 black ON red+
     WRITE 'Customer ID: ' AT 15 6 yellow ON + <_>black
     WRITE 'Phone: ' AT 15 26 yellow ON black
     WRITE '(   )' AT 15 33 yellow ON black
     WRITE '-' At 15 43 yellow ON black
     SET VAR vlast = (LASTKEY(0))
     IF vlast = '[ESC]' then
       RETURN
     ENDIF
     FILLIN vfname=13 USING  ' ' AT 7 18 black ON red
     FILLIN vmi=1 USING  ' ' AT 7 36 black ON red
     FILLIN vlname=15 USING ' ' AT 7 51 black ON red
     FILLIN vaddr1=35 USING ' ' At 8 15 black ON red
     FILLIN vaddr2=35 USING ' ' AT 9 15 black ON red
     FILLIN vapt#=5 USING  ' ' AT 9 59 black ON red
     FILLIN vcustid=5 USING ' ' AT 15 19 yellow ON black
     FILLIN varea=3 USING ' ' AT 15 34 yellow ON black
     FILLIN vprefix=3 USING ' ' AT 15 40 yellow ON black
     FILLIN vsuffix=4 USING ' ' AT 15 44 yellow ON black
     INSERT INTO customer + (fname,mi,lname,addr1,addr2,apt#,custid,+
      area, prefix,suffix) +
      VALUES (.vfname,.vmi,.vlname,.vaddr1,.vaddr2,.vapt#,.vcustid,+
       .varea, . vprefix,.vsuffix)
     RETURN