home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / busi / office1.zip / PERSONAL.MDL < prev    next >
Text File  |  1988-10-05  |  42KB  |  1,040 lines

  1. *GLOBAL*************************************************************************
  2.          INCLUDE('STD_KEYS.CLA')
  3.          INCLUDE('CTL_KEYS.CLA')
  4.          INCLUDE('ALT_KEYS.CLA')
  5.          INCLUDE('SHF_KEYS.CLA')
  6.  
  7. REJECT_KEY   EQUATE(CTRL_ESC)
  8. ACCEPT_KEY   EQUATE(CTRL_ENTER)
  9. TRUE         EQUATE(1)
  10. FALSE         EQUATE(0)
  11.  
  12.          MAP
  13.            @MODULES
  14.          .
  15.          EJECT('FILE LAYOUTS')
  16.          @FILE
  17.          EJECT('GLOBAL MEMORY VARIABLES')
  18. ACTION         SHORT                 !0 = NO ACTION
  19.                          !1 = ADD RECORD
  20.                          !2 = CHANGE RECORD
  21.                          !3 = DELETE RECORD
  22.                          !4 = LOOKUP FIELD
  23.          @MEMORY
  24.  
  25.          EJECT('CODE SECTION')
  26.   CODE
  27.   SETHUE(7,0)                     !SET WHITE ON BLACK
  28.   BLANK                         !  AND BLANK
  29.   SETHUE()                     !    THE SCREEN
  30.   HELP(@HELPFILE)                 !OPEN THE HELP FILE
  31.   @OPENFILES                     !OPEN OR CREATE FILES
  32.   @BASEPROC                     !CALL THE BASE PROCEDURE
  33.   RETURN                     !EXIT TO DOS
  34. *MENU***************************************************************************
  35. @PROCNAME    PROCEDURE
  36.  
  37. SCREEN         SCREEN      PRE(SCR),@SCREENOPT
  38.               @PAINTS
  39.               @STRINGS
  40.               @VARIABLES
  41.               ENTRY,USE(?FIRST_FIELD)
  42.               @FIELDS
  43.               MENU,USE(?MENU_FIELD),REQ
  44.                 @CHOICES
  45.          .          .
  46.  
  47.   EJECT
  48.   CODE
  49.   OPEN(SCREEN)                     !OPEN THE MENU SCREEN
  50.   SETCURSOR                     !TURN OFF ANY CURSOR
  51.   @SETUP                     !CALL SETUP PROCEDURE
  52.   LOOP                         !LOOP UNTIL USER EXITS
  53.     @LOOKUPS                     !DISPLAY FROM OTHER FILES
  54.     @SHOW                     !DISPLAY STRING VARIABLES
  55.     @COMPUTE                     !DISPLAY COMPUTED FIELDS
  56.     @RESULT                     !MOVE RESULTING VALUES
  57.     ALERT                     !TURN OFF ALL ALERTED KEYS
  58.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  59.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  60.     @ALERT                     !ALERT HOT KEYS
  61.     ACCEPT                     !READ A FIELD OR MENU CHOICE
  62.     @CHECKHOT                     !ON HOT KEY, CALL PROCEDURE
  63.     IF KEYCODE() = REJECT_KEY THEN RETURN.     !RETURN ON SCREEN REJECT
  64.  
  65.     EDIT_RANGE# = FIELD()             !SET ONE FIELD EDIT RANGE
  66.     IF KEYCODE() = ACCEPT_KEY             !ON SCREEN ACCEPT KEY
  67.       UPDATE                     !  MOVE ALL FIELDS FROM SCREEN
  68.       EDIT_RANGE# = ?MENU_FIELD - 1         !  AND EDIT REMAINING FIELDS
  69.       SELECT(?MENU_FIELD)             !  IF OK THEN START HERE NEXT
  70.     .                         !
  71.  
  72.     LOOP FIELD# = FIELD() TO EDIT_RANGE#     !EDIT FIELDS IN THE EDIT RANGE
  73.  
  74.       CASE FIELD#                 !JUMP TO FIELD EDIT ROUTINE
  75.       OF ?FIRST_FIELD                 !FROM THE FIRST FIELD
  76.     IF KEYCODE() = ESC_KEY THEN RETURN.     !  RETURN ON ESC KEY
  77.  
  78.       @EDITS                     !EDIT ROUTINES GO HERE
  79.       OF ?MENU_FIELD                 !FROM THE MENU FIELD
  80.     EXECUTE CHOICE()             !  CALL THE SELECTED PROCEDURE
  81.       @MENU                     !
  82.   . . . .
  83. *TABLE**************************************************************************
  84. @PROCNAME    PROCEDURE
  85.  
  86. SCREEN         SCREEN      PRE(SCR),@SCREENOPT
  87.               @PAINTS
  88.               @STRINGS
  89.               @VARIABLES
  90.               ENTRY,USE(?FIRST_FIELD)
  91.               @FIELDS
  92.               @PREPOINT
  93.               REPEAT(@COUNT),EVERY(@PROWS),INDEX(NDX)
  94.           @PLOC        POINT(@PROWS,@COLS),USE(?POINT),ESC(?-1)
  95.                 @SCROLLVARIABLES
  96.          .          .
  97.  
  98. NDX         BYTE                 !REPEAT INDEX FOR POINT FIELD
  99. ROW         BYTE                 !ACTUAL ROW OF SCROLL AREA
  100. COL         BYTE                 !ACTUAL COLUMN OF SCROLL AREA
  101. MAX         LONG                 !LESSER OF COUNT AND RECORDS
  102. COUNT         BYTE(@COUNT)             !NUMBER OF ITEMS TO SCROLL
  103. ROWS         BYTE(@ROWS)             !NUMBER OF ROWS TO SCROLL
  104. COLS         BYTE(@COLS)             !NUMBER OF COLUMNS TO SCROLL
  105.  
  106.   EJECT
  107.   CODE
  108.   ACTION# = ACTION                 !SAVE ACTION
  109.   OPEN(SCREEN)                     !OPEN THE SCREEN
  110.   SETCURSOR                     !TURN OFF ANY CURSOR
  111.   @SETUP                     !CALL SETUP PROCEDURE
  112.   NDX = 1                     !PUT SELECTOR BAR ON TOP ITEM
  113.   ROW = ROW(?POINT)                 !REMEMBER TOP ROW AND
  114.   COL = COL(?POINT)                 !  LEFT COLUMN OF SCROLL AREA
  115.   IF ACTION = 4                     !IF THIS IS A LOOKUP REQUEST
  116.     SET(@KEYNAME,@KEYNAME)             !  FIND IT IN THE FILE
  117.     NEXT(@FILENAME)                 !    AND READ IT
  118.     POINTER# = POINTER(@FILENAME)         !  SAVE POINTER TO CURRENT
  119.     SKIP(@FILENAME,-1)                 !  MAKE IT THE TOP RECORD
  120.     DO SHOW_TABLE                 !  FILL SCROLL AREA
  121.     GET(@FILENAME,POINTER#)             !  AND REFRESH CURRENT RECORD
  122.   ELSE                         !OTHERWISE
  123.     SET(@KEYNAME)                 !  SET TO FIRST RECORD IN FILE
  124.     DO SHOW_TABLE                 !  FILL SCROLL AREA
  125.   .
  126.   RECORDS# = TRUE                 !INITIALIZE RECORDS FLAG
  127.   LOOP                         !LOOP UNTIL USER EXITS
  128.     MAX = RECORDS(@KEYNAME)             !SET LESSER OF FILE RECORD
  129.     IF MAX > COUNT THEN MAX = COUNT.         !  COUNT AND SCROLL ITEM COUNT
  130.     ACTION = ACTION#                 !RESTORE ACTION
  131.     POINTER# = 0                 !CLEAR ADD POINTER
  132.     @LOOKUPS                     !DISPLAY FROM OTHER FILES
  133.     @SHOW                     !DISPLAY STRING VARIABLES
  134.     @COMPUTE                     !DISPLAY COMPUTED FIELDS
  135.     @RESULT                     !MOVE RESULTING VALUES
  136.     IF ~RECORDS(@KEYNAME)             !IF THERE ARE NO RECORDS
  137.       CLEAR(@PRE:RECORD)             !  CLEAR RECORD AREA
  138.       ACTION = 1                 !  SET ACTION TO ADD
  139.       @UPDATE                     !  CALL FORM FOR FIRST RECORD
  140.       IF ~RECORDS(@KEYNAME) THEN BREAK.         !  IF ADD ABORTED THEN EXIT
  141.       SET(@KEYNAME)                 !  SET TO NEW RECORD
  142.       DO SHOW_TABLE                 !  FILL SCROLL AREA
  143.       NDX = 1                     !  PUT SELECTOR BAR ON TOP ITEM
  144.       MAX = 1                     !  MAXIMUM DISPLAYED IS 1
  145.     .                         !
  146.     ALERT                     !RESET ALERTED KEYS
  147.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  148.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  149.     @ALERT                     !ALERT HOT KEY
  150.     ACCEPT                     !READ A FIELD
  151.     @TABLEHOT                     !ON HOT KEY, CALL PROCEDURE
  152.     IF KEYCODE() = REJECT_KEY THEN BREAK.     !RETURN ON SCREEN REJECT KEY
  153.  
  154.     EDIT_RANGE# = FIELD()             !SET ONE FIELD EDIT RANGE
  155.     IF KEYCODE() = ACCEPT_KEY             !ON SCREEN ACCEPT KEY
  156.       UPDATE                     !  MOVE ALL FIELDS FROM SCREEN
  157.       EDIT_RANGE# = ?POINT - 1             !  AND EDIT REMAINING FIELDS
  158.       SELECT(?POINT)                 !  IF OK THEN START HERE NEXT
  159.     .                         !
  160.  
  161.     LOOP FIELD# = FIELD() TO EDIT_RANGE#     !EDIT FIELDS IN THE EDIT RANGE
  162.  
  163.       CASE FIELD#                 !JUMP TO FIELD EDIT ROUTINE
  164.       OF ?FIRST_FIELD                 !FROM THE FIRST FIELD
  165.     IF KEYCODE() = ESC_KEY    OR |         !  RETURN ON ESC KEY
  166.        RECORDS# = FALSE             !  OR NO RECORDS
  167.          RETURN
  168.     .
  169.       @EDITS                     !EDIT ROUTINES GO HERE
  170.     RECORDS# = TRUE                 !  ASSUME RECORDS ARE HERE
  171.       @INITLOCATE                 !SHOW CURSOR FOR LOCATOR
  172.       OF ?POINT                     !FROM THE POINT FIELD
  173.     CASE KEYCODE()                 !  PROCESS THE KEYSTROKE
  174.  
  175.     OF INS_KEY                 !INSERT KEY
  176.       CLEAR(@PRE:RECORD)             !  CLEAR RECORD AREA
  177.       ACTION = 1                 !  SET ACTION TO ADD
  178.       @UPDATE                 !  CALL FORM FOR NEW RECORD
  179.       IF ~ACTION                 !  IF A NEW RECORD WAS ADDED
  180.         POINTER# = POINTER(@FILENAME)     !    REMEMBER WHICH RECORD
  181.         SET(@KEYNAME,@KEYNAME)         !    SET TO NEW RECORD AND
  182.         SKIP(@FILENAME,-1)             !    MAKE IT THE TOP ITEM
  183.         DO SHOW_TABLE             !    DISPLAY THAT PAGE
  184.       .
  185.     OF ENTER_KEY                 !ENTER KEY OR
  186.     OROF ACCEPT_KEY                 !CTRL ENTER KEY
  187.       DO GET_RECORD                 !  READ THE SELECTED RECORD
  188.       IF ACTION = 4                 !  IF THIS IS A LOOKUP REQUEST
  189.         ACTION = 0                 !    SET ACTION TO COMPLETE
  190.         RETURN                 !    AND RETURN TO CALLER
  191.       .                     !
  192.       ACTION = 2                 !  SET ACTION TO CHANGE
  193.       @UPDATE                 !  CALL FORM TO CHANGE RECORD
  194.       IF ~ACTION                 !  IF THE RECORD WAS CHANGED
  195.         POINTER# = POINTER(@FILENAME)     !    REMEMBER WHICH RECORD
  196.         SET(@KEYNAME,@KEYNAME)         !    SET TO CHANGED RECORD
  197.         SKIP(@FILENAME,-1)             !    MAKE IT THE TOP ITEM
  198.         DO SHOW_TABLE             !    AND DISPLAY THAT PAGE
  199.       ELSE                     !  OTHERWISE
  200.         SKIP(@FILENAME,(MAX-NDX))         !  SKIP BACK TO SAME PAGE
  201.       .
  202.     OF DEL_KEY                 !DELETE KEY
  203.       DO GET_RECORD                 !  READ THE SELECTED RECORD
  204.       ACTION = 3                 !  SET ACTION TO DELETE
  205.       @UPDATE                 !  CALL FORM TO DELETE RECORD
  206.       IF ~ACTION                 !  IF RECORD WAS DELETED
  207.         SKIP(@FILENAME,-NDX)         !    SET NEXT RECORD ON TOP
  208.         DO SHOW_TABLE             !    AND DISPLAY THAT PAGE
  209.       ELSE                     !  OTHERWISE
  210.         SKIP(@FILENAME,(MAX-NDX))         !  SKIP BACK TO SAME PAGE
  211.       .
  212.     OF DOWN_KEY                 !DOWN ARROW KEY
  213.       IF NOT EOF(@FILENAME)             !  IF THERE ARE MORE RECORDS
  214.         SCROLL(ROW,COL,ROWS,COLS,ROWS(?POINT)) !  SCROLL THE SCREEN UP
  215.         NEXT(@FILENAME)             !    READ THE BOTTOM RECORD
  216.         DO SHOW_RECORD             !    AND DISPLAY IT
  217.       .
  218.     OF PGDN_KEY                 !PAGE DOWN KEY
  219.       IF EOF(@FILENAME)             !  ON THE LAST PAGE
  220.         NDX = MAX                 !    POINT TO BOTTOM ITEM
  221.       ELSE                     !  OTHERWISE
  222.         DO SHOW_TABLE             !    DISPLAY NEXT PAGE
  223.       .
  224.     OF CTRL_PGDN                 !CTRL-PAGE DOWN KEY
  225.       NDX = MAX                 !  POINT TO BOTTOM ITEM
  226.       IF NOT EOF(@FILENAME)             !  ON THE LAST PAGE
  227.         SET(@KEYNAME)             !    SET TO BOTTOM RECORD MINUS
  228.         SKIP(@FILENAME,-COUNT)         !    ONE PAGE OF RECORDS
  229.         DO SHOW_TABLE             !    DISPLAY THE LAST PAGE
  230.       .
  231.     OF UP_KEY                 !UP ARROW KEY
  232.       SKIP(@FILENAME,-(COUNT-1))         !    SET TO TOP RECORD MINUS 1
  233.       IF NOT BOF(@FILENAME)             !  IF THERE IS A PRIOR RECORD
  234.         PREVIOUS(@FILENAME)             !     READ THE TOP RECORD
  235.         IF NOT ERROR()             !    IF READ A RECORD
  236.           SCROLL(ROW,COL,ROWS,COLS,-(ROWS(?POINT)))! SCROLL THE SCREEN DOWN
  237.           DO SHOW_RECORD             !     AND DISPLAY IT
  238.         ELSIF ERRORCODE() = 33         !    ELSIF RECORD NOT AVAILABLE
  239.           NEXT(@FILENAME)             !     RETRIEVE FIRST ONE
  240.       . .
  241.       SKIP(@FILENAME,COUNT-1)         !  SET RECORD FOR NEXT PAGE
  242.  
  243.     OF PGUP_KEY                 !PAGE UP KEY
  244.       SKIP(@FILENAME,-(COUNT-1))         !  SET TO TOP RECORD MINUS ONE
  245.       IF BOF(@FILENAME)             !  IF THERE IS NO PRIOR RECORD
  246.         NDX = 1                 !    THEN POINT TO TOP ITEM
  247.         SKIP(@FILENAME,COUNT-1)         !    SET RECORD FOR THIS PAGE
  248.       ELSE                     !  OTHERWISE
  249.         SKIP(@FILENAME,-(COUNT+1))         !    SET RECORD FOR PRIOR PAGE
  250.         DO SHOW_TABLE             !    AND DISPLAY THE PAGE
  251.       .
  252.     OF CTRL_PGUP                 !CTRL-PAGE UP KEY
  253.       SET(@KEYNAME)                 !  SET TO FIRST RECORD
  254.       NDX = 1                 !  POINT TO TOP ITEM
  255.       DO SHOW_TABLE                 !  AND DISPLAY THE PAGE
  256.     .
  257.     @LOCATE
  258.   . . .
  259.   RETURN                     !RETURN TO CALLER
  260.  
  261. SHOW_TABLE ROUTINE                 !DISPLAY A PAGE OF RECORDS
  262.   SKIP(@FILENAME,COUNT-1)             !  SET TO THE BOTTOM RECORD
  263.   IF EOF(@FILENAME)                 !  FOR A PARTIAL PAGE
  264.     SET(@KEYNAME)                 !    SET TO THE LAST RECORD
  265.     SKIP(@FILENAME,-COUNT)             !    AND BACK UP ONE PAGE
  266.   ELSE                         !  OTHERWISE
  267.     SKIP(@FILENAME,-(COUNT-1))             !    SET RECORD FOR THIS PAGE
  268.   .
  269.   NDX# = NDX                     !  SAVE REPEAT INDEX
  270.   LOOP NDX = 1 TO COUNT                 !  LOOP THRU THE SCROLL AREA
  271.     IF EOF(@FILENAME) THEN BREAK.         !    BREAK ON END OF FILE
  272.     NEXT(@FILENAME)                 !    READ THE NEXT RECORD
  273.     DO SHOW_RECORD                 !    AND DISPLAY IT
  274.     IF POINTER(@FILENAME) = POINTER# THEN NDX# = NDX.!POINT TO CORRECT RECORD
  275.   .
  276.   NDX = NDX#                     !  RESTORE REPEAT INDEX
  277.   CLEAR(@PRE:RECORD)                 !  CLEAR RECORD AREA
  278.   IF RECORDS(@KEYNAME) < COUNT             !  IF RECORDS DO NOT FILL
  279.      NDX#= RECORDS(@KEYNAME) * @PROWS         !     GET NUMBER TIMES SIZE
  280.      BLANK(ROW + NDX#,COL,ROWS-NDX#,COLS)     !     BLANK REMAINING AREA
  281.   .
  282.  
  283. SHOW_RECORD ROUTINE                 !DISPLAY A RECORD
  284.   @LOOKUPSCROLL                     !  DISPLAY FROM OTHER FILES
  285.   @SHOWSCROLL                     !  DISPLAY STRING VARIABLES
  286.   @COMPUTESCROLL                 !  DISPLAY COMPUTED FIELDS
  287.  
  288. GET_RECORD ROUTINE                 !READ SELECTED RECORD
  289.   SKIP(@FILENAME,-(MAX-NDX+1))             !  SET TO SELECTED RECORD
  290.   NEXT(@FILENAME)                 !    AND READ IT
  291.  
  292. FIND_RECORD ROUTINE                 !LOCATE REQUESTED RECORD
  293.   SET(@KEYNAME,@KEYNAME)             !  SET TO REQUESTED RECORD
  294.   IF EOF(@FILENAME)                 !  IF BEYOND END OF FILE
  295.     PREVIOUS(@FILENAME)                 !    GET THE LAST RECORD
  296.   ELSE                         !  ELSE
  297.     NEXT(@FILENAME)                 !    READ THIS RECORD
  298.   .
  299.   POINTER# = POINTER(@FILENAME)             !  SAVE ITS RECORD POINTER
  300.   SKIP(@FILENAME,-1)                 !  MAKE IT THE TOP RECORD
  301.   DO SHOW_TABLE                     !  AND FILL THE SCROLL AREA
  302.  
  303. SAME_PAGE ROUTINE                 !SET TO SAME PAGE ROUTINE
  304.   SKIP(@FILENAME,-NDX)                 !  SKIP TO TOP OF SAME PAGE
  305. *SELTABLE***********************************************************************
  306. @PROCNAME    PROCEDURE
  307.  
  308. SCREEN         SCREEN      PRE(SCR),@SCREENOPT
  309.               @PAINTS
  310.               @STRINGS
  311.               @VARIABLES
  312.               ENTRY,USE(?FIRST_FIELD)
  313.               @FIELDS
  314.               @PREPOINT
  315.               REPEAT(@COUNT),EVERY(@PROWS),INDEX(NDX)
  316.           @PLOC        POINT(@PROWS,@COLS),USE(?POINT),ESC(?-1)
  317.                 @SCROLLVARIABLES
  318.          .          .
  319.  
  320. PTR         LONG                 !ENTRY POINTER FOR KEY TABLE
  321. NDX         BYTE                 !REPEAT INDEX FOR POINT AREA
  322. ROW         BYTE                 !ACTUAL ROW OF SCROLL AREA
  323. COL         BYTE                 !ACTUAL COLUMN OF SCROLL AREA
  324. COUNT         BYTE(@COUNT)             !NUMBER OF ITEMS TO SCROLL
  325. ROWS         BYTE(@ROWS)             !NUMBER OF ROWS TO SCROLL
  326. COLS         BYTE(@COLS)             !NUMBER OF COLUMNS TO SCROLL
  327.  
  328. TABLE         TABLE                 !TABLE OF RECORD KEYS
  329. TBLPTR           LONG                 !  POINTER TO DATA RECORD
  330. KEY           GROUP,PRE(TBL)             !  RECORD KEY FIELDS
  331.          @COMPONENTS
  332.          . .
  333. @SAVEITEMS
  334.  
  335.   EJECT
  336.   CODE
  337.   ACTION# = ACTION                 !SAVE ACTION
  338.   OPEN(SCREEN)                     !OPEN THE SCREEN
  339.   SETCURSOR                     !TURN OFF ANY CURSOR
  340.   @SETUP                     !CALL SETUP PROCEDURE
  341.   @INITSELECTS                     !SAVE SELECTOR FIELDS
  342.   PTR = 1                     !START AT TABLE ENTRY
  343.   NDX = 1                     !PUT SELECTOR BAR ON TOP ITEM
  344.   ROW = ROW(?POINT)                 !REMEMBER TOP ROW AND
  345.   COL = COL(?POINT)                 !LEFT COLUMN OF SCROLL AREA
  346.   RECORDS# = TRUE                 !INITIALIZE RECORDS FLAG
  347.   LOOP                         !LOOP UNTIL USER EXITS
  348.     ACTION = ACTION#                 !RESTORE ACTION
  349.     @RESTSELECTS                 !RESTORE SELECTOR FIELDS
  350.     @LOOKUPS                     !DISPLAY FROM OTHER FILES
  351.     @SHOW                     !DISPLAY STRING VARIABLES
  352.     @COMPUTE                     !DISPLAY COMPUTED FIELDS
  353.     @RESULT                     !MOVE RESULTING VALUES
  354.     ALERT                     !RESET ALERTED KEYS
  355.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  356.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  357.     @ALERT                     !ALERT HOT KEY
  358.     ACCEPT                     !READ A FIELD
  359.     MEM:MESSAGE = ''                 !CLEAR MESSAGE AREA
  360.     @TABLEHOT                     !ON HOT KEY, CALL PROCEDURE
  361.     IF KEYCODE() = REJECT_KEY THEN BREAK.     !RETURN ON SCREEN REJECT KEY
  362.  
  363.     EDIT_RANGE# = FIELD()             !SET ONE FIELD EDIT RANGE
  364.     IF KEYCODE() = ACCEPT_KEY             !ON SCREEN ACCEPT KEY
  365.       UPDATE                     !  MOVE ALL FIELDS FROM SCREEN
  366.       EDIT_RANGE# = ?POINT - 1             !  AND EDIT REMAINING FIELDS
  367.       SELECT(?POINT)                 !  IF OK THEN START HERE NEXT
  368.     .                         !
  369.  
  370.     LOOP FIELD# = FIELD() TO EDIT_RANGE#     !EDIT FIELDS IN THE EDIT RANGE
  371.  
  372.       CASE FIELD#                 !JUMP TO FIELD EDIT ROUTINE
  373.  
  374.       OF ?FIRST_FIELD                 !FROM THE FIRST FIELD
  375.     IF KEYCODE() = ESC_KEY OR |         !  RETURN ON ESC KEY
  376.        RECORDS# = FALSE             !  OR NO RECORDS
  377.          FREE(TABLE)             !  FREE THE TABLE OF POINTS
  378.          RETURN                 !  RETURN TO CALLER
  379.     .
  380.       @EDITS                     !EDIT ROUTINES GO HERE
  381.     RECORDS# = TRUE                 !  ASSUME THERE ARE RECORDS
  382.       @INITLOCATE
  383.       OF ?POINT                     !PROCESS THE POINT FIELD
  384.     IF ~RECORDS(TABLE)             !IF THERE ARE NO RECORDS
  385.       CLEAR(@PRE:RECORD)             !  CLEAR RECORD AREA
  386.       UPDATE                 !  UPDATE ALL FIELDS
  387.       ACTION = 1                 !  SET ACTION TO ADD
  388.       @UPDATE                 !  CALL FORM FOR FIRST RECORD
  389.       IF ~ACTION                 !  IF RECORD WAS ADDED
  390.         DO ADD_TABLE             !    THEN ADD NEW TABLE ENTRY
  391.         DO SORT_TABLE             !    SORT THE TABLE
  392.         DO SHOW_TABLE             !    AND DISPLAY FIRST PAGE
  393.       .
  394.       IF ~RECORDS(TABLE)             !  IF ADD ABORTED TRY AGAIN
  395.           RECORDS# = FALSE             !    INDICATE NO RECORDS
  396.           SELECT(?-1)             !    SELECT PREVIOUS FIELD
  397.           BREAK                 !    END THE EDITS
  398.       .
  399.       CYCLE                     !  CONTINUE THE EDIT
  400.     .
  401.     CASE KEYCODE()                 !PROCESS THE KEYSTROKE
  402.  
  403.     OF ENTER_KEY                 !ENTER KEY OR
  404.     OROF ACCEPT_KEY                 !CTRL-ENTER KEY
  405.       DO GET_RECORD                 !  READ THE SELECTED RECORD
  406.       IF ERROR()                 !  IF RECORD HAS BEEN DELETED
  407.         MEM:MESSAGE = ERROR()         !    TELL USER WHAT HAPPENED
  408.         SELECT(?)                 !    STAY IN THE POINT FIELD
  409.         DO BUILD_TABLE             !    REBUILD TABLE
  410.         DO SORT_TABLE             !    SORT IT
  411.         DO SHOW_TABLE             !    SHOW IT
  412.         BREAK                 !    AND GET ANOTHER KEY
  413.       .
  414.       IF ACTION = 4                 !  IF THIS IS A LOOKUP REQUEST
  415.         ACTION = 0                 !    SET ACTION TO COMPLETE
  416.         FREE(TABLE)                 !    FREE THE TABLE OF POINTS
  417.         RETURN                 !    RETURN TO CALLER
  418.       .
  419.       ACTION = 2                 !  SET ACTION TO CHANGE
  420.       @UPDATE                 !  CALL FORM TO CHANGE RECORD
  421.       IF ~ACTION                 !  IF THE RECORD WAS CHANGED
  422.         DELETE(TABLE)             !    DELETE OLD TABLE ENTRY
  423.         DO ADD_TABLE             !    ADD NEW TABLE ENTRY
  424.         DO SORT_TABLE             !    SORT THE TABLE
  425.         DO SHOW_TABLE             !    AND DISPLAY THAT PAGE
  426.       .
  427.     OF INS_KEY                 !INS KEY
  428.       CLEAR(@PRE:RECORD)             !  CLEAR RECORD AREA
  429.       UPDATE                 !  UPDATE ALL FIELDS
  430.       ACTION = 1                 !  SET ACTION TO ADD
  431.       @UPDATE                 !  CALL FORM FOR NEW RECORD
  432.       IF ~ACTION                 !  IF RECORD WAS ADDED
  433.         DO ADD_TABLE             !    ADD NEW TABLE ENTRY
  434.         DO SORT_TABLE             !    SORT THE TABLE
  435.         DO SHOW_TABLE             !    AND DISPLAY THAT PAGE
  436.       .
  437.     OF DEL_KEY                 !DEL KEY
  438.       DO GET_RECORD                 !  READ THE SELECTED RECORD
  439.       IF ERROR()                 !  IF RECORD HAS BEEN DELETED
  440.         MEM:MESSAGE = ERROR()         !    TELL USER WHAT HAPPENED
  441.         SELECT(?)                 !    STAY ON THE POINT FIELD
  442.         DO BUILD_TABLE             !    REBUILD TABLE
  443.         DO SORT_TABLE             !    SORT IT
  444.         DO SHOW_TABLE             !    SHOW IT
  445.         BREAK                 !    AND GET ANOTHER KEY
  446.       .
  447.       ACTION = 3                 !  SET ACTION TO DELETE
  448.       @UPDATE                 !  CALL FORM TO DELETE RECORD
  449.       IF ~ACTION                 !  IF RECORD WAS DELETED
  450.         DELETE(TABLE)             !    DELETE TABLE ENTRY
  451.         DO SHOW_TABLE             !    AND DISPLAY THAT PAGE
  452.       .
  453.     OF DOWN_KEY                 !DOWN ARROW KEY
  454.       IF PTR <= RECORDS(TABLE)-COUNT     !  IF THERE ARE MORE ENTRIES
  455.         SCROLL(ROW,COL,ROWS,COLS,ROWS(?POINT)) !  SCROLL THE SCREEN UP
  456.         PTR += 1                 !    SET TO THE NEXT ENTRY
  457.         DO SHOW_RECORD             !    AND DISPLAY THE RECORD
  458.       .
  459.     OF PGDN_KEY                 !PAGE DOWN KEY
  460.       IF PTR >= RECORDS(TABLE)-COUNT+1     !  ON THE LAST PAGE
  461.         NDX = COUNT.             !    POINT TO BOTTOM ITEM
  462.       PTR += COUNT                 !  OTHERWISE
  463.       TBLPTR = -1                 !  NOT SET TO A RECORD
  464.       DO SHOW_TABLE                 !    DISPLAY THE NEXT PAGE
  465.  
  466.     OF CTRL_PGDN                 !CTRL-PAGE DOWN KEY
  467.       PTR = RECORDS(TABLE) - COUNT + 1     !  SET TO LAST PAGE
  468.       NDX = COUNT                 !  POINT TO BOTTOM ITEM
  469.       TBLPTR = -1                 !  NOT SET TO A RECORD
  470.       DO SHOW_TABLE                 !  DISPLAY THE LAST PAGE
  471.  
  472.     OF UP_KEY                 !UP ARROW KEY
  473.       IF PTR > 1                 !  IF THERE IS A PRIOR RECORD
  474.         PTR -= 1                 !    SET TO PRIOR RECORD
  475.         SCROLL(ROW,COL,ROWS,COLS,-(ROWS(?POINT)))! SCROLL THE SCREEN DOWN
  476.         DO SHOW_RECORD             !    DISPLAY THE RECORD
  477.       .
  478.     OF PGUP_KEY                 !PAGE UP KEY
  479.       IF PTR = 1 THEN NDX = 1.         !  ON FIRST PAGE POINT TO TOP
  480.       PTR -= ROWS                 !  OTHERWISE BACK UP 1 PAGE
  481.       TBLPTR = -1                 !  NOT SET TO A RECORD
  482.       DO SHOW_TABLE                 !  AND DISPLAY IT
  483.  
  484.     OF CTRL_PGUP                 !CTRL-PAGE UP
  485.       PTR = 1                 !  POINT TO FIRST RECORD
  486.       NDX = 1                 !  POINT TO TOP ITEM
  487.       TBLPTR = -1                 !  NOT SET TO A RECORD
  488.       DO SHOW_TABLE                 !  AND DISPLAY THE FIRST PAGE
  489.     .
  490.     @LOCATE
  491.   . . .                         !
  492.  
  493.   FREE(TABLE)                     !FREE MEMORY TABLE
  494.   RETURN                     !AND RETURN TO CALLER
  495.  
  496. BUILD_TABLE ROUTINE                 !BUILD MEMORY TABLE
  497.   FREE(TABLE)                     !EMPTY THE TABLE
  498.   @READTABLE                     !DO SELECTOR OR FILTER
  499.   TBLPTR = -1                     !INITIALIZE TO NO RECORD
  500.   DO SHOW_TABLE                     !DISPLAY A PAGE OF RECORDS
  501.  
  502. ADD_TABLE ROUTINE                 !ADD ENTRY TO MEMORY TABLE
  503.   @CHECKADD                     !
  504.   IF ~(@FILTER) THEN EXIT.             !  EXIT IF FILTERED OUT
  505.   @SETCOMPONENTS                 !  MOVE KEY COMPONENTS
  506.   TBLPTR = POINTER(@FILENAME)             !  SAVE DATA RECORD POINTER
  507.   ADD(TABLE)                     !  ADD NEW TABLE ENTRY
  508.   IF ERROR()                     !  IF OUT OF MEMORY
  509.     MEM:MESSAGE = ERROR()             !    INFORM USER
  510.     BEEP                     !    SOUND ALARM
  511.   .
  512. SORT_TABLE ROUTINE                 !SORT TABLE ENTRIES
  513.   TBLPTR# = TBLPTR                 !  SAVE DATA RECORD POINTER
  514.   @SORTTABLE                     !  SORT THE TABLE
  515.   LOOP PTR = 1 TO RECORDS(TABLE)         !  LOOK UP THE SAVED POINTER
  516.     GET(TABLE,PTR)                 !    SO WE WILL STILL POINT
  517.     IF TBLPTR = TBLPTR# THEN EXIT.         !    AT THE SAME RECORD
  518.   .
  519.  
  520. SHOW_TABLE ROUTINE                 !DISPLAY A PAGE OF RECORDS
  521.   IF PTR > RECORDS(TABLE)-COUNT+1         !  FOR A PARTIAL PAGE
  522.     PTR = RECORDS(TABLE)-COUNT+1.         !    SET TO THE LAST RECORD
  523.   IF PTR < 1 THEN PTR = 1.             !    AND BACK UP ONE PAGE
  524.   TBLPTR# = TBLPTR                 !  SAVE DATA RECORD POINTER
  525.   NDX# = NDX                     !  SAVE REPEAT INDEX
  526.   LOOP NDX = 1 TO COUNT                 !  LOOP THRU THE SCROLL AREA
  527.     DO SHOW_RECORD                 !    DISPLAY A RECORD
  528.     IF TBLPTR# = TBLPTR THEN NDX# = NDX.     !    POINT TO CORRECT RECORD
  529.   .                         !
  530.   NDX = NDX#                     !  RESTORE REPEAT INDEX
  531.   IF NDX > RECORDS(TABLE) THEN NDX = RECORDS(TABLE).!SHOWING THE LAST
  532.   CLEAR(@PRE:RECORD)                 !  CLEAR RECORD AREA
  533.   IF RECORDS(TABLE) < COUNT             !  IF RECORDS DO NOT FILL
  534.      NDX#= RECORDS(TABLE) * @PROWS         !     GET NUMBER TIMES SIZE
  535.      BLANK(ROW + NDX#,COL,ROWS-NDX#,COLS)     !     BLANK REMAINING AREA
  536.   .
  537.  
  538. SHOW_RECORD ROUTINE                 !DISPLAY A RECORD
  539.   TBLPTR = 0                     !  START WITH NO RECORD
  540.   GET(TABLE,PTR+NDX-1)                 !  GET THE TABLE ENTRY
  541.   IF ~ERROR()                     !  IF THERE IS ONE
  542.     GET(@FILENAME,TBLPTR)             !    READ A DATA RECORD
  543.     IF ~ERROR()
  544.       @RESTSELECTS                 !    RESTORE SELECTOR FIELDS
  545.       @LOOKUPSCROLL                 !    DISPLAY FROM OTHER FILES
  546.       @SHOWSCROLL                 !    DISPLAY STRING VARIABLES
  547.       @COMPUTESCROLL                 !    DISPLAY COMPUTED FIELDS
  548.   . .
  549.  
  550. GET_RECORD ROUTINE                 !READ SELECTED RECORD
  551.   GET(TABLE,PTR+NDX-1)                 !  GET THE TABLE ENTRY
  552.   GET(@FILENAME,TBLPTR)                 !  READ THE DATA RECORD
  553.  
  554. FIND_RECORD ROUTINE                 !LOCATE REQUESTED RECORD
  555.   @SETCOMPONENTS                 !  MOVE THEM TO THE TABLE
  556.   GET(TABLE,KEY)                 !  GET THE TABLE ENTRY
  557.   PTR = POINTER(TABLE)                 !  SET RECORD POINTER
  558.   IF ~PTR THEN PTR = RECORDS(TABLE).         !  SET TO LAST IF NO POINTER
  559.   GET(TABLE,PTR)                 !  AND READ THE DATA RECORD
  560.   DO SHOW_TABLE                     !  DISPLAY THAT PAGE
  561.  
  562. SAME_PAGE ROUTINE                 !SET TO SAME PAGE ROUTINE
  563.   DO SORT_TABLE                     !  SORT THE TABLE
  564. *FORM***************************************************************************
  565. @PROCNAME    PROCEDURE
  566.  
  567. SCREEN         SCREEN      PRE(SCR),@SCREENOPT
  568.               @PAINTS
  569.               @STRINGS
  570.               @VARIABLES
  571.               ENTRY,USE(?FIRST_FIELD)
  572.               @FIELDS
  573.               @PAUSE
  574.               ENTRY,USE(?LAST_FIELD)
  575.               PAUSE(''),USE(?DELETE_FIELD)
  576.          .
  577.  
  578.   EJECT
  579.   CODE
  580.   OPEN(SCREEN)                     !OPEN THE SCREEN
  581.   SETCURSOR                     !TURN OFF ANY CURSOR
  582.   @SETUP                     !CALL SETUP PROCEDURE
  583.   DISPLAY                     !DISPLAY THE FIELDS
  584.   EXECUTE ACTION                 !SET THE CURRENT RECORD POINTER
  585.     POINTER# = 0                 !  NO RECORD FOR ADD
  586.     POINTER# = POINTER(@FILENAME)         !  CURRENT RECORD FOR CHANGE
  587.   .
  588.   LOOP                         !LOOP THRU ALL THE FIELDS
  589.     MEM:MESSAGE = CENTER(MEM:MESSAGE,SIZE(MEM:MESSAGE)) !DISPLAY ACTION MESSAGE
  590.     @LOOKUPS                     !DISPLAY FROM OTHER FILES
  591.     @SHOW                     !DISPLAY STRING VARIABLES
  592.     @COMPUTE                     !DISPLAY COMPUTED FIELDS
  593.     @RESULT                     !MOVE RESULTING VALUES
  594.     ALERT                     !RESET ALERTED KEYS
  595.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  596.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  597.     @ALERT                     !ALERT HOT KEY
  598.     ACCEPT                     !READ A FIELD
  599.     @CHECKHOT                     !ON HOT KEY, CALL PROCEDURE
  600.     IF KEYCODE() = REJECT_KEY THEN RETURN.     !RETURN ON SCREEN REJECT KEY
  601.     EXECUTE ACTION                 !SET ACTION MESSAGE
  602.       MEM:MESSAGE = 'Record will be Added'     !
  603.       MEM:MESSAGE = 'Record will be Changed'     !
  604.       MEM:MESSAGE = 'Press Enter to Delete'     !
  605.     .
  606.     EDIT_RANGE# = FIELD()             !SET ONE FIELD EDIT RANGE
  607.     IF KEYCODE() = ACCEPT_KEY             !ON SCREEN ACCEPT KEY
  608.       UPDATE                     !  MOVE ALL FIELDS FROM SCREEN
  609.       EDIT_RANGE# = FIELDS()             !  AND EDIT REMAINING FIELDS
  610.     .                         !
  611.     LOOP FIELD# = FIELD() TO EDIT_RANGE#     !EDIT FIELDS IN THE EDIT RANGE
  612.       CASE FIELD#                 !JUMP TO FIELD EDIT ROUTINE
  613.       OF ?FIRST_FIELD                 !FROM THE FIRST FIELD
  614.     IF KEYCODE() = ESC_KEY THEN RETURN.     !  RETURN ON ESC KEY
  615.     IF ACTION = 3 THEN SELECT(?DELETE_FIELD).!  OR CONFIRM FOR DELETE
  616.  
  617.       @EDITS                     !EDIT ROUTINES GO HERE
  618.       OF ?LAST_FIELD                 !FROM THE LAST FIELD
  619.     EXECUTE ACTION                 !  UPDATE THE FILE
  620.       ADD(@FILENAME)             !    ADD NEW RECORD
  621.       PUT(@FILENAME)             !    CHANGE EXISTING RECORD
  622.       DELETE(@FILENAME)             !    DELETE EXISTING RECORD
  623.     .
  624.     IF ERROR() THEN STOP(ERROR()).         !  CHECK FOR UNEXPECTED ERROR
  625.     PUT(@FILENAME2)                 !  UPDATE SECONDARY FILES
  626.     PUT(@FILENAME3)                 !  UPDATE SECONDARY FILES
  627.     PUT(@FILENAME4)                 !  UPDATE SECONDARY FILES
  628.     @NEXTFORM                 !  CALL NEXT FORM PROCEDURE
  629.     ACTION = 0                 !  SET ACTION TO COMPLETE
  630.     RETURN                     !  AND RETURN TO CALLER
  631.  
  632.       OF ?DELETE_FIELD                 !FROM THE DELETE FIELD
  633.     IF KEYCODE() = ENTER_KEY |         !  ON ENTER KEY
  634.     OR KEYCODE() = ACCEPT_KEY         !  OR CTRL-ENTER KEY
  635.       SELECT(?LAST_FIELD)             !    DELETE THE RECORD
  636.     ELSE                     !  OTHERWISE
  637.       BEEP                     !    BEEP AND ASK AGAIN
  638.   . . . .
  639.  
  640. *MEMFORM************************************************************************
  641. @PROCNAME    PROCEDURE
  642.  
  643. SCREEN         SCREEN      PRE(SCR),@SCREENOPT
  644.               @PAINTS
  645.               @STRINGS
  646.               @VARIABLES
  647.               ENTRY,USE(?FIRST_FIELD)
  648.               @FIELDS
  649.               @PAUSE
  650.               ENTRY,USE(?LAST_FIELD)
  651.          .
  652.  
  653.   EJECT
  654.   CODE
  655.   OPEN(SCREEN)                     !OPEN THE SCREEN
  656.   SETCURSOR                     !TURN OFF ANY CURSOR
  657.   @SETUP                     !CALL SETUP PROCEDURE
  658.   DISPLAY                     !DISPLAY THE FIELDS
  659.   LOOP                         !LOOP THRU ALL THE FIELDS
  660.     @LOOKUPS                     !DISPLAY FROM OTHER FILES
  661.     @SHOW                     !DISPLAY STRING VARIABLES
  662.     @COMPUTE                     !DISPLAY COMPUTED FIELDS
  663.     @RESULT                     !MOVE RESULTING VALUES
  664.     ALERT                     !RESET ALERTED KEYS
  665.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  666.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  667.     @ALERT                     !ALERT HOT KEY
  668.     ACCEPT                     !READ A FIELD
  669.     @CHECKHOT                     !ON HOT KEY, CALL PROCEDURE
  670.     IF KEYCODE() = REJECT_KEY THEN RETURN.     !RETURN ON SCREEN REJECT KEY
  671.     EDIT_RANGE# = FIELD()             !SET ONE FIELD EDIT RANGE
  672.     IF KEYCODE() = ACCEPT_KEY             !ON SCREEN ACCEPT KEY
  673.       UPDATE                     !  MOVE ALL FIELDS FROM SCREEN
  674.       EDIT_RANGE# = FIELDS()             !  AND EDIT REMAINING FIELDS
  675.     .                         !
  676.     LOOP FIELD# = FIELD() TO EDIT_RANGE#     !EDIT FIELDS IN THE EDIT RANGE
  677.       CASE FIELD#                 !JUMP TO FIELD EDIT ROUTINE
  678.       OF ?FIRST_FIELD                 !FROM THE FIRST FIELD
  679.     IF KEYCODE() = ESC_KEY THEN RETURN.     !  RETURN ON ESC KEY
  680.  
  681.       @EDITS                     !EDIT ROUTINES GO HERE
  682.       OF ?LAST_FIELD                 !FROM THE LAST FIELD
  683.     PUT(@FILENAME2)                 !  UPDATE SECONDARY FILES
  684.     PUT(@FILENAME3)                 !  UPDATE SECONDARY FILES
  685.     PUT(@FILENAME4)                 !  UPDATE SECONDARY FILES
  686.     @NEXTFORM                 !  CALL NEXT FORM PROCEDURE
  687.     ACTION = 0                 !  SET ACTION TO COMPLETE
  688.     RETURN                     !  AND RETURN TO CALLER
  689.   . . .
  690.  
  691. *REPORT*************************************************************************
  692.  
  693. @PROCNAME    PROCEDURE
  694.  
  695. REPORT         @REPORT
  696.  
  697. @SAVEITEMS
  698.  
  699.   CODE
  700.   DONE# = 0                     !TURN OFF DONE FLAG
  701.   @SETUP                     !CALL SETUP PROCEDURE
  702.   @INITSELECTS                     !SAVE SELECTOR FIELDS
  703.   BUILD(@INDEX)                     !BUILD FILE INDEX
  704.   @INITREPORT                     !INIT REPORT VARIABLES
  705.   @RPTHEADER                     !DO REPORT HEADER COMPUTES
  706.   PRINT(TTL:RPT_HEAD)                 !PRINT TITLE PAGE
  707.   @PRINTMEMO                     !PRINT ANY MEMO FILES
  708.   @SETFILE                     !SET TO FIRST RECORD
  709.   DO NEXT_RECORD                 !READ FIRST RECORD
  710.   OPEN(REPORT)                     !OPEN THE REPORT
  711.   LOOP UNTIL DONE#                 !READ ALL RECORDS IN FILE
  712.     @INITBREAK                     !  SET BREAK CRITERIA
  713.     @INITGROUP                     !  INIT GROUP VARIABLES
  714.     @GRPHEADER                     !  DO HEADER COMPUTES
  715.     PRINT(RPT:GRP_HEAD)                 !  PRINT GROUP HEADER
  716.     DO CHECK_PAGE                 !  DO PAGE BREAK IF NEEDED
  717.     @PRINTMEMO                     !  PRINT ANY MEMO FIELD
  718.  
  719.     LOOP UNTIL DONE#                 !  READ ALL RECORDS IN GROUP
  720.       SAVE_LINE# = MEM:LINE             !    SAVE LINE NUMBER
  721.       @RUNTOTALS                 !    ACCUMULATE RUNNING TOTALS
  722.       @INITDETAIL                 !    SET UP FOR DETAIL LINE
  723.       PRINT(RPT:DETAIL)                 !    PRINT DETAIL LINES
  724.       DO CHECK_PAGE                 !    DO PAGE BREAK IF NEEDED
  725.       @PRINTMEMO                 !    PRINT ANY MEMO FIELD
  726.       @TOTALS                     !    ACCUMULATE TOTALS
  727.       DO NEXT_RECORD                 !    GET NEXT RECORD
  728.       @CHECKBREAK                 !    EXIT ON NEW GROUP
  729.     .                         !
  730.     @GRPFOOTER                     !  DO FOOTER COMPUTES
  731.     PRINT(RPT:GRP_FOOT)                 !  PRINT GROUP FOOTER
  732.     DO CHECK_PAGE                 !  DO PAGE BREAK IF NEEDED
  733.     @PRINTMEMO                     !  PRINT ANY MEMO FIELD
  734.   .                         !
  735.   @RPTFOOTER                     !DO REPORT FOOTER COMPUTES
  736.   PRINT(RPT:RPT_FOOT)                 !PRINT GRAND TOTALS
  737.   DO CHECK_PAGE                     !  DO PAGE BREAK IF NEEDED
  738.   @PRINTMEMO                     !  PRINT ANY MEMO FIELD
  739.   CLOSE(REPORT)                     !CLOSE REPORT
  740.   RETURN                     !RETURN TO CALLER
  741.  
  742.  
  743. NEXT_RECORD ROUTINE                 !GET NEXT RECORD
  744.   LOOP UNTIL EOF(@FILENAME)             !  READ UNTIL END OF FILE
  745.     NEXT(@FILENAME)                 !    READ NEXT RECORD
  746.     @CHECKSELECT                 !    STOP IF PAST SELECTOR
  747.     @DETAIL                     !    DO DETAIL COMPUTES
  748.     IF ~(@FILTER) THEN CYCLE.             !    IF FILTERED OUT, GET NEXT
  749.     @PAGEHEADER                     !    DO PAGE HEADER COMPUTES
  750.     @PAGEFOOTER                     !    DO PAGE FOOTER COMPUTES
  751.     EXIT                     !    EXIT THE ROUTINE
  752.   .                         !
  753.   DONE# = 1                     !  ON EOF, SET DONE FLAG
  754.  
  755. CHECK_PAGE ROUTINE                 !CHECK FOR NEW PAGE
  756.   IF MEM:LINE <= SAVE_LINE#             !  ON PAGE OVERFLOW
  757.     @INITPAGE                     !    INIT PAGE VARIABLES
  758.   .
  759.  
  760. *MEMREPORT**********************************************************************
  761.  
  762. @PROCNAME    PROCEDURE
  763.  
  764. REPORT         @REPORT
  765.  
  766.   CODE
  767.   @SETUP                     !CALL SETUP PROCEDURE
  768.   @INITREPORT                     !INIT REPORT VARIABLES
  769.   @RPTHEADER                     !DO REPORT HEADER COMPUTES
  770.   PRINT(TTL:RPT_HEAD)                 !PRINT TITLE PAGE
  771.   OPEN(REPORT)                     !OPEN REPORT BODY
  772.   @INITGROUP                     !INIT GROUP VARIABLES
  773.   @GRPHEADER                     !DO HEADER COMPUTES
  774.   PRINT(RPT:GRP_HEAD)                 !PRINT GROUP HEADER
  775.   @MEMMEMO                     !PRINT ANY MEMO FIELD
  776.   @DETAIL                     !DO DETAIL COMPUTES
  777.   @RUNTOTALS                     !ACCUMULATE RUNNING TOTALS
  778.   @INITDETAIL                     !SET UP FOR DETAIL RECORD
  779.   PRINT(RPT:DETAIL)                 !PRINT DETAIL LINES
  780.   @MEMMEMO                     !PRINT ANY MEMO FIELD
  781.   @TOTALS                     !ACCUMULATE TOTALS
  782.   @GRPFOOTER                     !DO FOOTER COMPUTES
  783.   PRINT(RPT:GRP_FOOT)                 !PRINT GROUP FOOTER
  784.   @MEMMEMO                     !PRINT ANY MEMO FIELD
  785.   @RPTFOOTER                     !DO REPORT FOOTER COMPUTES
  786.   PRINT(RPT:RPT_FOOT)                 !PRINT REPORT FOOTER
  787.   @MEMMEMO                     !PRINT ANY MEMO FIELD
  788.   CLOSE(REPORT)                     !CLOSE REPORT
  789.   RETURN                     !RETURN TO CALLER
  790.  
  791. *PRINTMEMO**********************************************************************
  792.       @MEMOLEN                     !DETERMINE MEMO SIZE
  793.       J# = 2                     !START WITH SECOND ROW
  794.       LOOP                     !LOOP THRU ALL USED ROWS
  795.     MEMODONE# = 0                 !  NO MEMOS DONE YET
  796.     @SETMEMO                 !  SET THE MEMO VARIABLES
  797.     IF MEMODONE# = 0 THEN BREAK.         !  ALL MEMOS PRINTED
  798.     @PRTDETAIL                 !  AND PRINT IT
  799.     J# += 1                     !  INCREMENT COUNTER
  800.     DO CHECK_PAGE                 !  DO PAGE BREAK IF NEEDED
  801.       .
  802.       DO CHECK_PAGE                 !DO PAGE BREAK IF NEEDED
  803. *SETMEMO************************************************************************
  804.       IF J# <= @MEMOTMP#             !IF IN THE RANGE OF THIS MEMO
  805.           @MEMOVAR = @MEMOROW[J#]         !  MOVE A MEMO FIELD ROW
  806.           MEMODONE# = 1             !  MEMO HAS BEEN MOVED
  807.       ELSE                     !OTHERWISE
  808.           @MEMOVAR = ''             !  NO MEMO TO DO
  809.       .                     ! END OF SETMEMO
  810. *MEMOLEN************************************************************************
  811.       LOOP @MEMOTMP# = @MEMOSIZE TO 2 BY -1     !BACKSCAN THE MEMO FIELD TO
  812.     IF @MEMOROW[@MEMOTMP#] <> '' THEN BREAK. ! FIND NUMBER OF ROWS USED
  813.       .                         ! END OF MEMOLEN
  814. *PRTDETAIL**********************************************************************
  815.     PRINT(@MEMDETAIL)             !PRINT THE DETAIL RECORD
  816. *MEMMEMO************************************************************************
  817.   @MEMOLEN                     !DETERMINE MEMO SIZE
  818.   J# = 2                     !START WITH ROW 2
  819.   LOOP                         !LOOP THRU ALL USED ROWS
  820.     MEMODONE# = 0                 !  NO MEMOS DONE YET
  821.     @SETMEMO                     !  SET THE MEMO VARIABLES
  822.     IF MEMODONE# = 0 THEN BREAK.         !  ALL MEMOS PRINTED
  823.     @PRTDETAIL                     !  AND PRINT IT
  824.     J# += 1                     !  INCREMENT COUNTER
  825.   .
  826. *ALERT**************************************************************************
  827.     ALERT(@HOTKEY)                 !ALERT HOT KEY
  828. *TODO***************************************************************************
  829. @PROCNAME    PROCEDURE                 !THIS PROCEDURE IS NOT DEFINED
  830.  
  831.   CODE                         !
  832.   RETURN                     !RETURN TO CALLER
  833. *SHOWMEMO***********************************************************************
  834.     LOOP I# = 1 TO @MEMOROWS             !DISPLAY MEMO FIELD BY ROWS
  835.       SHOW(ROW(@SCRMEMO)+I#-1,COL(@SCRMEMO),@MEMOROW[I#],@S@MEMOCOLS)
  836.     .
  837. *INRANGE************************************************************************
  838.     IF ~INRANGE(@FIELD,@LOWER,@UPPER)     !IF FIELD IS OUT OF RANGE
  839.       BEEP                     !  SOUND KEYBOARD ALARM
  840.       SELECT(?@FIELD)             !  AND STAY ON THIS FIELD
  841.       BREAK                     !
  842.     .
  843. *REQUIRED***********************************************************************
  844.     IF @FIELD = ''                 !IF REQUIRED FIELD IS EMPTY
  845.       BEEP                     !  SOUND KEYBOARD ALARM
  846.       SELECT(?@FIELD)             !  AND STAY ON THIS FIELD
  847.       BREAK                     !
  848.     .
  849. *NOTREQUIRED********************************************************************
  850.     IF @FIELD = ''                 !IF NOT REQUIRED THEN
  851.       @EDITPROC                 !  CALL THE EDIT PROCEDURE
  852.       CYCLE                     !  END THE EDIT
  853.     .
  854. *UNIQUEKEY**********************************************************************
  855.     GET(@FILENAME,@ACCESSKEY)         !READ THE RECORD BY KEY
  856.     IF NOT ERROR()                 !IF A RECORD IS FOUND
  857.       IF POINTER(@FILENAME) <> POINTER#     !  BUT NOT THE SAME RECORD
  858.         CLEAR(@PRE:RECORD)             !    CLEAR IN CASE OF ADD
  859.         GET(@FILENAME,POINTER#)         !    RE-READ THE OLD RECORD
  860.         UPDATE                 !    RE-UPDATE THE RECORD
  861.         MEM:MESSAGE = 'CREATES DUPLICATE KEY'!    MOVE AN ERROR MESSAGE
  862.         SELECT(?@FIELD)             !    STAY ON THE SAME FIELD
  863.         BEEP                 !    SOUND THE KEYBOARD ALARM
  864.         BREAK                 !    AND LOOP AGAIN
  865.     . .
  866.     GET(@FILENAME,POINTER#)             !  RE-READ THE OLD RECORD
  867.     UPDATE                     !  AND RE-UPDATE THE RECORD
  868. *SETTOP*************************************************************************
  869.   SET(@KEYNAME)                     !SET TO FIRST RECORD
  870. *SETSELECT**********************************************************************
  871.   SET(@KEYNAME,@KEYNAME)             !SET TO FIRST SELECTED RECORD
  872. *INITLOCATE*********************************************************************
  873.     OF ?PRE_POINT                 !
  874.       IF KEYCODE() = ESC_KEY OR |         !  IF GOING UP
  875.       KEYCODE() = UP_KEY OR |             !    THE SCREEN
  876.       RECORDS# = FALSE                 !    OR NO RECORDS ON SCREEN
  877.     SCR:LOCATOR = ''             !    CLEAR LOCATOR
  878.     SELECT(?-1)                 !    AND GO TO PREVIOUS FIELD
  879.     SETCURSOR                 !    AND TURN CURSOR OFF
  880.       ELSE                     !  OTHERWISE, GOING DOWN
  881.     LEN# = 0                 !    RESET TO START OF LOCATOR
  882.     SETCURSOR(ROW(SCR:LOCATOR),COL(SCR:LOCATOR)) !AND TURN CURSOR ON
  883.       .
  884. *PREPOINT***********************************************************************
  885.               ENTRY,USE(?PRE_POINT)
  886. *LOCATE*************************************************************************
  887.       IF KEYCODE() > 31               |     !THE DISPLAYABLE CHARACTERS
  888.       AND KEYCODE() < 255             !ARE USED TO LOCATE RECORDS
  889.     IF LEN# < SIZE(SCR:LOCATOR)         !  IF THERE IS ROOM LEFT
  890.       SCR:LOCATOR = SUB(SCR:LOCATOR,1,LEN#) & CHR(KEYCODE())
  891.       LEN# += 1                 !    INCREMENT THE LENGTH
  892.     .
  893.       ELSIF KEYCODE() = BS_KEY             !BACKSPACE UNTYPES A CHARACTER
  894.     IF LEN# > 0                 !  IF THERE ARE CHARACTERS LEFT
  895.       LEN# -= 1                 !    DECREMENT THE LENGTH
  896.       SCR:LOCATOR = SUB(SCR:LOCATOR,1,LEN#)     !    ERASE THE LAST CHARACTER
  897.     .
  898.       ELSE                     !FOR ANY OTHER CHARACTER
  899.     LEN# = 0                 !  ZERO THE LENGTH
  900.     SCR:LOCATOR = ''             !  ERASE THE LOCATOR FIELD
  901.       .
  902.       SETCURSOR(ROW(SCR:LOCATOR),COL(SCR:LOCATOR)+LEN#) !AND RESET THE CURSOR
  903.       @SETLOCATE
  904.       IF LEN# > 0 THEN DO FIND_RECORD.         !    AND FIND THE RECORD
  905. *STRLOCATE**********************************************************************
  906.       @LOCFIELD = CLIP(SCR:LOCATOR)         !    UPDATE THE KEY FIELD
  907. *PICLOCATE**********************************************************************
  908.       @LOCFIELD = DEFORMAT(SCR:LOCATOR)         !    UPDATE THE KEY FIELD
  909. *SELECTOR***********************************************************************
  910.       SET(@KEYNAME,@KEYNAME)             !SET AT FIRST SELECTED RECORD
  911.       LOOP UNTIL EOF(@FILENAME)             !LOOP UNTIL END OF FILE
  912.     NEXT(@FILENAME)                 !  READ A RECORD
  913.     @CHECKSELECT                 !  CHECK THAT IT IS SELECTED
  914.     DO ADD_TABLE                 !  AND ADD TO MEMORY TABLE
  915.       .
  916. *FILTER*************************************************************************
  917.       BUFFER(@FILENAME,.25)             !USE 1/4TH OF MEMORY FOR BUFFER
  918.       SET(@FILENAME)                 !READ DATA RECORD SEQUENCE
  919.       LOOP UNTIL EOF(@FILENAME)             !LOOP UNTIL END OF FILE
  920.     NEXT(@FILENAME)                 !  READ A RECORD
  921.     DO ADD_TABLE                 !  ADD IT TO MEMORY TABLE
  922.       .
  923.       FREE(@FILENAME)                 !FREE MEMORY USED FOR BUFFERING
  924.       DO SORT_TABLE                 !SORT TABLE INTO KEY SEQUENCE
  925.       PTR = 1                     !DISPLAY FROM TOP OF TANLE
  926. *VALIDATE***********************************************************************
  927.     @ACCESSFIELD = @FIELD             !MOVE RELATED FIELDS
  928.     GET(@FILENAME,@ACCESSKEY)         !READ THE RECORD
  929.     IF ERROR()                 !IF NO RECORD IS FOUND
  930.       MEM:MESSAGE = 'RECORD NOT FOUND'     !  MOVE AN ERROR MESSAGE
  931.       BEEP                     !  SOUND THE KEYBOARD ALARM
  932.       SELECT(?@FIELD)             !  AND STAY ON THE SAME FIELD
  933.     .
  934. *ENTERTABLE*********************************************************************
  935.     @ACCESSFIELD = @FIELD             !MOVE RELATED FIELDS
  936.     GET(@FILENAME,@ACCESSKEY)         !READ THE RECORD
  937.     IF ERROR()                 !IF NO RECORD IS FOUND
  938.       ACTION# = ACTION             !  SAVE ACTION
  939.       ACTION = 4                 !  REQUEST TABLE LOOKUP
  940.       @LOOKUP                 !  CALL LOOKUP PROCEDURE
  941.       @FIELD = @ACCESSFIELD             !  MOVE LOOKUP FIELD
  942.       DISPLAY(?@FIELD)             !  AND DISPLAY IT
  943.       IF ACTION THEN SELECT(?@FIELD).     !  NO SELECTION WAS MADE
  944.       ACTION = ACTION#             !  RESTORE ACTION
  945.     .
  946. *AUTOTABLE**********************************************************************
  947.     @ACCESSFIELD = @FIELD             !MOVE RELATED FIELDS
  948.     GET(@FILENAME,@ACCESSKEY)         !READ THE RECORD
  949.     ACTION# = ACTION             !SAVE ACTION
  950.     ACTION = 4                 !REQUEST TABLE LOOKUP
  951.     @LOOKUP                     !CALL LOOKUP PROCEDURE
  952.     @LOOKFIELD = @ACCESSFIELD         !SAVE LOOKUP FIELD
  953.     @FIELD = @ACCESSFIELD             !MOVE LOOKUP FIELD
  954.     DISPLAY(?@FIELD)             !AND DISPLAY IT
  955.     IF ACTION THEN SELECT(?@FIELD-1).     !NO SELECTION WAS MADE
  956.     ACTION = ACTION#             !RESTORE ACTION
  957. *HOTTABLE***********************************************************************
  958.     IF KEYCODE() = @HOTKEY             !IF HOT KEY PRESSED
  959.       UPDATE                 !  UPDATE ALL FIELDS
  960.       @ACCESSFIELD = @FIELD             !  MOVE RELATED FIELDS
  961.       GET(@FILENAME,@ACCESSKEY)         !  READ THE RECORD
  962.       ACTION# = ACTION             !  SAVE ACTION
  963.       ACTION = 4                 !  REQUEST TABLE LOOKUP
  964.       @LOOKUP                 !  CALL LOOKUP PROCEDURE
  965.       @FIELD = @ACCESSFIELD             !  MOVE LOOKUP FIELD
  966.       DISPLAY(?@FIELD)             !  AND DISPLAY IT
  967.       IF ACTION THEN SELECT(?@FIELD).     !  NO SELECTION WAS MADE
  968.       ACTION = ACTION#             !  RESTORE ACTION
  969.     .
  970. *NEXTFORM***********************************************************************
  971.     IF ACTION <> 3                 !IF THIS IS NOT A DELETE
  972.       ACTION = 2                 !  SET ACTION TO CHANGE MODE
  973.       @NEXTPAGE                 !  CALL NEXT FORM PROCEDURE
  974.       IF ACTION                 !  IF RECORD WAS NOT CHANGED
  975.         SELECT(?LAST_FIELD - 1)         !    SELECT THE LAST ENTRY
  976.         BREAK                 !    AND LOOP AGAIN
  977.     . .
  978. *PAUSE**************************************************************************
  979.       OF ?PAUSE_FIELD                 !ON PAUSE FIELD
  980.     IF KEYCODE() <> ENTER_KEY  |         !IF NOT ENTER KEY
  981.     AND KEYCODE() <> ACCEPT_KEY         !AND NOT CTRL-ENTER KEY
  982.       BEEP                     !  SOUND KEYBOARD ALARM
  983.       SELECT(?PAUSE_FIELD)             !  AND STAY ON PAUSE FIELD
  984.     .
  985. *LOOKUPS************************************************************************
  986.     UPDATE                     !UPDATE RECORD KEYS
  987.     @ACCESSFIELD = @FIELD             !MOVE RELATED KEY FIELDS
  988.     GET(@FILENAME,@ACCESSKEY)             !READ THE RECORD
  989.     IF ERROR() THEN CLEAR(@PRE:RECORD).         !IF NOT FOUND, CLEAR RECORD
  990.     @SCRFIELD = @LOOKUPFIELD             !DISPLAY LOOKUP FIELD
  991. *LOOKUPSCROLL*******************************************************************
  992.     @ACCESSFIELD = @FIELD             !MOVE RELATED KEY FIELDS
  993.     GET(@FILENAME,@ACCESSKEY)             !READ THE RECORD
  994.     IF ERROR() THEN CLEAR(@PRE:RECORD).         !IF NOT FOUND, CLEAR RECORD
  995.     @SCRFIELD = @LOOKUPFIELD             !DISPLAY LOOKUP FIELD
  996. *OPENFILES**********************************************************************
  997.   OPEN(@FILENAME)                 !OPEN THE FILE
  998.   @CREATEFILE                     !IF NOT FOUND, THEN CREATE
  999. *CREATEFILE*********************************************************************
  1000.   IF ERRORCODE() = 2 THEN CREATE(@FILENAME).     !IF NOT FOUND, THEN CREATE
  1001.  
  1002. *SAVEITEMS**********************************************************************
  1003.          GROUP,PRE(SAV)
  1004.            @BREAKFIELDS
  1005.            @SELECTFIELDS
  1006.          .
  1007. *INITBREAK**********************************************************************
  1008.     @SAVEFIELD = @FIELD                 !SAVE BREAK FIELD
  1009. *INITSELECTS********************************************************************
  1010.     @SAVEFIELD = @FIELD                 !SAVE SELECTOR FIELD
  1011. *RESTSELECTS********************************************************************
  1012.     @FIELD = @SAVEFIELD                 !RESTORE SELECTOR FIELD
  1013. *CHECKBREAK*********************************************************************
  1014.       IF @FIELD <> @SAVEFIELD THEN BREAK.     !BREAK ON NEW GROUP
  1015. *SORTTABLE**********************************************************************
  1016.   SORT(TABLE,@COMPONENT)             !SORT TABLE INTO KEY SEQUENCE
  1017. *CHECKSELECT********************************************************************
  1018.     IF @FIELD <> @SAVEFIELD THEN BREAK.     !BREAK ON END OF SELECTION
  1019. *CHECKADD***********************************************************************
  1020.   IF @FIELD <> @SAVEFIELD THEN EXIT.         !EXIT ON END OF SELECTION
  1021. *CHECKHOT***********************************************************************
  1022.       IF KEYCODE() = @HOTKEY             !ON HOT KEY
  1023.     @HOTPROC                 !  CALL HOT KEY PROCEDURE
  1024.     SELECT(?)                 !  DO SAME FIELD AGAIN
  1025.     CYCLE                     !  AND LOOP AGAIN
  1026.       .
  1027. *TABLEHOT***********************************************************************
  1028.       IF KEYCODE() = @HOTKEY             !ON HOT KEY
  1029.     IF FIELD() = ?POINT THEN DO GET_RECORD.     !  READ RECORD IF NEEDED
  1030.     DO SAME_PAGE                 !  RESET TO SAME PAGE
  1031.     @HOTPROC                 !  CALL HOT KEY PROCEDURE
  1032.     DO SHOW_TABLE                 !  DISPLAY A PAGE OF RECORDS
  1033.     CYCLE                     !  AND LOOP AGAIN
  1034.       .
  1035. *BUILDTABLE*********************************************************************
  1036.   PTR = 1
  1037.   NDX = 1
  1038.   DO BUILD_TABLE                 !BUILD MEMORY TABLE OK KEYS
  1039. ********************************************************************************
  1040.