home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / clarion / pswmodel.zip / PASSWORD.MDL < prev    next >
Text File  |  1990-02-18  |  65KB  |  1,663 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.            PROC(G_OPENFILES)         ! OPEN FILES
  14.            FUNC(CHECK_PASS),LONG         ! CHECK PASSWORD
  15.            @RUNMAP
  16.            @MODULES
  17.          .
  18.          EJECT('FILE LAYOUTS')
  19.          @FILE
  20.  
  21. PASSWORD     FILE,PRE(PAS),CREATE,RECLAIM
  22.            OWNER('MASTER'),ENCRYPT
  23. BY_OPERATOR    KEY(PAS:OPERATOR_ID),NOCASE,OPT
  24. RECORD           RECORD
  25. OPERATOR_ID     STRING(5)
  26. PASSWORD     STRING(20)
  27. LEVEL         DECIMAL(2,0)
  28.          . .
  29.  
  30.          EJECT('GLOBAL MEMORY VARIABLES')
  31.  
  32. CLEARANCE    LONG                 ! SECURITY CLEARANCE
  33.  
  34. SAVE_CLEAR   LONG                 ! TEMP HOLDING VARIABLE
  35.                          ! FOR CLEARANCE ON ENTRY
  36.                          ! AND EXIT OF PROCEDURES
  37.  
  38. ACTION         SHORT                 !0 = NO ACTION
  39.                          !1 = ADD RECORD
  40.                          !2 = CHANGE RECORD
  41.                          !3 = DELETE RECORD
  42.                          !4 = LOOKUP FIELD
  43.                          !5 = AUTONUMKEY ADD
  44.          @MEMORY
  45.  
  46.          EJECT('CODE SECTION')
  47.  
  48. GET_PASS     SCREEN      WINDOW(25,80),PRE(SCR),HLP('GETPASS'),HUE(7,0)
  49.            ROW(10,20) PAINT(6,42),HUE(15,1)
  50.            ROW(1,1)      REPEAT(9);STRING('▒{80}') .
  51.            ROW(10,1)  STRING('▒{19}<0{42}>▒{19}')
  52.            ROW(11,1)  REPEAT(5);STRING('▒{19}<0{42}>░▒{18}') .
  53.            ROW(16,1)  STRING('▒{21}░{41}▒{18}')
  54.            ROW(17,1)  REPEAT(9);STRING('▒{80}') .
  55.            ROW(10,20) STRING('╔═{40}╗')
  56.            ROW(11,20) REPEAT(4);STRING('║<0{40}>║') .
  57.            ROW(15,20) STRING('╚═{40}╝')
  58.            ROW(13,22) STRING('Password:'),HUE(11,1)
  59. MSG           ROW(11,31) STRING(20),HUE(31,1)
  60.            ROW(12,22) STRING('Operator ID:'),HUE(11,1)
  61.          COL(35)  ENTRY(@S5),USE(OP_ID),HUE(14,1),SEL(0,7),OVR,LFT,UPR
  62.          .
  63. OP_ID         STRING(5)
  64. PW         STRING(20)
  65. KEYPRESS     STRING(1)
  66.  
  67.   CODE
  68.   SETHUE(7,0)                     !SET WHITE ON BLACK
  69.   BLANK                         !  AND BLANK
  70.   HELP(@HELPFILE)                 !OPEN THE HELP FILE
  71.   RECOVER(60)                     !HOLDS TIMEOUT IN 60 SECONDS
  72.   G_OPENFILES                     !OPEN OR CREATE FILES
  73.   SETHUE()                     !    THE SCREEN
  74.  
  75.   SHARE(PASSWORD)                 !OPEN PASSWORD FILE
  76.   OPEN(GET_PASS)                 !OPEN THE PASSWORD SCREEN
  77.   SETCURSOR                     !TURN OFF ANY CURSOR
  78.   DISPLAY                     !DISPLAY THE FIELDS
  79.   LOOP                         !LOOP THRU ALL THE FIELDS
  80.     ALERT                     !RESET ALERTED KEYS
  81.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  82.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  83.     ACCEPT                     !READ A FIELD
  84.     IF KEYCODE() = REJECT_KEY THEN RETURN.     !RETURN ON SCREEN REJECT KEY
  85.       CASE FIELD()                 !JUMP TO FIELD EDIT ROUTINE
  86.  
  87.       OF ?OP_ID
  88.     IF OP_ID = ''                 !IF REQUIRED FIELD IS EMPTY
  89.       BEEP                     !  SOUND KEYBOARD ALARM
  90.       SELECT(?OP_ID)             !  AND STAY ON THIS FIELD
  91.       CYCLE                     !
  92.     .
  93.  
  94.     PAS:OPERATOR_ID = OP_ID             ! SET UP TO GET PASSWORD
  95.     GET(PASSWORD,PAS:BY_OPERATOR)
  96.     IF ERRORCODE() = 35
  97.        BEEP
  98.        BEEP
  99.        SELECT(?OP_ID)             ! RESELECT OPERATOR ID
  100.        MSG = 'Invalid Operator ID'
  101.        MSG = CENTER(MSG)
  102.        CYCLE
  103.     .
  104.  
  105.     COL# = 35
  106.     PW = ''                     ! CLEAR PASSWORD
  107.     LOOP                     ! LOOP THROUGH PASSWORD
  108.       SETCURSOR(13,COL#)             ! TURN CURSOR ON AT COLUMN
  109.       ASK                     ! GET A KEYSTROKE
  110.                          ! UNTIL ENTER IS PRESSED
  111.  
  112.       KEYPRESS = CHR(KEYCODE())         ! STORE THE ASCII CODE
  113.                          ! INTO KEYPRESS VARIABLE
  114.  
  115.       IF KEYCODE() = ENTER_KEY OR KEYCODE() = ACCEPT_KEY THEN BREAK.
  116.  
  117.       IF KEYCODE() = BS_KEY             ! WAS IT A BACKSPACE?
  118.  
  119.         IF COL# <> 35             ! IF NOT AT BEGINNING OF FIELD
  120.           PW = SUB(PW,1,LEN(CLIP(PW)) - 1)     ! PROCESS THE BACKSPACE AND
  121.           COL# -= 1                 ! DECREMENT COLUMN NO
  122.           SHOW(13,COL#,' ')             ! BLANK THAT POSITION
  123.         ELSE
  124.           BEEP                 ! IF AT BEGINNING BEEP AND
  125.                          ! IGNORE THE BACKSPACE
  126.         .
  127.       ELSE
  128.         COL# += 1                 ! INCREMENT COLUMN NO
  129.         PW = CLIP(PW) & UPPER(KEYPRESS)     ! OTHERWISE ADD THE CHAR
  130.                          ! (CHANGE IT TO UPPER CASE)
  131.         SHOW(13,COL# - 1,'.')         ! SHOW A PERIOD AT THAT
  132.                          ! CHARACTER POSITION
  133.     . .
  134.  
  135.     IF PW = ''                 !IF REQUIRED FIELD IS EMPTY
  136.       BEEP                     !  SOUND KEYBOARD ALARM
  137.       SELECT(?OP_ID)             !  AND SELECT OPERATOR ID
  138.       CYCLE
  139.     .
  140.     IF PW <> UPPER(PAS:PASSWORD)         ! DO PASSWORDS MATCH?
  141.        BEEP
  142.        BEEP
  143.        SELECT(?OP_ID)             ! RESELECT OPERATOR ID
  144.        MSG = 'Invalid Password'
  145.        MSG = CENTER(MSG)
  146.        COUNT# += 1                 ! INCREMENT BAD COUNT
  147.        IF COUNT# > 4             ! GIVE THEM FOUR TRIES
  148.         BEEP                 ! SOUND ALARM
  149.         BEEP
  150.         BEEP
  151.         BEEP
  152.         BEEP
  153.         RETURN                 ! AND EXIT TO DOS
  154.        .
  155.        CYCLE
  156.     .
  157.  
  158.     ! NOW SECURITY CLEARANCE LEVEL IS STORED IN PAS:LEVEL.
  159.  
  160.     MSG = 'Password Accepted'
  161.     COUNT# = 0                 ! CLEAR COUNTER
  162.     LOOP 500 TIMES.                 ! WHOA HORSE...
  163.                          ! GIVE USER TIME TO READ
  164.                          ! MESSAGE
  165.     BREAK
  166.  
  167.   .   .
  168.   CLOSE(PASSWORD)                 ! CLOSE PASSWORD FILE
  169.  
  170.   @BASEPROC                     !CALL THE BASE PROCEDURE
  171.   CLOSE(GET_PASS)                 ! CLOSE PASSWORD SCREEN
  172.  
  173.   RETURN                     !EXIT TO DOS
  174.  
  175. G_OPENFILES  PROCEDURE                 !OPEN FILES & CHECK FOR ERROR
  176.   CODE
  177.   @OPENFILES                     !OPEN EACH FILE
  178.   BLANK                         !BLANK THE SCREEN
  179.  
  180.   @RUNPROC
  181.  
  182.  
  183. CHECK_PASS   FUNCTION
  184.  
  185. DENY_ENTRY   SCREEN      WINDOW(10,53),HUE(7,0)
  186.            ROW(1,53)  PAINT(1,1),TRN
  187.            ROW(10,1)  PAINT(1,2),TRN
  188.            ROW(1,1)      PAINT(9,52),HUE(15,4)
  189.          COL(1)      STRING('╔═{50}╗'),HUE(14,4)
  190.            ROW(2,1)      REPEAT(5);STRING('║<0{50}>║'),HUE(14,4) .
  191.            ROW(7,1)      STRING('╟─{50}╢'),HUE(14,4)
  192.            ROW(8,1)      STRING('║<0{50}>║'),HUE(14,4)
  193.            ROW(9,1)      STRING('╚═{50}╝'),HUE(14,4)
  194.            ROW(2,53)  REPEAT(8);STRING('░') .
  195.            ROW(10,3)  STRING('░{51}')
  196.            ROW(2,4)      STRING('Sorry.  You do not have security clearances' |
  197.                 & ' '),HUE(11,4)
  198.            ROW(3,4)      STRING('to this portion of the program.'),HUE(11,4)
  199.            ROW(5,4)      STRING('Please see your supervisor if you have any') |
  200.                 HUE(11,4)
  201.            ROW(6,4)      STRING('questions.'),HUE(11,4)
  202.            ROW(8,15)  PAUSE('Press Enter to continue...'),USE(?PAUSE)
  203.          .
  204.  
  205.     CODE
  206.  
  207.     IF CLEARANCE = 0                 ! DO THEY NEED SECURITY?
  208.        RETURN(TRUE)
  209.     .
  210.  
  211.     IF PAS:LEVEL < CLEARANCE             ! DO THEY HAVE SECURITY
  212.        OPEN(DENY_ENTRY)                 ! CLEARANCE?
  213.        BEEP;BEEP;BEEP
  214.        ACCEPT                     ! WAIT FOR PAUSE FIELD
  215.        RETURN(FALSE)                 ! RETURN FALSE
  216.     .
  217.     RETURN(TRUE)                 ! ELSE RETURN TRUE
  218.  
  219.  
  220. *MENU***************************************************************************
  221. @PROCNAME    PROCEDURE
  222.  
  223. SCREEN         SCREEN      PRE(SCR),@SCREENOPT
  224.               @PAINTS
  225.               @STRINGS
  226.               @VARIABLES
  227.               ENTRY,USE(?FIRST_FIELD)
  228.               @FIELDS
  229.               MENU,USE(?MENU_FIELD),REQ
  230.                 @CHOICES
  231.          .          .
  232.  
  233.   EJECT
  234.   CODE
  235.  
  236.   OPEN(SCREEN)                     !OPEN THE MENU SCREEN
  237.   SETCURSOR                     !TURN OFF ANY CURSOR
  238.  
  239.   SAVE_CLEAR = CLEARANCE             ! SAVE SECURITY CLEARANCE
  240.                          ! OF CALLER
  241.  
  242.   CLEARANCE = 0                     ! ASSUME NO SECURITY
  243.  
  244.   @SETUP                     !CALL SETUP PROCEDURE
  245.  
  246.   IF NOT CHECK_PASS()                 ! IF THEY DO NOT HAVE
  247.      CLEARANCE = SAVE_CLEAR             ! SECURITY CLEARANCES
  248.      RETURN                     ! THEN EXIT
  249.   .
  250.  
  251.   LOOP                         !LOOP UNTIL USER EXITS
  252.     @LOOKUPS                     !DISPLAY FROM OTHER FILES
  253.     @SHOW                     !DISPLAY STRING VARIABLES
  254.     @COMPUTE                     !DISPLAY COMPUTED FIELDS
  255.     @CONDITIONAL                 !DISPLAY CONDITIONAL FIELDS
  256.     @RESULT                     !MOVE RESULTING VALUES
  257.     ALERT                     !TURN OFF ALL ALERTED KEYS
  258.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  259.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  260.     @ALERT                     !ALERT HOT KEYS
  261.     ACCEPT                     !READ A FIELD OR MENU CHOICE
  262.     @CHECKHOT                     !ON HOT KEY, CALL PROCEDURE
  263.     IF KEYCODE() = REJECT_KEY             !RETURN ON SCREEN REJECT
  264.        CLEARANCE = SAVE_CLEAR
  265.        RETURN
  266.     .
  267.  
  268.     EDIT_RANGE# = FIELD()             !SET ONE FIELD EDIT RANGE
  269.     IF KEYCODE() = ACCEPT_KEY             !ON SCREEN ACCEPT KEY
  270.       UPDATE                     !  MOVE ALL FIELDS FROM SCREEN
  271.       EDIT_RANGE# = ?MENU_FIELD - 1         !  AND EDIT REMAINING FIELDS
  272.       SELECT(?MENU_FIELD)             !  IF OK THEN START HERE NEXT
  273.     .                         !
  274.  
  275.     LOOP FIELD# = FIELD() TO EDIT_RANGE#     !EDIT FIELDS IN THE EDIT RANGE
  276.  
  277.       CASE FIELD#                 !JUMP TO FIELD EDIT ROUTINE
  278.       OF ?FIRST_FIELD                 !FROM THE FIRST FIELD
  279.     IF KEYCODE() = ESC_KEY             !  RETURN ON ESC KEY
  280.        CLEARANCE = SAVE_CLEAR
  281.        RETURN
  282.     .
  283.  
  284.       @EDITS                     !EDIT ROUTINES GO HERE
  285.       OF ?MENU_FIELD                 !FROM THE MENU FIELD
  286.     EXECUTE CHOICE()             !  CALL THE SELECTED PROCEDURE
  287.       @MENU                     !
  288.   . . . .
  289. *TABLE**************************************************************************
  290. @PROCNAME    PROCEDURE
  291.  
  292. SCREEN         SCREEN      PRE(SCR),@SCREENOPT
  293.               @PAINTS
  294.               @STRINGS
  295.               @VARIABLES
  296.               ENTRY,USE(?FIRST_FIELD)
  297.               @FIELDS
  298.               @PREPOINT
  299.               REPEAT(@COUNT),EVERY(@PROWS),INDEX(NDX)
  300.           @PLOC        POINT(@PROWS,@COLS),USE(?POINT),ESC(?-1)
  301.                 @SCROLLVARIABLES
  302.          .          .
  303.  
  304. TABLE         TABLE                 !TABLE OF RECORD POINTERS
  305. TBLPTR           LONG                 !  POINTER TO DATA RECORD
  306.          .
  307.  
  308. NDX         BYTE                 !REPEAT INDEX FOR POINT FIELD
  309. ROW         BYTE                 !ACTUAL ROW OF SCROLL AREA
  310. COL         BYTE                 !ACTUAL COLUMN OF SCROLL AREA
  311. MAX         LONG                 !LESSER OF COUNT AND RECORDS
  312. COUNT         BYTE(@COUNT)             !NUMBER OF ITEMS TO SCROLL
  313. ROWS         BYTE(@ROWS)             !NUMBER OF ROWS TO SCROLL
  314. COLS         BYTE(@COLS)             !NUMBER OF COLUMNS TO SCROLL
  315.  
  316. @SAVETOTALS
  317.  
  318.   EJECT
  319.   CODE
  320.   ACTION# = ACTION                 !SAVE ACTION
  321.   OPEN(SCREEN)                     !OPEN THE SCREEN
  322.   SETCURSOR                     !TURN OFF ANY CURSOR
  323.   SAVE_CLEAR = CLEARANCE             ! SAVE SECURITY CLEARANCE
  324.                          ! OF CALLER
  325.  
  326.   CLEARANCE = 0                     ! ASSUME NO SECURITY
  327.  
  328.   @SETUP                     !CALL SETUP PROCEDURE
  329.  
  330.   IF NOT CHECK_PASS()                 ! IF THEY DO NOT HAVE
  331.      CLEARANCE = SAVE_CLEAR             ! SECURITY CLEARANCES
  332.      RETURN                     ! THEN EXIT
  333.   .
  334.  
  335.   NDX = 1                     !PUT SELECTOR BAR ON TOP ITEM
  336.   ROW = ROW(?POINT)                 !REMEMBER TOP ROW AND
  337.   COL = COL(?POINT)                 !  LEFT COLUMN OF SCROLL AREA
  338.   @TOTALCALC                     !BUILD TABLE TOTAL FIELDS
  339.   IF ACTION = 4                     !IF THIS IS A LOOKUP REQUEST
  340.     DO FIND_RECORD                 !  POSITION FILE
  341.     GET(@FILENAME,POINTER#)             !  REFRESH CURRENT RECORD
  342.   ELSE                         !OTHERWISE
  343.     SET(@KEYNAME)                 !  SET TO FIRST RECORD IN FILE
  344.     DO SHOW_TABLE                 !  FILL SCROLL AREA
  345.   .
  346.   RECORDS# = TRUE                 !INITIALIZE RECORDS FLAG
  347.   LOOP                         !LOOP UNTIL USER EXITS
  348.     MAX = RECORDS(@KEYNAME)             !SET LESSER OF FILE RECORD
  349.     IF MAX > COUNT THEN MAX = COUNT.         !  COUNT AND SCROLL ITEM COUNT
  350.     ACTION = ACTION#                 !RESTORE ACTION
  351.     POINTER# = 0                 !CLEAR ADD POINTER
  352.     @TOTSHOW                     !DISPLAY TOTAL AMOUNT ON SCREEN
  353.     @LOOKUPS                     !DISPLAY FROM OTHER FILES
  354.     @SHOW                     !DISPLAY STRING VARIABLES
  355.     @COMPUTE                     !DISPLAY COMPUTED FIELDS
  356.     @CONDITIONAL                 !DISPLAY CONDITIONAL FIELDS
  357.     @RESULT                     !MOVE RESULTING VALUES
  358.     IF ~RECORDS(@KEYNAME)             !IF THERE ARE NO RECORDS
  359.       CLEAR(@PRE:RECORD)             !  CLEAR RECORD AREA
  360.       ACTION = 1                 !  SET ACTION TO ADD
  361.       @AUTONUMKEY                 !  AUTO INCREMENT KEY FIELD
  362.       @UPDATE                     !  CALL FORM FOR FIRST RECORD
  363.       @AUTONUMESC                 !  DELETE IF FORM NOT COMPLETED
  364.       IF ~RECORDS(@KEYNAME) THEN BREAK.         !  IF ADD ABORTED THEN EXIT
  365.       DO SHOW_RECORD                 !    PERFORM ALL CALCULATIONS
  366.       @TOTPLUS                     !    UPDATE TOTAL FIELDS
  367.       SET(@KEYNAME)                 !  SET TO NEW RECORD
  368.       DO SHOW_TABLE                 !  FILL SCROLL AREA
  369.       NDX = 1                     !  PUT SELECTOR BAR ON TOP ITEM
  370.       MAX = 1                     !  MAXIMUM DISPLAYED IS 1
  371.     .                         !
  372.     ALERT                     !RESET ALERTED KEYS
  373.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  374.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  375.     @ALERT                     !ALERT HOT KEY
  376.     ACCEPT                     !READ A FIELD
  377.     @TABLEHOT                     !ON HOT KEY, CALL PROCEDURE
  378.     IF KEYCODE() = REJECT_KEY THEN BREAK.     !RETURN ON SCREEN REJECT KEY
  379.     EDIT_RANGE# = FIELD()             !SET ONE FIELD EDIT RANGE
  380.     IF KEYCODE() = ACCEPT_KEY AND |         !ON SCREEN ACCEPT KEY
  381.        EDIT_RANGE# <> ?POINT             ! AND NOT ON THE POINT FIELD
  382.       UPDATE                     !  MOVE ALL FIELDS FROM SCREEN
  383.       EDIT_RANGE# = ?POINT - 1             !  AND EDIT REMAINING FIELDS
  384.       SELECT(?POINT)                 !  IF OK THEN START HERE NEXT
  385.     .                         !
  386.  
  387.     LOOP FIELD# = FIELD() TO EDIT_RANGE#     !EDIT FIELDS IN THE EDIT RANGE
  388.  
  389.       CASE FIELD#                 !JUMP TO FIELD EDIT ROUTINE
  390.       OF ?FIRST_FIELD                 !FROM THE FIRST FIELD
  391.     IF KEYCODE() = ESC_KEY    OR |         !  RETURN ON ESC KEY
  392.        RECORDS# = FALSE             !  OR NO RECORDS
  393.          FREE(TABLE)             !    FREE THE MEMORY TABLE
  394.          CLEARANCE = SAVE_CLEAR         !    RESTORE CLEARANCE
  395.          RETURN
  396.     .
  397.       @EDITS                     !EDIT ROUTINES GO HERE
  398.     RECORDS# = TRUE                 !  ASSUME RECORDS ARE HERE
  399.       @INITLOCATE                 !SHOW CURSOR FOR LOCATOR
  400.       OF ?POINT                     !FROM THE POINT FIELD
  401.     @LOCATE                     !  PERFORM LOCATOR LOGIC
  402.     CASE KEYCODE()                 !  PROCESS THE KEYSTROKE
  403.     OF INS_KEY                 !INSERT KEY
  404.       CLEAR(@PRE:RECORD)             !  CLEAR RECORD AREA
  405.       ACTION = 1                 !  SET ACTION TO ADD
  406.       @AUTONUMKEY                 !  AUTO INCREMENT KEY FIELD
  407.       @TOTCHECK                 !  SAVE TOTAL FIELD AMOUNT
  408.       @UPDATE                 !  CALL FORM FOR NEW RECORD
  409.       @AUTONUMESC                 !  DELETE IF FORM NOT COMPLETED
  410.       IF ~ACTION                 !  IF A NEW RECORD WAS ADDED
  411.         POINTER# = POINTER(@FILENAME)     !    REMEMBER WHICH RECORD
  412.         SET(@KEYNAME,@KEYNAME)         !    SET TO NEW RECORD AND
  413.         SKIP(@FILENAME,-1)             !    MAKE IT THE TOP ITEM
  414.         DO SHOW_TABLE             !    DISPLAY THAT PAGE
  415.       .
  416.     OF ENTER_KEY                 !ENTER KEY OR
  417.     OROF ACCEPT_KEY                 !CTRL ENTER KEY
  418.       DO GET_RECORD                 !  READ THE SELECTED RECORD
  419.       IF ERROR()                 !  IF RECORD HAS BEEN DELETED
  420.         MEM:MESSAGE = ERROR()         !    TELL USER WHAT HAPPENED
  421.         SELECT(?)                 !    STAY IN THE POINT FIELD
  422.         DO SHOW_TABLE             !    SHOW IT
  423.         BREAK                 !    AND GET ANOTHER KEY
  424.       .
  425.       IF ACTION = 4 AND KEYCODE() = ENTER_KEY!  IF THIS IS A LOOKUP REQUEST
  426.         ACTION = 0                 !    SET ACTION TO COMPLETE
  427.         FREE(TABLE)                 !    FREE THE MEMORY TABLE
  428.         CLEARANCE = SAVE_CLEAR         !    RESTORE CLEARANCE
  429.         RETURN                 !    AND RETURN TO CALLER
  430.       .                     !
  431.       ACTION = 2                 !  SET ACTION TO CHANGE
  432.       @TOTCHECK                 !  SAVE TOTAL FIELD AMOUNT
  433.       @UPDATE                 !  CALL FORM TO CHANGE RECORD
  434.       IF ~ACTION                 !  IF THE RECORD WAS CHANGED
  435.         POINTER# = POINTER(@FILENAME)     !    REMEMBER WHICH RECORD
  436.         SET(@KEYNAME,@KEYNAME)         !    SET TO CHANGED RECORD
  437.         SKIP(@FILENAME,-1)             !    MAKE IT THE TOP ITEM
  438.         DO SHOW_TABLE             !    AND DISPLAY THAT PAGE
  439.       .
  440.     OF DEL_KEY                 !DELETE KEY
  441.       DO GET_RECORD                 !  READ THE SELECTED RECORD
  442.       IF ERROR()                 !  IF RECORD HAS BEEN DELETED
  443.         MEM:MESSAGE = ERROR()         !    TELL USER WHAT HAPPENED
  444.         SELECT(?)                 !    STAY IN THE POINT FIELD
  445.         DO SHOW_TABLE             !    SHOW IT
  446.         BREAK                 !    AND GET ANOTHER KEY
  447.       .
  448.       ACTION = 3                 !  SET ACTION TO DELETE
  449.       @TOTSAVE                 !  SAVE TOTAL FIELD AMOUNT
  450.       @UPDATE                 !  CALL FORM TO DELETE RECORD
  451.       IF ~ACTION                 !  IF RECORD WAS DELETED
  452.         @TOTMINUS                 !    SUBTRACT FROM TOTAL FLDS
  453.         SKIP(@FILENAME,-COUNT)         !    SET NEXT RECORD ON TOP
  454.         DO SHOW_TABLE             !    AND DISPLAY THAT PAGE
  455.       .
  456.     OF DOWN_KEY                 !DOWN ARROW KEY
  457.       IF NOT EOF(@FILENAME)             !  IF THERE ARE MORE RECORDS
  458.         SCROLL(ROW,COL,ROWS,COLS,ROWS(?POINT)) !  SCROLL THE SCREEN UP
  459.         NEXT(@FILENAME)             !    READ THE BOTTOM RECORD
  460.         GET(TABLE,1)             !    GET THE TOP POINTER
  461.         DELETE(TABLE)             !    REMOVE TOP ITEM
  462.         TBLPTR = POINTER(@FILENAME)         !    DETERMINE RECORD POINTER
  463.         ADD(TABLE)                 !    ADD TO BOTTOM OF TABLE
  464.         DO SHOW_RECORD             !    AND DISPLAY IT
  465.       .
  466.     OF PGDN_KEY                 !PAGE DOWN KEY
  467.       IF EOF(@FILENAME)             !  ON THE LAST PAGE
  468.         NDX = MAX                 !    POINT TO BOTTOM ITEM
  469.       ELSE                     !  OTHERWISE
  470.         DO SHOW_TABLE             !    DISPLAY NEXT PAGE
  471.       .
  472.     OF CTRL_PGDN                 !CTRL-PAGE DOWN KEY
  473.       NDX = MAX                 !  POINT TO BOTTOM ITEM
  474.       IF NOT EOF(@FILENAME)             !  ON THE LAST PAGE
  475.         SET(@KEYNAME)             !    SET TO BOTTOM RECORD MINUS
  476.         SKIP(@FILENAME,-COUNT)         !    ONE PAGE OF RECORDS
  477.         DO SHOW_TABLE             !    DISPLAY THE LAST PAGE
  478.       .
  479.     OF UP_KEY                 !UP ARROW KEY
  480.       SKIP(@FILENAME,-(COUNT-1))         !  SET TO TOP RECORD MINUS ONE
  481.       IF NOT BOF(@FILENAME)             !  IF THERE IS A PRIOR RECORD
  482.         PREVIOUS(@FILENAME)             !     READ THE TOP RECORD
  483.         IF NOT ERROR()             !    IF RETRIEVED OKAY
  484.           SCROLL(ROW,COL,ROWS,COLS,-(ROWS(?POINT)))! SCROLL THE SCREEN DOWN
  485.           GET(TABLE,RECORDS(TABLE))         !    GET THE LAST POINTER
  486.           DELETE(TABLE)             !    REMOVE LAST ITEM
  487.           TBLPTR = POINTER(@FILENAME)     !     DETERMINE RECORD POINTER
  488.           ADD(TABLE,1)             !    ADD TO TOP OF TABLE
  489.           DO SHOW_RECORD             !     AND DISPLAY IT
  490.         ELSIF ERRORCODE() = 33         !    ELSE IF RECORD NOT AVAIL
  491.           NEXT(@FILENAME)             !    RETURN TO FIRST RECORD
  492.       . .
  493.       SKIP(@FILENAME,COUNT-1)         !  SET RECORD FOR NEXT PAGE
  494.  
  495.     OF PGUP_KEY                 !PAGE UP KEY
  496.       SKIP(@FILENAME,-(COUNT-1))         !  SET TO TOP RECORD MINUS ONE
  497.       IF BOF(@FILENAME)             !  IF THERE IS NO PRIOR RECORD
  498.         NDX = 1                 !    THEN POINT TO TOP ITEM
  499.         SKIP(@FILENAME,COUNT-1)         !    SET RECORD FOR THIS PAGE
  500.       ELSE                     !  OTHERWISE
  501.         SKIP(@FILENAME,-(COUNT+1))         !    SET RECORD FOR PRIOR PAGE
  502.         DO SHOW_TABLE             !    AND DISPLAY THE PAGE
  503.       .
  504.     OF CTRL_PGUP                 !CTRL-PAGE UP KEY
  505.       SET(@KEYNAME)                 !  SET TO FIRST RECORD
  506.       NDX = 1                 !  POINT TO TOP ITEM
  507.       DO SHOW_TABLE                 !  AND DISPLAY THE PAGE
  508.     .
  509.   . . .
  510.   FREE(TABLE)                     !FREE THE MEMORY TABLE
  511.   CLEARANCE = SAVE_CLEAR             ! RESTORE CLEARANCE
  512.   RETURN                     !RETURN TO CALLER
  513.  
  514. SHOW_TABLE ROUTINE                 !DISPLAY A PAGE OF RECORDS
  515.   FREE(TABLE)                     !  FREE THE MEMORY TABLE
  516.   SKIP(@FILENAME,COUNT-1)             !  SET TO THE BOTTOM RECORD
  517.   IF EOF(@FILENAME)                 !  FOR A PARTIAL PAGE
  518.     SET(@KEYNAME)                 !    SET TO THE LAST RECORD
  519.     SKIP(@FILENAME,-COUNT)             !    AND BACK UP ONE PAGE
  520.   ELSE                         !  OTHERWISE
  521.     SKIP(@FILENAME,-(COUNT-1))             !    SET RECORD FOR THIS PAGE
  522.   .
  523.   NDX# = NDX                     !  SAVE REPEAT INDEX
  524.   LOOP NDX = 1 TO COUNT                 !  LOOP THRU THE SCROLL AREA
  525.     IF EOF(@FILENAME) THEN BREAK.         !    BREAK ON END OF FILE
  526.     NEXT(@FILENAME)                 !    READ THE NEXT RECORD
  527.     TBLPTR = POINTER(@FILENAME)             !    GET THE RECORD NUMBER
  528.     ADD(TABLE)                     !    ADD IT TO THE TABLE
  529.     DO SHOW_RECORD                 !    AND DISPLAY IT
  530.     IF POINTER(@FILENAME) = POINTER#         !    POINT TO CORRECT RECORD
  531.       NDX# = NDX                 !  POINT TO CORRECT RECORD
  532.       @DOTOTALS                     !  CALCULATE TOTAL FIELDS
  533.   . .
  534.   NDX = NDX#                     !  RESTORE REPEAT INDEX
  535.   CLEAR(@PRE:RECORD)                 !  CLEAR RECORD AREA
  536.   IF RECORDS(@KEYNAME) < COUNT             !  IF RECORDS DO NOT FILL
  537.      NDX#= RECORDS(@KEYNAME) * @PROWS         !     GET NUMBER TIMES SIZE
  538.      BLANK(ROW + NDX#,COL,ROWS-NDX#,COLS)     !     BLANK REMAINING AREA
  539.   .
  540.  
  541. SHOW_RECORD ROUTINE                 !DISPLAY A RECORD
  542.   @LOOKUPSCROLL                     !  DISPLAY FROM OTHER FILES
  543.   @SHOWSCROLL                     !  DISPLAY STRING VARIABLES
  544.   @COMPUTESCROLL                 !  DISPLAY COMPUTED FIELDS
  545.   @CONDITIONALSCRL                 !  DISPLAY CONDITIONAL FIELDS
  546.   @RESULTSCROLL                     !  ASSIGN RESULT FIELDS
  547.  
  548. GET_RECORD ROUTINE                 !READ SELECTED RECORD
  549.   GET(TABLE,NDX)                 !  GET THE TABLE RECORD
  550.   GET(@FILENAME,TBLPTR)                 !  GET THIS RECORD
  551.  
  552. FIND_RECORD ROUTINE                 !LOCATE REQUESTED RECORD
  553.   SET(@KEYNAME,@KEYNAME)             !  SET TO REQUESTED RECORD
  554.   IF EOF(@FILENAME)                 !  IF BEYOND END OF FILE
  555.     PREVIOUS(@FILENAME)                 !    GET THE LAST RECORD
  556.   ELSE                         !  ELSE
  557.     NEXT(@FILENAME)                 !    READ THIS RECORD
  558.   .
  559.   POINTER# = POINTER(@FILENAME)             !  SAVE ITS RECORD POINTER
  560.   SKIP(@FILENAME,-1)                 !  MAKE IT THE TOP RECORD
  561.   DO SHOW_TABLE                     !  AND FILL THE SCROLL AREA
  562.  
  563. SAME_PAGE ROUTINE                 !SET TO SAME PAGE ROUTINE
  564.   POINTER# = POINTER(@FILENAME)             !  SAVE ITS RECORD POINTER
  565.   GET(@FILENAME,POINTER#)             !  GET THE CURRENT RECORD
  566.   SET(@KEYNAME,@KEYNAME)             !    SET TO NEW RECORD AND
  567.   SKIP(@FILENAME,-1)                 !  SKIP TO TOP OF SAME PAGE
  568.  
  569. @COMPUTETOTS                     !CALCULATE TOTAL FIELDS
  570. *SELTABLE***********************************************************************
  571. @PROCNAME    PROCEDURE
  572.  
  573. SCREEN         SCREEN      PRE(SCR),@SCREENOPT
  574.               @PAINTS
  575.               @STRINGS
  576.               @VARIABLES
  577.               ENTRY,USE(?FIRST_FIELD)
  578.               @FIELDS
  579.               @PREPOINT
  580.               REPEAT(@COUNT),EVERY(@PROWS),INDEX(NDX)
  581.           @PLOC        POINT(@PROWS,@COLS),USE(?POINT),ESC(?-1)
  582.                 @SCROLLVARIABLES
  583.          .          .
  584.  
  585. PTR         LONG                 !ENTRY POINTER FOR KEY TABLE
  586. NDX         BYTE                 !REPEAT INDEX FOR POINT AREA
  587. ROW         BYTE                 !ACTUAL ROW OF SCROLL AREA
  588. COL         BYTE                 !ACTUAL COLUMN OF SCROLL AREA
  589. COUNT         BYTE(@COUNT)             !NUMBER OF ITEMS TO SCROLL
  590. ROWS         BYTE(@ROWS)             !NUMBER OF ROWS TO SCROLL
  591. COLS         BYTE(@COLS)             !NUMBER OF COLUMNS TO SCROLL
  592.  
  593. TABLE         TABLE                 !TABLE OF RECORD KEYS
  594. TBLPTR           LONG                 !  POINTER TO DATA RECORD
  595. KEY           GROUP,PRE(TBL)             !  RECORD KEY FIELDS
  596.          @COMPONENTS
  597.          . .
  598. @SAVEITEMS
  599. @SAVETOTALS
  600.  
  601.   EJECT
  602.   CODE
  603.   ACTION# = ACTION                 !SAVE ACTION
  604.   OPEN(SCREEN)                     !OPEN THE SCREEN
  605.   SETCURSOR                     !TURN OFF ANY CURSOR
  606.   SAVE_CLEAR = CLEARANCE             ! SAVE SECURITY CLEARANCE
  607.                          ! OF CALLER
  608.  
  609.   CLEARANCE = 0                     ! ASSUME NO SECURITY
  610.  
  611.   @SETUP                     !CALL SETUP PROCEDURE
  612.  
  613.   IF NOT CHECK_PASS()                 ! IF THEY DO NOT HAVE
  614.      CLEARANCE = SAVE_CLEAR             ! SECURITY CLEARANCES
  615.      RETURN                     ! THEN EXIT
  616.   .
  617.  
  618.   @INITSELECTS                     !SAVE SELECTOR FIELDS
  619.   @TOTCLEAR                     !ZERO TOTAL FIELDS
  620.   PTR = 1                     !START AT TABLE ENTRY
  621.   NDX = 1                     !PUT SELECTOR BAR ON TOP ITEM
  622.   ROW = ROW(?POINT)                 !REMEMBER TOP ROW AND
  623.   COL = COL(?POINT)                 !LEFT COLUMN OF SCROLL AREA
  624.   RECORDS# = TRUE                 !INITIALIZE RECORDS FLAG
  625.   LOOP                         !LOOP UNTIL USER EXITS
  626.     ACTION = ACTION#                 !RESTORE ACTION
  627.     @RESTSELECTS                 !RESTORE SELECTOR FIELDS
  628.     @TOTSHOW                     !DISPLAY TOTAL AMOUNTS ON SCRN
  629.     @LOOKUPS                     !DISPLAY FROM OTHER FILES
  630.     @SHOW                     !DISPLAY STRING VARIABLES
  631.     @COMPUTE                     !DISPLAY COMPUTED FIELDS
  632.     @CONDITIONAL                 !DISPLAY CONDITIONAL FIELDS
  633.     @RESULT                     !MOVE RESULTING VALUES
  634.     ALERT                     !RESET ALERTED KEYS
  635.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  636.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  637.     @ALERT                     !ALERT HOT KEY
  638.     ACCEPT                     !READ A FIELD
  639.     MEM:MESSAGE = ''                 !CLEAR MESSAGE AREA
  640.     @TABLEHOT                     !ON HOT KEY, CALL PROCEDURE
  641.     IF KEYCODE() = REJECT_KEY THEN BREAK.     !RETURN ON SCREEN REJECT KEY
  642.  
  643.     EDIT_RANGE# = FIELD()             !SET ONE FIELD EDIT RANGE
  644.     IF KEYCODE() = ACCEPT_KEY AND |         !ON SCREEN ACCEPT KEY
  645.        EDIT_RANGE# <> ?POINT             ! AND NOT ON THE POINT FIELD
  646.       UPDATE                     !  MOVE ALL FIELDS FROM SCREEN
  647.       EDIT_RANGE# = ?POINT - 1             !  AND EDIT REMAINING FIELDS
  648.       SELECT(?POINT)                 !  IF OK THEN START HERE NEXT
  649.     .                         !
  650.  
  651.     LOOP FIELD# = FIELD() TO EDIT_RANGE#     !EDIT FIELDS IN THE EDIT RANGE
  652.  
  653.       CASE FIELD#                 !JUMP TO FIELD EDIT ROUTINE
  654.  
  655.       OF ?FIRST_FIELD                 !FROM THE FIRST FIELD
  656.     IF KEYCODE() = ESC_KEY OR |         !  RETURN ON ESC KEY
  657.        RECORDS# = FALSE             !  OR NO RECORDS
  658.          FREE(TABLE)             !  FREE THE TABLE OF POINTS
  659.          CLEARANCE = SAVE_CLEAR         !  RESTORE CLEARANCE
  660.          RETURN                 !  RETURN TO CALLER
  661.     .
  662.       @EDITS                     !EDIT ROUTINES GO HERE
  663.     RECORDS# = TRUE                 !  ASSUME THERE ARE RECORDS
  664.       @INITLOCATE
  665.       OF ?POINT                     !PROCESS THE POINT FIELD
  666.     IF ~RECORDS(TABLE)             !IF THERE ARE NO RECORDS
  667.       CLEAR(@PRE:RECORD)             !  CLEAR RECORD AREA
  668.       UPDATE                 !  UPDATE ALL FIELDS
  669.       ACTION = 1                 !  SET ACTION TO ADD
  670.       @AUTONUMKEY                 !  AUTO INCREMENT KEY FIELD
  671.       @TOTCHECK                 !  SAVE TOTAL FIELD AMOUNT
  672.       @UPDATE                 !  CALL FORM FOR FIRST RECORD
  673.       @AUTONUMESC                 !  DELETE IF FORM NOT COMPLETED
  674.       IF ~ACTION                 !  IF RECORD WAS ADDED
  675.         DO ADD_TABLE             !    THEN ADD NEW TABLE ENTRY
  676.         DO SORT_TABLE             !    SORT THE TABLE
  677.         DO SHOW_TABLE             !    AND DISPLAY FIRST PAGE
  678.       .
  679.       IF ~RECORDS(TABLE)             !  IF ADD ABORTED TRY AGAIN
  680.           RECORDS# = FALSE             !    INDICATE NO RECORDS
  681.           SELECT(?-1)             !    SELECT PREVIOUS FIELD
  682.           BREAK                 !    END THE EDITS
  683.       .
  684.       CYCLE                     !  CONTINUE THE EDIT
  685.     .
  686.     @LOCATE
  687.     CASE KEYCODE()                 !PROCESS THE KEYSTROKE
  688.  
  689.     OF ENTER_KEY                 !ENTER KEY OR
  690.     OROF ACCEPT_KEY                 !CTRL-ENTER KEY
  691.       DO GET_RECORD                 !  READ THE SELECTED RECORD
  692.       IF ERROR()                 !  IF RECORD HAS BEEN DELETED
  693.         MEM:MESSAGE = ERROR()         !    TELL USER WHAT HAPPENED
  694.         SELECT(?)                 !    STAY IN THE POINT FIELD
  695.         DO BUILD_TABLE             !    REBUILD TABLE
  696.         DO SORT_TABLE             !    SORT IT
  697.         DO SHOW_TABLE             !    SHOW IT
  698.         BREAK                 !    AND GET ANOTHER KEY
  699.       .
  700.       IF ACTION = 4 AND KEYCODE() = ENTER_KEY!  IF THIS IS A LOOKUP REQUEST
  701.         ACTION = 0                 !    SET ACTION TO COMPLETE
  702.         FREE(TABLE)                 !    FREE THE TABLE OF POINTS
  703.         CLEARANCE = SAVE_CLEAR         !    RESTORE CLEARANCE
  704.         RETURN                 !    RETURN TO CALLER
  705.       .
  706.       ACTION = 2                 !  SET ACTION TO CHANGE
  707.       @TOTSAVE                 !  SAVE TOTAL FIELD AMOUNT
  708.       @UPDATE                 !  CALL FORM TO CHANGE RECORD
  709.       IF ~ACTION                 !  IF THE RECORD WAS CHANGED
  710.         @TOTMINUS                 !    SUBTRACT OLD TOTAL AMOUNT
  711.         DELETE(TABLE)             !    DELETE OLD TABLE ENTRY
  712.         DO ADD_TABLE             !    ADD NEW TABLE ENTRY
  713.         DO SORT_TABLE             !    SORT THE TABLE
  714.         DO SHOW_TABLE             !    AND DISPLAY THAT PAGE
  715.       .
  716.     OF INS_KEY                 !INS KEY
  717.       CLEAR(@PRE:RECORD)             !  CLEAR RECORD AREA
  718.       UPDATE                 !  UPDATE ALL FIELDS
  719.       ACTION = 1                 !  SET ACTION TO ADD
  720.       @AUTONUMKEY                 !  AUTO INCREMENT KEY FIELD
  721.       @UPDATE                 !  CALL FORM FOR NEW RECORD
  722.       @AUTONUMESC                 !  DELETE IF FORM NOT COMPLETED
  723.       IF ~ACTION                 !  IF RECORD WAS ADDED
  724.         DO ADD_TABLE             !    ADD NEW TABLE ENTRY
  725.         DO SORT_TABLE             !    SORT THE TABLE
  726.         DO SHOW_TABLE             !    AND DISPLAY THAT PAGE
  727.       .
  728.     OF DEL_KEY                 !DEL KEY
  729.       DO GET_RECORD                 !  READ THE SELECTED RECORD
  730.       IF ERROR()                 !  IF RECORD HAS BEEN DELETED
  731.         MEM:MESSAGE = ERROR()         !    TELL USER WHAT HAPPENED
  732.         SELECT(?)                 !    STAY ON THE POINT FIELD
  733.         DO BUILD_TABLE             !    REBUILD TABLE
  734.         DO SORT_TABLE             !    SORT IT
  735.         DO SHOW_TABLE             !    SHOW IT
  736.         BREAK                 !    AND GET ANOTHER KEY
  737.       .
  738.       @TOTSAVE                 !  SAVE TOTAL FIELD AMOUNT
  739.       ACTION = 3                 !  SET ACTION TO DELETE
  740.       @UPDATE                 !  CALL FORM TO DELETE RECORD
  741.       IF ~ACTION                 !  IF RECORD WAS DELETED
  742.         @TOTMINUS                 !    SUBTRACT FROM TOTAL FLDS
  743.         DELETE(TABLE)             !    DELETE TABLE ENTRY
  744.         DO SHOW_TABLE             !    AND DISPLAY THAT PAGE
  745.       .
  746.     OF DOWN_KEY                 !DOWN ARROW KEY
  747.       IF PTR <= RECORDS(TABLE)-COUNT     !  IF THERE ARE MORE ENTRIES
  748.         SCROLL(ROW,COL,ROWS,COLS,ROWS(?POINT)) !  SCROLL THE SCREEN UP
  749.         PTR += 1                 !    SET TO THE NEXT ENTRY
  750.         DO SHOW_RECORD             !    AND DISPLAY THE RECORD
  751.       .
  752.     OF PGDN_KEY                 !PAGE DOWN KEY
  753.       IF PTR >= RECORDS(TABLE)-COUNT+1     !  ON THE LAST PAGE
  754.         NDX = COUNT.             !    POINT TO BOTTOM ITEM
  755.       PTR += COUNT                 !  OTHERWISE
  756.       TBLPTR = -1                 !INITIALIZE TO NO RECORD
  757.       DO SHOW_TABLE                 !    DISPLAY THE NEXT PAGE
  758.  
  759.     OF CTRL_PGDN                 !CTRL-PAGE DOWN KEY
  760.       PTR = RECORDS(TABLE) - COUNT + 1     !  SET TO LAST PAGE
  761.       NDX = COUNT                 !  POINT TO BOTTOM ITEM
  762.       TBLPTR = -1                 !INITIALIZE TO NO RECORD
  763.       DO SHOW_TABLE                 !  DISPLAY THE LAST PAGE
  764.  
  765.     OF UP_KEY                 !UP ARROW KEY
  766.       IF PTR > 1                 !  IF THERE IS A PRIOR RECORD
  767.         PTR -= 1                 !    SET TO PRIOR RECORD
  768.         SCROLL(ROW,COL,ROWS,COLS,-(ROWS(?POINT)))! SCROLL THE SCREEN DOWN
  769.         DO SHOW_RECORD             !    DISPLAY THE RECORD
  770.       .
  771.     OF PGUP_KEY                 !PAGE UP KEY
  772.       IF PTR = 1 THEN NDX = 1.         !  ON FIRST PAGE POINT TO TOP
  773.       PTR -= COUNT                 !  OTHERWISE BACK UP 1 PAGE
  774.       TBLPTR = -1                 !INITIALIZE TO NO RECORD
  775.       DO SHOW_TABLE                 !  AND DISPLAY IT
  776.  
  777.     OF CTRL_PGUP                 !CTRL-PAGE UP
  778.       PTR = 1                 !  POINT TO FIRST RECORD
  779.       NDX = 1                 !  POINT TO TOP ITEM
  780.       TBLPTR = -1                 !INITIALIZE TO NO RECORD
  781.       DO SHOW_TABLE                 !  AND DISPLAY THE FIRST PAGE
  782.     .
  783.   . . .                         !
  784.  
  785.   FREE(TABLE)                     !FREE MEMORY TABLE
  786.   CLEARANCE = SAVE_CLEAR
  787.   RETURN                     !AND RETURN TO CALLER
  788.  
  789. BUILD_TABLE ROUTINE                 !BUILD MEMORY TABLE
  790.   FREE(TABLE)                     !EMPTY THE TABLE
  791.   CLEAR(@PRE:RECORD)                 !MAKE SURE RECORD CLEARED
  792.   @TOTCLEAR                     !ZERO TOTAL FIELDS
  793.   @RESTSELECTS                     !RESTORE SELECTOR CRITERIA
  794.   @READTABLE                     !DO SELECTOR OR FILTER
  795.   TBLPTR = -1                     !INITIALIZE TO NO RECORD
  796.   DO SHOW_TABLE                     !DISPLAY A PAGE OF RECORDS
  797.  
  798. ADD_TABLE ROUTINE                 !ADD ENTRY TO MEMORY TABLE
  799.   @CHECKADD                     !
  800.   IF ~(@FILTER) THEN EXIT.             !  EXIT IF FILTERED OUT
  801.   @SETCOMPONENTS                 !  MOVE KEY COMPONENTS
  802.   TBLPTR = POINTER(@FILENAME)             !  SAVE DATA RECORD POINTER
  803.   ADD(TABLE)                     !  ADD NEW TABLE ENTRY
  804.   IF ERROR()                     !  IF OUT OF MEMORY
  805.     MEM:MESSAGE = ERROR()             !    INFORM USER
  806.     BEEP                     !    SOUND ALARM
  807.   .
  808.   @TOTALCALCSEL                     !CALCULATE TOTAL FIELDS
  809.  
  810. SORT_TABLE ROUTINE                 !SORT TABLE ENTRIES
  811.   TBLPTR# = TBLPTR                 !  SAVE DATA RECORD POINTER
  812.   @SORTTABLE                     !  SORT THE TABLE
  813.   LOOP PTR = 1 TO RECORDS(TABLE)         !  LOOK UP THE SAVED POINTER
  814.     GET(TABLE,PTR)                 !    SO WE WILL STILL POINT
  815.     IF TBLPTR = TBLPTR# THEN EXIT.         !    AT THE SAME RECORD
  816.   .
  817.  
  818. SHOW_TABLE ROUTINE                 !DISPLAY A PAGE OF RECORDS
  819.   IF PTR > RECORDS(TABLE)-COUNT+1         !  FOR A PARTIAL PAGE
  820.     PTR = RECORDS(TABLE)-COUNT+1.         !    SET TO THE LAST RECORD
  821.   IF PTR < 1 THEN PTR = 1.             !    AND BACK UP ONE PAGE
  822.   TBLPTR# = TBLPTR                 !  SAVE DATA RECORD POINTER
  823.   NDX# = NDX                     !  SAVE REPEAT INDEX
  824.   LOOP NDX = 1 TO COUNT                 !  LOOP THRU THE SCROLL AREA
  825.     DO SHOW_RECORD                 !    DISPLAY A RECORD
  826.     IF TBLPTR# = TBLPTR THEN NDX# = NDX.     !    POINT TO CORRECT RECORD
  827.   .                         !
  828.   NDX = NDX#                     !  RESTORE REPEAT INDEX
  829.   IF NDX > RECORDS(TABLE) THEN NDX = RECORDS(TABLE).!SHOWING THE LAST
  830.   CLEAR(@PRE:RECORD)                 !  CLEAR RECORD AREA
  831.   IF RECORDS(TABLE) < COUNT             !  IF RECORDS DO NOT FILL
  832.      NDX#= RECORDS(TABLE) * @PROWS         !     GET NUMBER TIMES SIZE
  833.      BLANK(ROW + NDX#,COL,ROWS-NDX#,COLS)     !     BLANK REMAINING AREA
  834.   .
  835.  
  836. SHOW_RECORD ROUTINE                 !DISPLAY A RECORD
  837.   TBLPTR = 0                     !  START WITH NO RECORD
  838.   GET(TABLE,PTR+NDX-1)                 !  GET THE TABLE ENTRY
  839.   IF ~ERROR()                     !  IF THERE IS ONE
  840.     GET(@FILENAME,TBLPTR)             !    READ A DATA RECORD
  841.     IF ~ERROR()
  842.       @RESTSELECTS                 !    RESTORE SELECTOR FIELDS
  843.       DO SHOW_LINE                 !    DISPLAY SCROLLING LINE
  844.   . .
  845.  
  846. SHOW_LINE    ROUTINE                 !DISPLAY SCROLLING LINE
  847.   @LOOKUPSCROLL                     !    DISPLAY FROM OTHER FILES
  848.   @SHOWSCROLL                     !    DISPLAY STRING VARIABLES
  849.   @COMPUTESCROLL                 !    DISPLAY COMPUTED FIELDS
  850.   @CONDITIONALSCRL                 !    DISPLAY CONDITIONAL FIELDS
  851.   @RESULTSCROLL                     !    ASSIGN RESULT FIELDS
  852.  
  853. GET_RECORD ROUTINE                 !READ SELECTED RECORD
  854.   GET(TABLE,PTR+NDX-1)                 !  GET THE TABLE ENTRY
  855.   GET(@FILENAME,TBLPTR)                 !  READ THE DATA RECORD
  856.  
  857. FIND_RECORD ROUTINE                 !LOCATE REQUESTED RECORD
  858.   @SETCOMPONENTS                 !  MOVE THEM TO THE TABLE
  859.   GET(TABLE,KEY)                 !  GET THE TABLE ENTRY
  860.   PTR = POINTER(TABLE)                 !  SET RECORD POINTER
  861.   IF ~PTR THEN PTR = RECORDS(TABLE).         !  SET TO LAST IF NO POINTER
  862.   GET(TABLE,PTR)                 !  AND READ THE DATA RECORD
  863.   DO SHOW_TABLE                     !  DISPLAY THAT PAGE
  864.  
  865. SAME_PAGE ROUTINE                 !SET TO SAME PAGE ROUTINE
  866.   DO SORT_TABLE                     !  SORT THE TABLE
  867.  
  868. @COMPUTETOTS                     !CALCULATE TOTAL FIELDS
  869. *FORM***************************************************************************
  870. @PROCNAME    PROCEDURE
  871.  
  872. SCREEN         SCREEN      PRE(SCR),@SCREENOPT
  873.               @PAINTS
  874.               @STRINGS
  875.               @VARIABLES
  876.               ENTRY,USE(?FIRST_FIELD)
  877.               @FIELDS
  878.               @PAUSE
  879.               ENTRY,USE(?LAST_FIELD)
  880.               PAUSE(''),USE(?DELETE_FIELD)
  881.          .
  882.  
  883. SAVE_RECORD  GROUP;BYTE,DIM(SIZE(@PRE:RECORD)).
  884. SAVE_MEMO    GROUP;BYTE,DIM(SIZE(@MEMO)).
  885.  
  886.   EJECT
  887.   CODE
  888.   OPEN(SCREEN)                     !OPEN THE SCREEN
  889.   SETCURSOR                     !TURN OFF ANY CURSOR
  890.   SAVE_RECORD = @PRE:RECORD             !SAVE THE ORIGINAL
  891.   SAVE_MEMO   = @MEMO                 !SAVE THE ORIGINAL
  892.   IF ACTION = 5                     !AUTONUMBER ACTION
  893.     DISK_ACTN# = 2                 !  SET FOR PHYSICAL ACTION
  894.     ACTION = 1                     !  SET FOR LOGICAL ACTION
  895.   ELSE                         !OTHERWISE
  896.     DISK_ACTN# = ACTION                 !  SET ACTION FOR DISK WRITE
  897.   .
  898.   SAVE_CLEAR = CLEARANCE             ! SAVE SECURITY CLEARANCE
  899.                          ! OF CALLER
  900.  
  901.   CLEARANCE = 0                     ! ASSUME NO SECURITY
  902.  
  903.   @SETUP                     !CALL SETUP PROCEDURE
  904.  
  905.   IF NOT CHECK_PASS()                 ! IF THEY DO NOT HAVE
  906.      CLEARANCE = SAVE_CLEAR             ! SECURITY CLEARANCES
  907.      RETURN                     ! THEN EXIT
  908.   .
  909.  
  910.   DISPLAY                     !DISPLAY THE FIELDS
  911.  
  912.   EXECUTE DISK_ACTN#                 !SET THE CURRENT RECORD POINTER
  913.     POINTER# = 0                 !  NO RECORD FOR ADD
  914.     POINTER# = POINTER(@FILENAME)         !  CURRENT RECORD FOR CHANGE
  915.     POINTER# = POINTER(@FILENAME)         !  CURRENT RECORD FOR CHANGE
  916.   .
  917.   ACTION# = ACTION                 !STORE REQUIRED ACTION
  918.   LOOP                         !LOOP THRU ALL THE FIELDS
  919.     MEM:MESSAGE = CENTER(MEM:MESSAGE,SIZE(MEM:MESSAGE)) !DISPLAY ACTION MESSAGE
  920.     @LOOKUPS                     !DISPLAY FROM OTHER FILES
  921.     @SHOW                     !DISPLAY STRING VARIABLES
  922.     @COMPUTE                     !DISPLAY COMPUTED FIELDS
  923.     @CONDITIONAL                 !DISPLAY CONDITIONAL FIELDS
  924.     @RESULT                     !MOVE RESULTING VALUES
  925.     ALERT                     !RESET ALERTED KEYS
  926.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  927.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  928.     @ALERT                     !ALERT HOT KEY
  929.     ACCEPT                     !READ A FIELD
  930.     @CHECKHOT                     !ON HOT KEY, CALL PROCEDURE
  931.     IF KEYCODE() = REJECT_KEY             !RETURN ON SCREEN REJECT KEY
  932.     CLEARANCE = SAVE_CLEAR             ! RESTORE CLEARANCE
  933.     RETURN
  934.     .
  935.     EXECUTE ACTION                 !SET MESSAGE
  936.       MEM:MESSAGE = 'Record will be Added'     !
  937.       MEM:MESSAGE = 'Record will be Changed'     !
  938.       MEM:MESSAGE = 'Press Enter to Delete'     !
  939.     .
  940.     EDIT_RANGE# = FIELD()             !SET ONE FIELD EDIT RANGE
  941.     IF KEYCODE() = ACCEPT_KEY             !ON SCREEN ACCEPT KEY
  942.       UPDATE                     !  MOVE ALL FIELDS FROM SCREEN
  943.       EDIT_RANGE# = FIELDS()             !  AND EDIT REMAINING FIELDS
  944.     .                         !
  945.     LOOP FIELD# = FIELD() TO EDIT_RANGE#     !EDIT FIELDS IN THE EDIT RANGE
  946.       CASE FIELD#                 !JUMP TO FIELD EDIT ROUTINE
  947.       OF ?FIRST_FIELD                 !FROM THE FIRST FIELD
  948.     IF KEYCODE() = ESC_KEY             !  RETURN ON ESC KEY
  949.        CLEARANCE = SAVE_CLEAR         !  RESTORE CLEARANCE
  950.        RETURN
  951.     .
  952.     IF ACTION = 3 THEN SELECT(?DELETE_FIELD).!  OR CONFIRM FOR DELETE
  953.  
  954.       @EDITS                     !EDIT ROUTINES GO HERE
  955.       OF ?LAST_FIELD                 !FROM THE LAST FIELD
  956.     IF ACTION = 2 OR ACTION = 3         !IF UPDATING RECORD
  957.       HOLD(@FILENAME)             !  HOLD FILE
  958.       GET(@FILENAME,POINTER#)         !  RE-READ SAME RECORD
  959.       IF ERRORCODE() = 35             !  IF RECORD WAS DELETED
  960.         IF ACTION = 2             !  IF TRYING TO UPDATE
  961.            ACTION = 1             !    THEN ADD IT BACK
  962.         ELSE                 !
  963.            RELEASE(@FILENAME)         !  RELEASE FILE
  964.            ACTION = 0             !  TURN OFF ACTION
  965.         .
  966.       ELSIF |                 !  IF IT HAS BEEN CHANGED
  967.         @MEMO <> SAVE_MEMO OR |         !
  968.         @PRE:RECORD <> SAVE_RECORD         !    BY ANOTHER STATION
  969.         MEM:MESSAGE = 'CHANGED BY ANOTHER STATION' !INFORM USER
  970.         SELECT(2)                 !  GO BACK TO FIELD 1
  971.         BEEP                 !  SOUND ALARM
  972.         RELEASE(@FILENAME)             !  RELEASE FILE
  973.         SAVE_RECORD = @PRE:RECORD         !  SAVE RECORD
  974.         SAVE_MEMO = @MEMO             !  SAVE MEMO
  975.         DISPLAY                 !  DISPLAY THE FIELDS
  976.         BREAK                 !  AND CONTINUE
  977.       .
  978.       UPDATE                 !UPDATE FROM SCREEN TO RECORD
  979.       @RESULT                 !MOVE RESULTING VALUES
  980.     .
  981.     EXECUTE DISK_ACTN#             !  UPDATE THE FILE
  982.       ADD(@FILENAME)             !    ADD NEW RECORD
  983.       PUT(@FILENAME)             !    CHANGE EXISTING RECORD
  984.       DELETE(@FILENAME)             !    DELETE EXISTING RECORD
  985.     .
  986.     IF ERRORCODE() = 40             !  DUPLICATE KEY ERROR
  987.       MEM:MESSAGE = ERROR()             !    DISPLAY ERR MESSAGE
  988.       SELECT(2)                 !    POSITION TO TOP OF FORM
  989.       IF ACTION = 2 THEN RELEASE(@FILENAME). !    RELEASE HELD RECORD
  990.       BREAK                     !    GET OUT OF EDIT LOOP
  991.     ELSIF ERROR()                 !  CHECK FOR UNEXPECTED ERROR
  992.       STOP(ERROR())                 !    HALT EXECUTION
  993.     .
  994.  
  995.     PUT(@FILENAME2)                 !  UPDATE SECONDARY FILES
  996.     PUT(@FILENAME3)                 !  UPDATE SECONDARY FILES
  997.     PUT(@FILENAME4)                 !  UPDATE SECONDARY FILES
  998.     IF ACTION = 1 THEN POINTER# = POINTER(@FILENAME). !POINT TO RECORD
  999.     SAVE_RECORD = @PRE:RECORD         !  NEW ORIGINAL
  1000.     SAVE_MEMO   = @MEMO             !  NEW ORIGINAL
  1001.     ACTION = ACTION#             !  RETRIEVE ORIGINAL OPERATION
  1002.     @NEXTFORM                 !  CALL NEXT FORM PROCEDURE
  1003.     ACTION = 0                 !  SET ACTION TO COMPLETE
  1004.     CLEARANCE = SAVE_CLEAR             !  RESTORE CLEARANCE
  1005.     RETURN                     !  AND RETURN TO CALLER
  1006.  
  1007.       OF ?DELETE_FIELD                 !FROM THE DELETE FIELD
  1008.     IF KEYCODE() = ENTER_KEY |         !  ON ENTER KEY
  1009.     OR KEYCODE() = ACCEPT_KEY         !  OR CTRL-ENTER KEY
  1010.       SELECT(?LAST_FIELD)             !    DELETE THE RECORD
  1011.     ELSE                     !  OTHERWISE
  1012.       BEEP                     !    BEEP AND ASK AGAIN
  1013.   . . . .
  1014.  
  1015. *MEMFORM************************************************************************
  1016. @PROCNAME    PROCEDURE
  1017.  
  1018. SCREEN         SCREEN      PRE(SCR),@SCREENOPT
  1019.               @PAINTS
  1020.               @STRINGS
  1021.               @VARIABLES
  1022.               ENTRY,USE(?FIRST_FIELD)
  1023.               @FIELDS
  1024.               @PAUSE
  1025.               ENTRY,USE(?LAST_FIELD)
  1026.          .
  1027.  
  1028.   EJECT
  1029.   CODE
  1030.   OPEN(SCREEN)                     !OPEN THE SCREEN
  1031.   SETCURSOR                     !TURN OFF ANY CURSOR
  1032.   SAVE_CLEAR = CLEARANCE             ! SAVE SECURITY CLEARANCE
  1033.                          ! OF CALLER
  1034.  
  1035.   CLEARANCE = 0                     ! ASSUME NO SECURITY
  1036.  
  1037.   @SETUP                     !CALL SETUP PROCEDURE
  1038.  
  1039.   IF NOT CHECK_PASS()                 ! IF THEY DO NOT HAVE
  1040.      CLEARANCE = SAVE_CLEAR             ! SECURITY CLEARANCES
  1041.      RETURN                     ! THEN EXIT
  1042.   .
  1043.  
  1044.   DISPLAY                     !DISPLAY THE FIELDS
  1045.   LOOP                         !LOOP THRU ALL THE FIELDS
  1046.     @LOOKUPS                     !DISPLAY FROM OTHER FILES
  1047.     @SHOW                     !DISPLAY STRING VARIABLES
  1048.     @COMPUTE                     !DISPLAY COMPUTED FIELDS
  1049.     @CONDITIONAL                 !DISPLAY CONDITIONAL FIELDS
  1050.     @RESULT                     !MOVE RESULTING VALUES
  1051.     ALERT                     !RESET ALERTED KEYS
  1052.     ALERT(ACCEPT_KEY)                 !ALERT SCREEN ACCEPT KEY
  1053.     ALERT(REJECT_KEY)                 !ALERT SCREEN REJECT KEY
  1054.     @ALERT                     !ALERT HOT KEY
  1055.     ACCEPT                     !READ A FIELD
  1056.     @CHECKHOT                     !ON HOT KEY, CALL PROCEDURE
  1057.     IF KEYCODE() = REJECT_KEY             !RETURN ON SCREEN REJECT KEY
  1058.        CLEARANCE = SAVE_CLEAR             !  RESTORE CLEARANCE
  1059.        RETURN
  1060.     .
  1061.     EDIT_RANGE# = FIELD()             !SET ONE FIELD EDIT RANGE
  1062.     IF KEYCODE() = ACCEPT_KEY             !ON SCREEN ACCEPT KEY
  1063.       UPDATE                     !  MOVE ALL FIELDS FROM SCREEN
  1064.       EDIT_RANGE# = FIELDS()             !  AND EDIT REMAINING FIELDS
  1065.     .                         !
  1066.     LOOP FIELD# = FIELD() TO EDIT_RANGE#     !EDIT FIELDS IN THE EDIT RANGE
  1067.       CASE FIELD#                 !JUMP TO FIELD EDIT ROUTINE
  1068.       OF ?FIRST_FIELD                 !FROM THE FIRST FIELD
  1069.     IF KEYCODE() = ESC_KEY             !  RETURN ON ESC KEY
  1070.         CLEARANCE = SAVE_CLEAR         !  RESTORE CLEARANCE
  1071.         RETURN
  1072.     .
  1073.  
  1074.       @EDITS                     !EDIT ROUTINES GO HERE
  1075.       OF ?LAST_FIELD                 !FROM THE LAST FIELD
  1076.     PUT(@FILENAME2)                 !  UPDATE SECONDARY FILES
  1077.     PUT(@FILENAME3)                 !  UPDATE SECONDARY FILES
  1078.     PUT(@FILENAME4)                 !  UPDATE SECONDARY FILES
  1079.     @NEXTFORM                 !  CALL NEXT FORM PROCEDURE
  1080.     ACTION = 0                 !  SET ACTION TO COMPLETE
  1081.     CLEARANCE = SAVE_CLEAR             !  RESTORE CLEARANCE
  1082.     RETURN                     !  AND RETURN TO CALLER
  1083.   . . .
  1084.  
  1085. *REPORT*************************************************************************
  1086.  
  1087. @PROCNAME    PROCEDURE
  1088.  
  1089. REPORT         @REPORT
  1090.  
  1091. @SAVEITEMS
  1092.  
  1093.   CODE
  1094.   DONE# = 0                     !TURN OFF DONE FLAG
  1095.   SAVE_CLEAR = CLEARANCE             ! SAVE SECURITY CLEARANCE
  1096.                          ! OF CALLER
  1097.  
  1098.   CLEARANCE = 0                     ! ASSUME NO SECURITY
  1099.  
  1100.   @SETUP                     !CALL SETUP PROCEDURE
  1101.  
  1102.   IF NOT CHECK_PASS()                 ! IF THEY DO NOT HAVE
  1103.      CLEARANCE = SAVE_CLEAR             ! SECURITY CLEARANCES
  1104.      RETURN                     ! THEN EXIT
  1105.   .
  1106.  
  1107.   @INITSELECTS                     !SAVE SELECTOR FIELDS
  1108.   CLEAR(@PRE:RECORD)                 !MAKE SURE RECORD CLEARED
  1109.   @RESTSELECTS                     !RESTORE SELECTOR CRITERIA
  1110.   BUILD(@INDEX)                     !BUILD FILE INDEX
  1111.   @INITREPORT                     !INIT REPORT VARIABLES
  1112.   @RPTHEADER                     !DO REPORT HEADER COMPUTES
  1113.   PRINT(TTL:RPT_HEAD)                 !PRINT TITLE PAGE
  1114.   @PRINTMEMO                     !PRINT ANY MEMO FILES
  1115.   CLOSE(TITLE)                     !CLOSE TITLE REPORT
  1116.   @SETFILE                     !SET TO FIRST RECORD
  1117.   @PAGEFOOTER                     !DO PAGE FOOTER COMPUTES
  1118.   @PAGEHEADER                     !DO PAGE HEADER COMPUTES
  1119.   DO NEXT_RECORD                 !READ FIRST RECORD
  1120.   @PAGEHEADER                     !DO PAGE HEADER COMPUTES
  1121.   OPEN(REPORT)                     !OPEN THE REPORT
  1122.   @FIRSTBREAK                     !PRINT INITIAL BREAK HEADERS
  1123.   LOOP UNTIL DONE#                 !READ ALL RECORDS IN FILE
  1124.     SAVE_LINE# = MEM:LINE             !  SAVE LINE NUMBER
  1125.     LAST_REC# = POINTER(@FILENAME)
  1126.     @RUNTOTALS                     !  ACCUMULATE RUNNING TOTALS
  1127.     @INITDETAIL                     !  SET UP FOR DETAIL LINE
  1128.     PRINT(RPT:DETAIL)                 !  PRINT DETAIL LINES
  1129.     DO CHECK_PAGE                 !  DO PAGE BREAK IF NEEDED
  1130.     @PRINTMEMO                     !  PRINT ANY MEMO FIELD
  1131.     @TOTALS                     !  ACCUMULATE TOTALS
  1132.     @PAGEFOOTER                     !  DO PAGE FOOTER COMPUTES
  1133.     @PAGEHEADER                     !  DO PAGE HEADER COMPUTES
  1134.     @PAGEEJECT                     !  GO TO NEW PAGE
  1135.     DO NEXT_RECORD                 !  GET NEXT RECORD
  1136.     @CHECKBREAK                     !  CHECK FOR BREAK
  1137.   .                         !
  1138.   @LASTBREAK                     !  PRINT ENDING BREAK FOOTERS
  1139.   @RPTFOOTER                     !DO REPORT FOOTER COMPUTES
  1140.   PRINT(RPT:RPT_FOOT)                 !PRINT GRAND TOTALS
  1141.   DO CHECK_PAGE                     !  DO PAGE BREAK IF NEEDED
  1142.   @PRINTMEMO                     !  PRINT ANY MEMO FIELD
  1143.   CLOSE(REPORT)                     !CLOSE REPORT
  1144.   CLEARANCE = SAVE_CLEAR             !  RESTORE CLEARANCE
  1145.   RETURN                     !RETURN TO CALLER
  1146.  
  1147.  
  1148. NEXT_RECORD ROUTINE                 !GET NEXT RECORD
  1149.   LOOP UNTIL EOF(@FILENAME)             !  READ UNTIL END OF FILE
  1150.     NEXT(@FILENAME)                 !    READ NEXT RECORD
  1151.     @CHECKSELECT                 !    STOP IF PAST SELECTOR
  1152.     @DETAIL                     !    DO DETAIL COMPUTES
  1153.     IF ~(@FILTER) THEN CYCLE.             !    IF FILTERED OUT, GET NEXT
  1154.     EXIT                     !    EXIT THE ROUTINE
  1155.   .                         !
  1156.   DONE# = 1                     !  ON EOF, SET DONE FLAG
  1157.  
  1158. CHECK_PAGE ROUTINE                 !CHECK FOR NEW PAGE
  1159.   IF MEM:LINE <= SAVE_LINE#             !  ON PAGE OVERFLOW
  1160.     SAVE_LINE# = MEM:LINE             !    RESET LINE NUMBER
  1161.     @INITPAGE                     !    INIT PAGE VARIABLES
  1162.   .
  1163.   LOOP UNTIL NOT KEYBOARD()             !LOOK FOR KEYSTROKE
  1164.     ASK
  1165.     IF KEYCODE() = REJECT_KEY             !ABORT REPORT
  1166.        CLEARANCE = SAVE_CLEAR             ! RESTORE CLEARANCE
  1167.        RETURN
  1168.     .
  1169.   .
  1170.  
  1171. @BREAKRTN                     !CHECK FOR GROUP BREAK
  1172.  
  1173. *MEMREPORT**********************************************************************
  1174.  
  1175. @PROCNAME    PROCEDURE
  1176.  
  1177. REPORT         @REPORT
  1178.  
  1179.   CODE
  1180.   SAVE_CLEAR = CLEARANCE             ! SAVE SECURITY CLEARANCE
  1181.                          ! OF CALLER
  1182.  
  1183.   CLEARANCE = 0                     ! ASSUME NO SECURITY
  1184.  
  1185.   @SETUP                     !CALL SETUP PROCEDURE
  1186.  
  1187.   IF NOT CHECK_PASS()                 ! IF THEY DO NOT HAVE
  1188.      CLEARANCE = SAVE_CLEAR             ! SECURITY CLEARANCES
  1189.      RETURN                     ! THEN EXIT
  1190.   .
  1191.  
  1192.   @INITREPORT                     !INIT REPORT VARIABLES
  1193.   @RPTHEADER                     !DO REPORT HEADER COMPUTES
  1194.   PRINT(TTL:RPT_HEAD)                 !PRINT TITLE PAGE
  1195.   @MEMMEMO                     !PRINT ANY MEMO FILES
  1196.   CLOSE(TITLE)                     !CLOSE TITLE REPORT
  1197.   @PAGEFOOTER                     !DO PAGE FOOTER COMPUTES
  1198.   @PAGEHEADER                     !DO PAGE HEADER COMPUTES
  1199.   OPEN(REPORT)                     !OPEN REPORT BODY
  1200.   @MEMMEMO                     !PRINT ANY MEMO FIELD
  1201.   @DETAIL                     !DO DETAIL COMPUTES
  1202.   @RUNTOTALS                     !ACCUMULATE RUNNING TOTALS
  1203.   @INITDETAIL                     !SET UP FOR DETAIL RECORD
  1204.   PRINT(RPT:DETAIL)                 !PRINT DETAIL LINES
  1205.   @MEMMEMO                     !PRINT ANY MEMO FIELD
  1206.   @TOTALS                     !ACCUMULATE TOTALS
  1207.   @MEMMEMO                     !PRINT ANY MEMO FIELD
  1208.   @PAGEFOOTER                     !DO PAGE FOOTER COMPUTES
  1209.   @RPTFOOTER                     !DO REPORT FOOTER COMPUTES
  1210.   PRINT(RPT:RPT_FOOT)                 !PRINT REPORT FOOTER
  1211.   @MEMMEMO                     !PRINT ANY MEMO FIELD
  1212.   CLOSE(REPORT)                     !CLOSE REPORT
  1213.   CLEARANCE = SAVE_CLEAR             ! RESTORE CLEARANCE
  1214.   RETURN                     !RETURN TO CALLER
  1215.  
  1216. *PRINTMEMO**********************************************************************
  1217.     @MEMOLEN                     !DETERMINE MEMO SIZE
  1218.     J# = 2                     !START WITH SECOND ROW
  1219.     LOOP                     !LOOP THRU ALL USED ROWS
  1220.       MEMODONE# = 0                 !  NO MEMOS DONE YET
  1221.       @SETMEMO                     !  SET THE MEMO VARIABLES
  1222.       IF MEMODONE# = 0                 !  ALL MEMOS PRINTED
  1223.     DO CHECK_PAGE                 !  DO PAGE BREAK IF NEEDED
  1224.     BREAK                     !  EXIT MEMO PRINT LOOP
  1225.       .                         !
  1226.       @PRTDETAIL                 !  AND PRINT IT
  1227.       J# += 1                     !  INCREMENT COUNTER
  1228.       DO CHECK_PAGE                 !  DO PAGE BREAK IF NEEDED
  1229.     .
  1230. *SETMEMO************************************************************************
  1231.       IF J# <= @MEMOTMP#             !IF IN THE RANGE OF THIS MEMO
  1232.     @MEMOVAR = @MEMOROW[J#]             !  MOVE A MEMO FIELD ROW
  1233.     MEMODONE# = 1                 !  MEMO HAS BEEN MOVED
  1234.       ELSE                     !OTHERWISE
  1235.     @MEMOVAR = ''                 !  NO MEMO TO DO
  1236.       .                         ! END OF SETMEMO
  1237. *MEMOLEN************************************************************************
  1238.     LOOP @MEMOTMP# = @MEMOSIZE TO 2 BY -1     !BACKSCAN THE MEMO FIELD TO
  1239.       IF @MEMOROW[@MEMOTMP#] <> '' THEN BREAK. ! FIND NUMBER OF ROWS USED
  1240.     .                         ! END OF MEMOLEN
  1241. *PRTDETAIL**********************************************************************
  1242.     PRINT(@MEMDETAIL)                 !PRINT THE DETAIL RECORD
  1243. *MEMMEMO************************************************************************
  1244.   @MEMOLEN                     !DETERMINE MEMO SIZE
  1245.   J# = 2                     !START WITH ROW 2
  1246.   LOOP                         !LOOP THRU ALL USED ROWS
  1247.     MEMODONE# = 0                 !  NO MEMOS DONE YET
  1248.     @SETMEMO                     !  SET THE MEMO VARIABLES
  1249.     IF MEMODONE# = 0 THEN BREAK.         !  ALL MEMOS PRINTED
  1250.     @PRTDETAIL                     !  AND PRINT IT
  1251.     J# += 1                     !  INCREMENT COUNTER
  1252.   .
  1253. *ALERT**************************************************************************
  1254.     ALERT(@HOTKEY)                 !ALERT HOT KEY
  1255. *TODO***************************************************************************
  1256. @PROCNAME    PROCEDURE                 !THIS PROCEDURE IS NOT DEFINED
  1257.  
  1258.   CODE                         !
  1259.   RETURN                     !RETURN TO CALLER
  1260. *SHOWMEMO***********************************************************************
  1261.     R# = ROW(@SCRMEMO)                 !SAVE ROW OF MEMO
  1262.     C# = COL(@SCRMEMO)                 !SAVE COL OF MEMO
  1263.     SETHUE(FOREHUE(R#,C#),BACKHUE(R#,C#))     !RETRIEVE COLOR OF MEMO
  1264.     LOOP I# = 1 TO @MEMOROWS             !DISPLAY MEMO FIELD BY ROWS
  1265.       SHOW(R#+I#-1,C#,@MEMOROW[I#],@S@MEMOCOLS)     !SHOW NEXT ROW
  1266.     .
  1267.     SETHUE                     !TURN OFF COLOR
  1268. *INRANGE************************************************************************
  1269.     IF ~INRANGE(@FIELD,@LOWER,@UPPER)     !IF FIELD IS OUT OF RANGE
  1270.       BEEP                     !  SOUND KEYBOARD ALARM
  1271.       SELECT(?@FIELD)             !  AND STAY ON THIS FIELD
  1272.       BREAK                     !
  1273.     .
  1274. *REQUIRED***********************************************************************
  1275.     IF @FIELD = ''                 !IF REQUIRED FIELD IS EMPTY
  1276.       BEEP                     !  SOUND KEYBOARD ALARM
  1277.       SELECT(?@FIELD)             !  AND STAY ON THIS FIELD
  1278.       BREAK                     !
  1279.     .
  1280. *NOTREQUIRED********************************************************************
  1281.     IF @FIELD = ''                 !IF NOT REQUIRED THEN
  1282.       @EDITPROC                 !  CALL THE EDIT PROCEDURE
  1283.       CYCLE                     !  END THE EDIT
  1284.     .
  1285. *UNIQUEKEY**********************************************************************
  1286.     GET(@FILENAME,@ACCESSKEY)         !READ THE RECORD BY KEY
  1287.     IF NOT ERROR()                 !IF A RECORD IS FOUND
  1288.       IF POINTER(@FILENAME) <> POINTER#     !  BUT NOT THE SAME RECORD
  1289.         CLEAR(@PRE:RECORD)             !    CLEAR IN CASE OF ADD
  1290.         GET(@FILENAME,POINTER#)         !    RE-READ THE OLD RECORD
  1291.         UPDATE                 !    RE-UPDATE THE RECORD
  1292.         MEM:MESSAGE = 'CREATES DUPLICATE KEY'!    MOVE AN ERROR MESSAGE
  1293.         SELECT(?@FIELD)             !    STAY ON THE SAME FIELD
  1294.         BEEP                 !    SOUND THE KEYBOARD ALARM
  1295.         BREAK                 !    AND LOOP AGAIN
  1296.     . .
  1297.     GET(@FILENAME,POINTER#)             !  RE-READ THE OLD RECORD
  1298.     UPDATE                     !  AND RE-UPDATE THE RECORD
  1299. *SETTOP*************************************************************************
  1300.   SET(@KEYNAME)                     !SET TO FIRST RECORD
  1301. *SETSELECT**********************************************************************
  1302.   SET(@KEYNAME,@KEYNAME)             !SET TO FIRST SELECTED RECORD
  1303. *INITLOCATE*********************************************************************
  1304.     OF ?PRE_POINT                 !
  1305.       IF KEYCODE() = ESC_KEY OR |         !  IF GOING UP
  1306.       KEYCODE() = UP_KEY OR |             !    THE SCREEN
  1307.       RECORDS# = FALSE                 !    OR NO RECORDS ON SCREEN
  1308.     SCR:LOCATOR = ''             !    CLEAR LOCATOR
  1309.     SELECT(?-1)                 !    AND GO TO PREVIOUS FIELD
  1310.     SETCURSOR                 !    AND TURN CURSOR OFF
  1311.       ELSE                     !  OTHERWISE, GOING DOWN
  1312.     LEN# = 0                 !    RESET TO START OF LOCATOR
  1313.     SETCURSOR(ROW(SCR:LOCATOR),COL(SCR:LOCATOR)) !AND TURN CURSOR ON
  1314.       .
  1315. *PREPOINT***********************************************************************
  1316.               ENTRY,USE(?PRE_POINT)
  1317. *LOCATE*************************************************************************
  1318.       IF KEYCODE() > 31               |     !THE DISPLAYABLE CHARACTERS
  1319.       AND KEYCODE() < 255             !ARE USED TO LOCATE RECORDS
  1320.     IF LEN# < SIZE(SCR:LOCATOR)         !  IF THERE IS ROOM LEFT
  1321.       SCR:LOCATOR = SUB(SCR:LOCATOR,1,LEN#) & CHR(KEYCODE())
  1322.       LEN# += 1                 !    INCREMENT THE LENGTH
  1323.     .
  1324.       ELSIF KEYCODE() = BS_KEY             !BACKSPACE UNTYPES A CHARACTER
  1325.     IF LEN# > 0                 !  IF THERE ARE CHARACTERS LEFT
  1326.       LEN# -= 1                 !    DECREMENT THE LENGTH
  1327.       SCR:LOCATOR = SUB(SCR:LOCATOR,1,LEN#)     !    ERASE THE LAST CHARACTER
  1328.     .
  1329.       ELSE                     !FOR ANY OTHER CHARACTER
  1330.     LEN# = 0                 !  ZERO THE LENGTH
  1331.     SCR:LOCATOR = ''             !  ERASE THE LOCATOR FIELD
  1332.       .
  1333.       SETCURSOR(ROW(SCR:LOCATOR),COL(SCR:LOCATOR)+LEN#) !AND RESET THE CURSOR
  1334.       @SETLOCATE
  1335.       IF KEYBOARD() > 31           |     !THE DISPLAYABLE CHARACTERS
  1336.       AND KEYBOARD() < 255           |     !ARE USED TO LOCATE RECORDS
  1337.       OR  KEYBOARD() = BS_KEY             !INCLUDE BACKSPACE
  1338.     CYCLE
  1339.       .
  1340.       IF LEN# > 0 THEN DO FIND_RECORD.         !    AND FIND THE RECORD
  1341. *STRLOCATE**********************************************************************
  1342.       @LOCFIELD = CLIP(SCR:LOCATOR)         !    UPDATE THE KEY FIELD
  1343. *PICLOCATE**********************************************************************
  1344.       @LOCFIELD = DEFORMAT(SCR:LOCATOR)         !    UPDATE THE KEY FIELD
  1345. *SELECTOR***********************************************************************
  1346.       SET(@KEYNAME,@KEYNAME)             !SET AT FIRST SELECTED RECORD
  1347.       LOOP UNTIL EOF(@FILENAME)             !LOOP UNTIL END OF FILE
  1348.     NEXT(@FILENAME)                 !  READ A RECORD
  1349.     @CHECKSELECT                 !  CHECK THAT IT IS SELECTED
  1350.     DO ADD_TABLE                 !  AND ADD TO MEMORY TABLE
  1351.       .
  1352. *FILTER*************************************************************************
  1353.       BUFFER(@FILENAME,.25)             !USE 1/4TH OF MEMORY FOR BUFFER
  1354.       SET(@FILENAME)                 !READ DATA RECORD SEQUENCE
  1355.       LOOP UNTIL EOF(@FILENAME)             !LOOP UNTIL END OF FILE
  1356.     NEXT(@FILENAME)                 !  READ A RECORD
  1357.     DO ADD_TABLE                 !  ADD IT TO MEMORY TABLE
  1358.       .
  1359.       FREE(@FILENAME)                 !FREE MEMORY USED FOR BUFFERING
  1360.       DO SORT_TABLE                 !SORT TABLE INTO KEY SEQUENCE
  1361.       PTR = 1                     !DISPLAY FROM TOP OF TANLE
  1362. *VALIDATE***********************************************************************
  1363.     @ACCESSFIELD = @FIELD             !MOVE RELATED FIELDS
  1364.     GET(@FILENAME,@ACCESSKEY)         !READ THE RECORD
  1365.     IF ERROR()                 !IF NO RECORD IS FOUND
  1366.       MEM:MESSAGE = 'RECORD NOT FOUND'     !  MOVE AN ERROR MESSAGE
  1367.       BEEP                     !  SOUND THE KEYBOARD ALARM
  1368.       SELECT(?@FIELD)             !  AND STAY ON THE SAME FIELD
  1369.     .
  1370. *ENTERTABLE*********************************************************************
  1371.     @ACCESSFIELD = @FIELD             !MOVE RELATED FIELDS
  1372.     GET(@FILENAME,@ACCESSKEY)         !READ THE RECORD
  1373.     IF ERROR()                 !IF NO RECORD IS FOUND
  1374.       ACTION# = ACTION             !  SAVE ACTION
  1375.       ACTION = 4                 !  REQUEST TABLE LOOKUP
  1376.       @LOOKUP                 !  CALL LOOKUP PROCEDURE
  1377.       IF ACTION                 !  NO SELECTION WAS MADE
  1378.         SELECT(?@FIELD)             !    STAY ON FIELD
  1379.         ACTION = ACTION#             !    RESTORE ACTION
  1380.         CYCLE                 !    GO TO TOP OF LOOP
  1381.       .
  1382.       @FIELD = @ACCESSFIELD             !  MOVE LOOKUP FIELD
  1383.       DISPLAY(?@FIELD)             !  AND DISPLAY IT
  1384.       ACTION = ACTION#             !  RESTORE ACTION
  1385.     .
  1386. *AUTOTABLE**********************************************************************
  1387.     @ACCESSFIELD = @FIELD             !MOVE RELATED FIELDS
  1388.     GET(@FILENAME,@ACCESSKEY)         !READ THE RECORD
  1389.     ACTION# = ACTION             !SAVE ACTION
  1390.     ACTION = 4                 !REQUEST TABLE LOOKUP
  1391.     @LOOKUP                     !CALL LOOKUP PROCEDURE
  1392.     IF ACTION                 !NO SELECTION WAS MADE
  1393.       SELECT(?@FIELD-1)             ! BACK UP ONE FIELD
  1394.       ACTION = ACTION#             ! RESTORE ACTION
  1395.       CYCLE                     ! GO TO TOP OF LOOP
  1396.     .
  1397.     @LOOKFIELD = @ACCESSFIELD         !SAVE LOOKUP FIELD
  1398.     @FIELD = @ACCESSFIELD             !MOVE LOOKUP FIELD
  1399.     DISPLAY(?@FIELD)             !AND DISPLAY IT
  1400.     ACTION = ACTION#             !RESTORE ACTION
  1401. *HOTTABLE***********************************************************************
  1402.     IF KEYCODE() = @HOTKEY             !IF HOT KEY PRESSED
  1403.       UPDATE                 !  UPDATE ALL FIELDS
  1404.       @ACCESSFIELD = @FIELD             !  MOVE RELATED FIELDS
  1405.       GET(@FILENAME,@ACCESSKEY)         !  READ THE RECORD
  1406.       ACTION# = ACTION             !  SAVE ACTION
  1407.       ACTION = 4                 !  REQUEST TABLE LOOKUP
  1408.       @LOOKUP                 !  CALL LOOKUP PROCEDURE
  1409.       IF ACTION                 !  NO SELECTION WAS MADE
  1410.         SELECT(?@FIELD)             !   BACK UP ONE FIELD
  1411.         ACTION = ACTION#             !   RESTORE ACTION
  1412.         CYCLE                 !   GO TO TOP OF LOOP
  1413.       .
  1414.       @FIELD = @ACCESSFIELD             !  MOVE LOOKUP FIELD
  1415.       DISPLAY(?@FIELD)             !  AND DISPLAY IT
  1416.       ACTION = ACTION#             !  RESTORE ACTION
  1417.     .
  1418. *NEXTFORM***********************************************************************
  1419.     IF ACTION <> 3                 !IF THIS IS NOT A DELETE
  1420.       ACTION = 2                 !  SET ACTION TO CHANGE MODE
  1421.       @NEXTPAGE                 !  CALL NEXT FORM PROCEDURE
  1422.       IF ACTION                 !  IF RECORD WAS NOT CHANGED
  1423.         SELECT(?LAST_FIELD - 1)         !    SELECT THE LAST ENTRY
  1424.         BREAK                 !    AND LOOP AGAIN
  1425.     . .
  1426. *PAUSE**************************************************************************
  1427.       OF ?PAUSE_FIELD                 !ON PAUSE FIELD
  1428.     IF KEYCODE() <> ENTER_KEY  |         !IF NOT ENTER KEY
  1429.     AND KEYCODE() <> ACCEPT_KEY         !AND NOT CTRL-ENTER KEY
  1430.       BEEP                     !  SOUND KEYBOARD ALARM
  1431.       SELECT(?PAUSE_FIELD)             !  AND STAY ON PAUSE FIELD
  1432.     .
  1433. *LOOKUPS************************************************************************
  1434.     UPDATE                     !UPDATE RECORD KEYS
  1435.     @ACCESSFIELD = @FIELD             !MOVE RELATED KEY FIELDS
  1436.     GET(@FILENAME,@ACCESSKEY)             !READ THE RECORD
  1437.     IF ERROR() THEN CLEAR(@PRE:RECORD).         !IF NOT FOUND, CLEAR RECORD
  1438.     @SCRFIELD = @LOOKUPFIELD             !DISPLAY LOOKUP FIELD
  1439. *LOOKUPSCROLL*******************************************************************
  1440.     @ACCESSFIELD = @FIELD             !MOVE RELATED KEY FIELDS
  1441.     GET(@FILENAME,@ACCESSKEY)             !READ THE RECORD
  1442.     IF ERROR() THEN CLEAR(@PRE:RECORD).         !IF NOT FOUND, CLEAR RECORD
  1443.     @SCRFIELD = @LOOKUPFIELD             !DISPLAY LOOKUP FIELD
  1444. *OPENFILES**********************************************************************
  1445.   SHOW(25,1,CENTER('SHARING FILE: ' & '@FILENAME',80)) !DISPLAY FILE NAME
  1446.   SHARE(@FILENAME)                 !OPEN THE FILE IN SHARED MODE
  1447.   IF ERROR()                     !OPEN RETURNED AN ERROR
  1448.     CASE ERRORCODE()                 ! CHECK FOR SPECIFIC ERROR
  1449.     OF 46                     !  KEYS NEED TO BE REQUILT
  1450.       SETHUE(0,7)                 !  BLACK ON WHITE
  1451.       SHOW(25,1,CENTER('REBUILDING KEY FILES FOR @FILENAME',80)) !INDICATE MSG
  1452.       CLOSE(@FILENAME)                 !  LET BUILD OPEN FILE UNSHARED
  1453.       BUILD(@FILENAME)                 !  CALL THE BUILD PROCEDURE
  1454.       CLOSE(@FILENAME)                 !  CLOSE UNSHARED FILE
  1455.       SHARE(@FILENAME)                 !  OPEN FILE SHARED
  1456.       SETHUE(7,0)                 !  WHITE ON BLACK
  1457.       BLANK(25,1,1,80)                 !  BLANK THE MESSAGE
  1458.     @CREATEFILE                     !  IF NOT FOUND, THEN CREATE
  1459.     ELSE                     ! ANY OTHER ERROR
  1460.       LOOP;STOP('@FILENAME: ' & ERROR()).     !  STOP EXECUTION
  1461.   . .
  1462.  
  1463. *CREATEFILE*********************************************************************
  1464.     OF 2                     !IF NOT FOUND,
  1465.       CREATE(@FILENAME)                 !  THEN CREATE
  1466.       CLOSE(@FILENAME)                 !  CLOSE IT SO IT CAN
  1467.       SHARE(@FILENAME)                 !    BE OPENED SHARED
  1468. *SAVEITEMS**********************************************************************
  1469.          GROUP,PRE(SAV)
  1470.            @BREAKFIELDS
  1471.            @SELECTFIELDS
  1472.          .
  1473. *SAVETOTALS*********************************************************************
  1474. TOT_GROUP    GROUP,PRE(TOT)             !TABLE TOTAL FIELDS
  1475.            @TOTALFIELDS
  1476.          .
  1477. *TOTALCALC**********************************************************************
  1478.   BUFFER(@FILENAME,.25)                 !USE 1/4TH OF MEMORY FOR BUFFER
  1479.   @TOTCLEAR                     !ZERO TOTALS
  1480.   SET(@FILENAME)                 !READ DATA RECORD SEQUENCE
  1481.   SETHUE(BACKHUE(ROW,COL),BACKHUE(ROW,COL))     !TURN OFF DISPAY
  1482.   LOOP UNTIL EOF(@FILENAME)             !LOOP UNTIL END OF FILE
  1483.     NEXT(@FILENAME)                 !  READ A RECORD
  1484.     DO SHOW_RECORD                 !  DO COMPUTEDS, CONDS, & LKUPS
  1485.     @TOTPLUS                     !  ADD IT TO TOTAL AMOUNT
  1486.   .
  1487.   SETHUE()                     !TURN OFF SETHUE
  1488.   FREE(@FILENAME)                 !FREE MEMORY USED FOR BUFFERING
  1489. *TOTALCALCSEL*******************************************************************
  1490.   SETHUE(BACKHUE(ROW,COL),BACKHUE(ROW,COL))     !TURN OFF DISPLAY
  1491.   DO SHOW_LINE                     !  CALC SCROLLING LINE FIELDS
  1492.   @TOTPLUS                     !  ADD TO TOTALS
  1493.   SETHUE()
  1494. *DOTOTALS***********************************************************************
  1495.       IF ACTN# THEN DO COMP_TOTALS.         !CALCULATE TABLE TOTALS
  1496. *COMPUTETOTS********************************************************************
  1497. COMP_TOTALS  ROUTINE                 !CALCULATE TOTAL FIELDS
  1498.   CASE ACTN#                     !CHECK FOR ADD,REV,DEL
  1499.   OF INS_KEY                     !ADD NEW AMOUNT TO TOTAL
  1500.     @TOTPLUS
  1501.   OF ENTER_KEY                     !REVISE TOTAL AMOUNT
  1502.     @TOTCHANGE
  1503.   .
  1504.   ACTN# = ''
  1505. *TOTCHECK***********************************************************************
  1506.       ACTN# = KEYCODE()             !SAVE ACTION FOR COMP_TOTALS
  1507.       @TOTSAVE
  1508. *TOTCLEAR***********************************************************************
  1509.   CLEAR(TOT_GROUP)                 !ZERO TOTALS
  1510.   @TOTCLEARIMPL                     !ZERO AVERAGE CALC IMPLICITS
  1511. *TOTESC*************************************************************************
  1512.         ACTN# = ''                 !RESET ACTN
  1513. *INITBREAK**********************************************************************
  1514.   @SAVEFIELD = @FIELD                 !SAVE BREAK FIELD
  1515. *INITSELECTS********************************************************************
  1516.     @SAVEFIELD = @FIELD                 !SAVE SELECTOR FIELD
  1517. *RESTSELECTS********************************************************************
  1518.     @FIELD = @SAVEFIELD                 !RESTORE SELECTOR FIELD
  1519. *SORTTABLE**********************************************************************
  1520.   SORT(TABLE,@COMPONENT)             !SORT TABLE INTO KEY SEQUENCE
  1521. *CHECKSELECT********************************************************************
  1522.     IF @FIELD <> @SAVEFIELD THEN BREAK.     !BREAK ON END OF SELECTION
  1523. *CHECKADD***********************************************************************
  1524.   IF @FIELD <> @SAVEFIELD THEN EXIT.         !EXIT ON END OF SELECTION
  1525. *CHECKHOT***********************************************************************
  1526.       IF KEYCODE() = @HOTKEY             !ON HOT KEY
  1527.     @HOTPROC                 !  CALL HOT KEY PROCEDURE
  1528.     SELECT(?)                 !  DO SAME FIELD AGAIN
  1529.     CYCLE                     !  AND LOOP AGAIN
  1530.       .
  1531. *TABLEHOT***********************************************************************
  1532.       IF KEYCODE() = @HOTKEY             !ON HOT KEY
  1533.     IF FIELD() = ?POINT THEN DO GET_RECORD.     !  READ RECORD IF NEEDED
  1534.     @HOTPROC                 !  CALL HOT KEY PROCEDURE
  1535.     DO SAME_PAGE                 !  RESET TO SAME PAGE
  1536.     DO SHOW_TABLE                 !  DISPLAY A PAGE OF RECORDS
  1537.     CYCLE                     !  AND LOOP AGAIN
  1538.       .
  1539. *BUILDTABLE*********************************************************************
  1540.   PTR = 1                     !START AT TABLE ENTRY
  1541.   NDX = 1                     !PUT SELECTOR BAR ON TOP ITEM
  1542.   DO BUILD_TABLE                 !BUILD MEMORY TABLE OK KEYS
  1543. *AUTONUMKEY*********************************************************************
  1544.       DO GET_RECORD                 !READ CURRENT SCREEN RECORD
  1545.       SAVPTR# = POINTER(@FILENAME)         ! AND SAVE POSITION
  1546.       LOOP                     !LOOP TILL ADD IS SUCCESSFUL
  1547.         SET(@KEYNAME)             !SET TO HIGHEST KEY VALUE
  1548.         PREVIOUS(@FILENAME)             !READ LAST KEY RECORD
  1549.         KEYFIELD# = @INCFIELD + 1         !INCREMENT FIELD
  1550.         CLEAR(@PRE:RECORD)             !CLEAR LAST KEY RECORD
  1551.         @INCFIELD = KEYFIELD#         !LOAD KEY FIELD
  1552.         ADD(@FILENAME)             !ESTABLISH RECORD WITH UNIQUE
  1553.         IF NOT ERROR()             !ADD WAS SUCCESSFUL
  1554.           POINTER# = POINTER(@FILENAME)     !SAVE POINTER
  1555.           ACTION = 5             !SET ACTION FOR UPDATE
  1556.           BREAK                 !EXIT LOOP
  1557.       . .
  1558. *AUTONUMESC*********************************************************************
  1559.       IF ACTION                 !FORM WAS NOT COMPLETED
  1560.         @TOTESC                 !CLEAR TOTAL FIELD CALCULATIONS
  1561.         HOLD(@FILENAME)             !HOLD RECORD
  1562.         GET(@FILENAME,POINTER#)         !READ RECORD
  1563.         DELETE(@FILENAME)             !DELETE RECORD
  1564.         POINTER# = SAVPTR#             !SET POINTER TO PROPER REC
  1565.         GET(@FILENAME,POINTER#)         !READ RECORD
  1566.         SET(@KEYNAME,@KEYNAME)         !POSITION FILE
  1567.         SKIP(@FILENAME,-1)             !BACK UP ONE
  1568.         DO SHOW_TABLE             !RE-DISPLAY PAGE
  1569.       .
  1570. *AUTONUMSEL*********************************************************************
  1571.       GET(TABLE,RECORDS(TABLE))         !READ HIGHEST KEY VALUE
  1572.       IF ERROR() THEN CLEAR(TABLE).         !ZERO FIELDS IF EMPTY TABLE
  1573.       @RESTSELECTS                 !LOAD PRIOR KEY FIELDS
  1574.       @INCFIELD = @TABLEFIELD         !LOAD INCREMENT FIELD
  1575.       LOOP                     !LOOP TILL ADD IS SUCCESSFUL
  1576.         @INCFIELD += 1             !  INCREMENT FIELD
  1577.         ADD(@FILENAME)             !  ESTABLISH REC WITH UNIQUE KY
  1578.         IF NOT ERROR()             !  ADD WAS SUCCESSFUL
  1579.           POINTER# = POINTER(@FILENAME)     !SAVE POINTER
  1580.           ACTION = 5             !SET ACTION FOR UPDATE
  1581.           BREAK                 !EXIT LOOP
  1582.       . .
  1583. *AUTOSELESC*********************************************************************
  1584.       IF ACTION                 !FORM WAS NOT COMPLETED
  1585.         HOLD(@FILENAME)             !HOLD RECORD
  1586.         GET(@FILENAME,POINTER#)         !READ RECORD
  1587.         DELETE(@FILENAME)             !DELETE RECORD
  1588.       .
  1589. *CONDITIONAL********************************************************************
  1590.       IF @IFCOND                 !EVALUATE CONDITION
  1591.     @IFCONDTRUE                 !  CONDITION IS TRUE
  1592.       ELSE                     !OTHERWISE
  1593.     @IFCONDFALSE                 !  CONDITION IS FALSE
  1594.       .
  1595. *RUNMAP*************************************************************************
  1596.            PROC(G_RUNPROC)             !GLOBAL MODULE RUN PROCEDURE
  1597. *RUNPROC************************************************************************
  1598. G_RUNPROC    PROCEDURE(DOSPROG)             !GLOBAL RUN PROCEDURE
  1599. DOSPROG         STRING(12)                 !PROGRAM TO RUN
  1600. SCREEN         SCREEN    WINDOW(25,80),HUE(7,0,0). !SAVE WINDOW
  1601.  
  1602.   CODE
  1603.   OPEN(SCREEN)                     !SAVE CURRENT SCREEN
  1604.   SETCURSOR(25,1)                 !POSITION CURSOR AT BOTTOM
  1605.   RUN(DOSPROG)                     !RUN DOS PROGRAM
  1606.   G_OPENFILES                     !RE-OPEN FILES
  1607.   CLOSE(SCREEN)                     !RESTORE SCREEN
  1608.   RETURN                     !EXIT BACK TO CALLING MENU
  1609. *RUNCODE************************************************************************
  1610.       G_RUNPROC('@RUNDESC')             !RUN DOS PROGRAM
  1611. *FIRSTBREAK*********************************************************************
  1612.   BRK_FLAG# = 0                     !CLEAR BREAK LEVEL FLAG
  1613.   DO PRT_BRK_HDRS                 !PRINT GROUP HEADER(S)
  1614. *CHECKBREAK*********************************************************************
  1615.     IF NOT DONE# THEN DO CHECK_BREAK.         !  CHECK FOR GROUP BREAK
  1616. *LASTBREAK**********************************************************************
  1617.   BRK_FLAG# = 0                     !CLEAR BREAK LEVEL FLAG
  1618.   DO PRT_BRK_FTRS                 !PRINT GROUP FOOTER(S)
  1619. *BREAKRTN***********************************************************************
  1620. CHECK_BREAK  ROUTINE                 !CHECK FOR GROUP BREAK
  1621.   @COMPAREBREAK                     !GENERATE IF STATEMENTS
  1622.  
  1623. PRT_BRK_HDRS ROUTINE                 !DO GROUP HEADERS
  1624.   @BREAKHEADER                     !PRINT HEADERS
  1625.   @INITBREAK                     !INITIALIZE BREAK FIELDS
  1626.  
  1627. PRT_BRK_FTRS ROUTINE                 !DO GROUP FOOTERS
  1628.   GET(@FILENAME,LAST_REC#)             !REREAD PREVIOUS RECORD
  1629.   @BREAKFOOTER                     !PRINT FOOTERS
  1630.   SKIP(@FILENAME,-1)                 !BACKUP ONE RECORD
  1631.   NEXT(@FILENAME)                 !AND REREAD IT
  1632. *COMPAREBREAK*******************************************************************
  1633.   IF @FIELD <> @SAVEFIELD             !BREAK ON NEW GROUP
  1634.     BRK_FLAG# = @BRKNUM                 !SET BREAK LEVEL
  1635.     DO PRT_BRK_FTRS                 !PRINT FOOTERS FOR THIS LEVEL
  1636.     DO PRT_BRK_HDRS                 !PRINT HEADERS FOR THIS LEVEL
  1637.     EXIT                     !RETURN TO REPORT
  1638.   .
  1639. *BREAKHEADER********************************************************************
  1640.   IF BRK_FLAG# <= @BRKNUM             !CHECK BREAK LEVEL
  1641.     @INITGROUP                     ! INIT GROUP VARIABLES
  1642.     @GRPHEADER                     ! DO HEADER COMPUTES
  1643.     PRINT(GRP_HEAD@BRKNUM)             ! PRINT GROUP HEADER
  1644.     @PRINTMEMO                     ! PRINT ANY MEMO FIELD
  1645.     DO CHECK_PAGE                 ! DO PAGE BREAK IF NEEDED
  1646.   .
  1647. *BREAKFOOTER********************************************************************
  1648.   IF BRK_FLAG# <= @BRKNUM             !CHECK BREAK LEVEL
  1649.     @GRPFOOTER                     ! DO FOOTER COMPUTES
  1650.     PRINT(GRP_FOOT@BRKNUM)             ! PRINT GROUP FOOTER
  1651.     @PRINTMEMO                     ! PRINT ANY MEMO FIELD
  1652.     DO CHECK_PAGE                 ! DO PAGE BREAK IF NEEDED
  1653.     @PAGEEJECT                     ! GO TO NEW PAGE
  1654.   .
  1655. *PAGEEJECT**********************************************************************
  1656.     MEM:LINE = 0                 !  SET FOR CALL TO CHECK_PAGE
  1657.     DO CHECK_PAGE                 !  INITIALIZE PAGE VARIABLES
  1658.     IF NOT DONE#                 !  MORE ITEMS TO PRINT
  1659.       PRINT(PAGE_FOOT)                 !  PRINT PAGE FOOTER
  1660.       PRINT(PAGE_HEAD)                 !  PRINT PAGE HEADER
  1661.     .
  1662. ********************************************************************************
  1663.