home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0020 - 0029 / ibm0020-0029 / ibm0028.tar / ibm0028 / SBTAR2.ZIP / SYSMULT.PRG < prev    next >
Encoding:
Text File  |  1990-06-04  |  72.4 KB  |  2,236 lines

  1. ********************** ' MultiNet Source Code ' ***********************
  2. ** '                       SBT Corporation                         ' **
  3. ** '         One Harbor Drive, Sausalito, California 94965         ' **
  4. ** '                   Telephone (415) 331-9900                    ' **
  5. ***********************************************************************
  6. ** '   (c) Copyright 1984, Revisions 1985 - 1990 SBT Corporation   ' **
  7. ** '            All Rights Reserved by SBT Corporation             ' **
  8. ** '                                                               ' **
  9. ***********************************************************************
  10. ** ' 05/21/90 = Last Update  **  SYSMULT.PRG  **   Version 6.35.00 ' **
  11. ***********************************************************************
  12. * ' Procedure file for Multi-user
  13. *
  14. ***********************************************************************
  15. *                                                                     *
  16. * ' NOTE: EVERY FUNCTIONAL CHANGE TO SYSMULT SHOULD RESULT IN A       *
  17. * '       CORRESPONDING  CHANGE TO MSYSDATE IN P0SETENV, AND TO       *
  18. * '       M0CURDTE IN xx.PRG. (Insure latest SYSTEM files in use)     *
  19. *                                                                     *
  20. ***********************************************************************
  21. *
  22. *
  23. *
  24. * ' Procedure Name:       P0SETENV
  25. * ' Purpose or Function:  Sets up initial program environment and confirm
  26. * '                       that most recent version of this file is being used
  27. * ' Parameters Passed:    None
  28. * ' Variables Passed:     None
  29. * ' Variables Returned:   None
  30. *
  31. * ' MODIFICATION NOTE: You may change the following values if you wish:
  32. * '                    SET CONFIRM
  33. * '                    SET BELL
  34. * '                    SET TYPEAHEAD
  35. * '                    You should not change SET SAFETY (we do overwrite files)
  36. *
  37. PROCEDURE p0setenv
  38.   * ' Sysdate is checked again in XX.PRG to insure system files up to date
  39.   RELEASE msysdate
  40.   PUBLIC msysdate
  41.   * ' This date should be adjusted with every functional change to this file
  42.   STORE '06/01/90' TO msysdate
  43.   SET CONFIRM OFF
  44.   SET SAFETY OFF
  45.   SET ESCAPE ON
  46.   SET EXACT OFF
  47.   SET BELL OFF
  48.   SET TYPEAHEAD TO 40
  49.   * ' Check for these variables in case calling program is early version
  50.   IF TYPE('m0switchar') = 'U'
  51.     PUBLIC m0switchar
  52.   ENDIF
  53.   IF TYPE('m0single') = 'U'
  54.     PUBLIC m0single
  55.     STORE .f. TO m0single
  56.   ENDIF
  57.   IF (.NOT. 'MULTI' $ UPPER(m0system)) .AND. m0pgmid <> 'CM'
  58.     STORE .t. TO m0single
  59.   ENDIF
  60.   IF TYPE('m0trial') = 'U'
  61.     PUBLIC m0trial
  62.     STORE .f. TO m0trial
  63.   ENDIF
  64.   IF TYPE('m0stpprn') = 'U'
  65.     PUBLIC m0stpprn
  66.     STORE .f. TO m0stpprn
  67.   ENDIF
  68.   IF TYPE('m0prnesc') = 'U'
  69.     PUBLIC m0prnesc
  70.     STORE .f. TO m0prnesc
  71.   ENDIF
  72.   IF m0single
  73.     SET EXCLUSIVE ON
  74.   ELSE
  75.     SET EXCLUSIVE OFF
  76.   ENDIF
  77.   * ' Initialize the print/screen environment in case of printer errors
  78.   DO p0setprn WITH 'ON', 'SCREEN', 'OFF', 0
  79.   ON ESCAPE DO p0escape
  80.   * ' Call to on-screen calculator, activate with Alt-A
  81.   * ' Only operates if foxbase and compatable with IBM character set
  82.   IF fox .AND. SUBSTR(m0border,170,1) = 'Y'
  83.     ON KEY=286 DO p0popclc
  84.   ENDIF
  85.   IF foxpro
  86.     * ' Set insert off and set cursor small
  87.     SET CONSOLE OFF
  88.     ? INSMODE(.f.)
  89.     ? SYS(2008,'O', 2)
  90.     SET CONSOLE ON
  91.   ENDIF
  92.   IF .NOT. 'OFF' $ UPPER(GETE('ONERROR'))
  93.     ON ERROR DO p0errors WITH ERROR(), MESSAGE()
  94.   ELSE
  95.     * ' don't enable error trap if debugging variable set
  96.     ON ERROR
  97.   ENDIF
  98. RETURN
  99. * ' EOP - P0SETENV
  100. *
  101. *
  102. * ' Procedure Name:       P0CLRENV
  103. * ' Purpose or Function:  Clears program environment
  104. * ' Parameters Passed:    None
  105. * ' Variables Passed:     None
  106. * ' Variables Returned:   None
  107. *
  108. PROCEDURE p0clrenv
  109.   CLOSE DATABASES
  110.   * ' Skip this multiuser function if setup as single user
  111.   IF .NOT. m0single
  112.     DO p0usrcnt WITH .f.
  113.   ENDIF
  114.   DO p0setprn WITH 'ON', 'SCREEN', 'OFF', 0
  115.   SET TALK ON
  116.   SET EXCLUSIVE ON
  117.   SET ESCAPE ON
  118.   ON ERROR
  119.   ON ESCAPE
  120.   SET PATH TO
  121. RETURN
  122. * ' EOP - P0CLRENV
  123. *
  124. *
  125. * ' Procedure Name:       P0CLRPRN
  126. * ' Purpose or Function:  Resets CONSOLE/DEVICE/PRINT settings
  127. * ' Parameters Passed:    None
  128. * ' Variables Passed:     m0con = 'ON' or 'OFF' - new current CONSOLE
  129. * '                       m0dev = 'SCREEN' or 'PRINT' - new current DEVICE
  130. * '                       m0prt = 'ON' or 'OFF' - new current PRINT
  131. * ' Variables Returned:   Same as Variables Passed
  132. *
  133. PROCEDURE p0clrprn
  134.   IF TYPE('m0con') = 'U' .OR. TYPE('m0prt') = 'U' .OR. TYPE('m0dev') = 'U'
  135.     DO p0setprn WITH 'ON', 'SCREEN', 'OFF', 0
  136.   ELSE
  137.     IF m0con = 'OFF'
  138.       SET CONSOLE OFF
  139.     ELSE
  140.       SET CONSOLE ON
  141.     ENDIF
  142.     IF m0dev = 'PRINT'
  143.       SET DEVICE TO PRINT
  144.     ELSE
  145.       SET DEVICE TO SCREEN
  146.     ENDIF
  147.     IF m0prt = 'ON'
  148.       SET PRINT ON
  149.     ELSE
  150.       SET PRINT OFF
  151.     ENDIF
  152.   ENDIF
  153. RETURN
  154. * ' EOP - P0CLRPRN
  155. *
  156. *
  157. * ' Procedure Name:       P0POPCLC
  158. * ' Purpose or Function:  Popup Calculator
  159. * ' Parameters Passed:    None
  160. * ' Variables Passed:     None
  161. * ' Variables Returned:   None
  162. *
  163. PROCEDURE p0popclc
  164.   PRIVATE mmemtotl, mtotal, mholder, mcans, minput, mchoice, mopmacro, mans
  165.   SAVE SCREEN
  166.   SET ESCAPE OFF
  167.   SET DECIMAL TO 5
  168.   SET INTENSITY OFF
  169.   IF ISCOLOR()
  170.     SET COLOR TO W+/R,GR+/B
  171.   ELSE
  172.     SET COLOR TO W/N,N/W,N
  173.   ENDIF
  174.   STORE '╔═╗║╝═╚║ ' TO combo3
  175.   STORE 0 TO mmemtotl, mtotal, mholder
  176.   STORE ' ' TO mcans, minput, mchoice, mopmacro
  177.   @ 2,42,10,72 BOX combo3
  178.   @ 2,51 SAY '╤'
  179.   @ 3,44 SAY 'Entry  │                  0'
  180.   @ 4,42 SAY '╠════════╪════════════════════╣'
  181.   @ 5,44 SAY 'Total  │                  0'
  182.   @ 6,42 SAY '╠════════╪════════════════════╣'
  183.   @ 7,44 SAY 'Memory │                  0'
  184.   @ 8,42 SAY '╠════════╧════════════════════╣'
  185.   @ 9,44 SAY SPACE(28)
  186.   @ 9,52 SAY '<H> = Help'
  187.   DO WHILE .t.
  188.     @ 3,70 SAY ''
  189.     WAIT '' TO mcans
  190.     @ 9,44 SAY SPACE(28)
  191.     @ 9,52 SAY '<H> = Help'
  192.     @ 3,70 SAY ' '
  193.     STORE UPPER(mcans) TO mcans
  194.     IF LEN(TRIM(mcans)) = 0
  195.       STORE '=' TO mcans
  196.     ENDIF
  197.     STORE .t. TO mclear
  198.     * ' If number entered, loop for more numbers
  199.     IF mcans $ '0123456789.'
  200.       STORE TRIM(minput) + mcans TO minput
  201.       @ 3,70 - LEN(minput) SAY minput PICTURE '#############.####'
  202.       STORE ' ' TO mcans
  203.       LOOP
  204.     ELSE
  205.       IF mchoice $ '+-/*^'
  206.         STORE mchoice TO mopmacro
  207.       ENDIF
  208.       STORE mcans TO mchoice
  209.       IF mchoice $ '+-/*^='
  210.         @ 3,53 SAY mchoice
  211.       ENDIF
  212.       @ 3,54 CLEAR TO 3,71
  213.       STORE ' ' TO mcans
  214.     ENDIF
  215.     DO CASE
  216.       CASE mchoice = 'Q'
  217.         * ' Quit back to program
  218.         EXIT
  219.       CASE mchoice = 'P'
  220.         STORE SYS(18) TO mfield
  221.         IF TYPE ('&mfield') = 'N'
  222.           * ' Paste total
  223.           KEYB LTRIM(STR(mtotal,7,2))
  224.           * ' and quit back to program
  225.           EXIT
  226.         ELSE
  227.           ?? CHR(7)
  228.           STORE ' ' TO mans
  229.           @ 9,44 SAY '** Only Paste to Numeric **'
  230.           LOOP
  231.         ENDIF
  232.       CASE mchoice = 'C'
  233.         * ' Clear current
  234.         STORE '0' TO mcans, minput
  235.         STORE ' ' TO mcans
  236.         @ 3,53 SAY mchoice
  237.       CASE mchoice = 'Z'
  238.         * ' Clear all registers
  239.         STORE  0  TO mtotal, mmemtotl, mholder
  240.         STORE '0' TO mcans, minput
  241.         @ 3,53 SAY mchoice
  242.       CASE mchoice $ '+-/*^='
  243.         * ' Compute
  244.         DO CASE
  245.           CASE LEN(TRIM(minput)) = 0
  246.             * ' If no entry, leave alone
  247.           CASE mtotal # 0
  248.             * ' Calculate
  249.             STORE mtotal &mopmacro VAL(minput) TO mtotal
  250.           OTHERWISE
  251.             * If zero just set to input value
  252.             STORE VAL(minput) TO mtotal
  253.         ENDCASE
  254.         IF mchoice = '='
  255.           STORE '+' TO mchoice, mopmacro
  256.         ENDIF
  257.       CASE mchoice = '%'
  258.         * ' Compute percentage
  259.         STORE mtotal + (mtotal * (VAL(minput)/100)) TO mtotal
  260.       CASE mchoice = 'M'
  261.         * ' Store to memory
  262.         STORE .f. TO mclear
  263.         mmemtotl = VAL(minput)
  264.       CASE mchoice = 'G'
  265.         * ' Get from memory
  266.         STORE .f.  TO mclear
  267.         STORE LTRIM(STR(mmemtotl,18,4)) TO minput
  268.       CASE mchoice = 'A'
  269.         * ' Add to Memory
  270.         STORE .f. TO mclear
  271.         STORE mmemtotl + VAL(minput) TO mmemtotl
  272.       CASE mchoice = 'S'
  273.         * ' Switch running total with memory total
  274.         STORE mtotal TO mholder
  275.         STORE mmemtotl TO mtotal
  276.         STORE mholder TO mmemtotl
  277.       CASE mchoice = 'F'
  278.         * ' Reverse (flip) sign
  279.         STORE STR(VAL(minput) * (-1),13,4) TO minput
  280.         STORE .f. TO mclear
  281.       CASE mchoice = 'R'
  282.         * ' Compute Square Root
  283.         STORE mtotal^(1/2) TO mtotal
  284.       CASE mchoice = 'Y'
  285.         * ' Compute Square
  286.         STORE mtotal^2 TO mtotal
  287.       CASE mchoice = 'H'
  288.         * ' Help Screen
  289.         SAVE SCREEN TO calc2
  290.         @ 8,42 SAY '╚════════╧════════════════════╝'
  291.         @ 9,42 SAY SPACE(31)
  292.         @ 9,52 SAY '«« HELP »»'
  293.         @ 10,42,23,72 BOX '╒═╕│╛═╘│ '
  294.         @ 10,47 SAY '╤'
  295.         @ 11,43 SAY 'C   │ Clear entry'
  296.         @ 12,43 SAY 'S   │ Switch memory and entry'
  297.         @ 13,43 SAY 'F   │ Flip sign Of entry'
  298.         @ 14,43 SAY '%   │ Percentage'
  299.         @ 15,43 SAY 'G   │ Get from memory'
  300.         @ 16,43 SAY 'R   │ square Root of total'
  301.         @ 17,43 SAY 'M   │ store entry to Memory'
  302.         @ 18,43 SAY 'A   │ Add entry to memory'
  303.         @ 19,43 SAY 'Y   │ square of total'
  304.         @ 20,43 SAY 'Z   │ Zap/clear all registers'
  305.         @ 21,43 SAY 'P   │ Put total in numeric'
  306.         @ 22,43 SAY 'Q   │ Quit calculator'
  307.         @ 23,47 SAY '╧'
  308.         WAIT ''
  309.         RESTORE SCREEN FROM calc2
  310.     ENDCASE
  311.     @ 5,54 SAY mtotal PICTURE '#############.####'
  312.     @ 7,54 SAY mmemtotl PICTURE '#############.####'
  313.     IF .NOT. mclear
  314.       @ 3,70 - LEN(minput) SAY minput PICTURE '#############.####'
  315.     ELSE
  316.       STORE ' ' TO mcans, minput
  317.     ENDIF
  318.   ENDDO
  319.   DO CASE
  320.     CASE m0monitor = 'C' .AND. LEN(m0color) > 0
  321.       SET COLOR TO &m0color
  322.     CASE m0monitor = 'C'
  323.       SET COLOR TO W+/B,N/W,B
  324.     CASE 'MAC' $ UPPER(OS()) .AND. fox
  325.       SET COLOR TO N/W,W/N,N
  326.     OTHERWISE
  327.       SET COLOR TO W+/N,N/W,N
  328.   ENDCASE
  329.   SET DECIMAL TO 2
  330.   SET INTENSITY ON
  331.   RESTORE SCREEN
  332. RETURN
  333. * ' EOP - P0POPCLC
  334. *
  335. *
  336. * ' Procedure Name:       P0DQUERY
  337. * ' Purpose or Function:  Dot prompt emulator
  338. * ' Parameters Passed:    None
  339. * ' Variables Passed:     None
  340. * ' Environment Passed:   None
  341. * ' Variables Returned:   None
  342. *
  343. PROCEDURE p0dquery
  344.   * ' Presumably next 4 lines will never be hit, they should use SYSCLIP
  345.   IF clipper .OR. xquicks
  346.     * ' display Option Not Available message
  347.     DO syshelp WITH 9010
  348.   RETURN
  349. ENDIF
  350. SET ESCAPE OFF
  351. SELECT a
  352. CLOSE DATABASES
  353. CLEAR
  354. STORE '..' TO comm
  355. DO WHILE SUBSTR(comm,1,1) <> ' '
  356.   CLEAR GETS
  357.   STORE SPACE(77) TO comm
  358.   ?
  359.   ?
  360.   ?
  361.   @ 22,0
  362.   @ 22,0 SAY 'Enter Database Command or <Enter> to return to menu...'
  363.   @ 23,0 SAY '. '
  364.   @ 23,2 GET comm
  365.   READ
  366.   * ' Don't allow quit or cancel from emulated dot prompt
  367.   IF LEN(TRIM(comm)) > 0 .AND. .NOT. TRIM(UPPER(comm)) $ ' QUIT CANCEL '
  368.     SET TALK ON
  369.     &comm
  370.     SET TALK OFF
  371.     STORE 'xxx' TO comm
  372.   ENDIF
  373.   CLEAR GETS
  374. ENDDO
  375. * ' Reset startup environment in case interactive work changed it.
  376. DO p0setenv
  377. * ' Close databases and reset to a to avoid problems
  378. * ' with files left open on return
  379. CLOSE DATABASES
  380. SELECT a
  381. RETURN
  382. * ' EOP - P0DQUERY
  383. *
  384. *
  385. * ' Procedure Name:       P0LSFILE
  386. * ' Purpose or Function:  Lists file records with like key values
  387. * ' Parameters Passed:    None
  388. * ' Variables Passed:     m0field = character var with key field name
  389. * '                       m0key   = character var with sought key value
  390. * '                       m0file  = 'ARCUST' - AR/SO 6.XX Customer File
  391. * '                                 'APVEND' - AP/PO 6.XX Vendor FIle
  392. * '                                 'APACCT' - AP 6.21 Checking Accounts File
  393. * '                                 'ARINVT' - AR/PO/SO 6.XX Inventory File
  394. * '                                 'ASSETS' - AS 6.20 Assets File
  395. * '                                 'PREMPL' - PR 6.15 Employee File
  396. * ' Environment Passed:   &m0file with INDEX assumed to be selected
  397. * ' Variables Returned:   m0new   = .t. if OK to add new record
  398. *
  399. * ' This procedure was replaced by SYSLIST.PRG in mid 1989.
  400. * ' You may remove it if not needed for backward compatibility
  401. *
  402. PROCEDURE p0lsfile
  403. PRIVATE mans, mxkey, mfirst, mlast, mline, mheading, mrecno, mtoprec
  404.   RELEASE m0new
  405.   PUBLIC m0new
  406.   STORE .f. TO m0new
  407.   SET EXACT OFF
  408.   STORE TRIM(m0key) TO mxkey
  409.   SEEK mxkey
  410.   DO WHILE LEN(mxkey) > 1 .AND. EOF()
  411.     STORE SUBSTR(mxkey,1,LEN(mxkey) - 1) TO mxkey
  412.     SEEK mxkey
  413.   ENDDO
  414.   @ 4,0 CLEAR
  415.   DO CASE
  416.     CASE m0file = 'APVEND'
  417.       STORE 'Vendor' TO mtitle
  418.       STORE 'Company                           Vendor No.   City   ' + ;
  419.       '           Phone' TO mheading
  420.     CASE m0file = 'APACCT'
  421.       STORE 'Account' TO mtitle
  422.       STORE 'Account       Description                           Last ' + ;
  423.       m0cheque TO mheading
  424.     CASE m0file = 'ARCUST'
  425.       STORE 'Customer' TO mtitle
  426.       STORE 'Company                           Cust No.     City   ' + ;
  427.       '           Phone' TO mheading
  428.     CASE m0file = 'ARINVT'
  429.       STORE 'Item' TO mtitle
  430.       STORE 'Description                           Item No.          ' + ;
  431.       'Vendor Part No.' TO mheading
  432.     CASE m0file = 'ASSETS'
  433.       STORE 'Tag' TO mtitle
  434.       STORE 'Tag Number   Description                             Cost' ;
  435.       TO mheading
  436.     CASE m0file = 'DBCLNT'
  437.       STORE 'Customer' TO mtitle
  438.       STORE 'Customer      Company' TO mheading
  439.     CASE m0file = 'JCPHAS'
  440.       STORE 'Phase' TO mtitle
  441.       STORE 'Phase         Description' TO mheading
  442.     CASE m0file = 'JCCATG'
  443.       STORE 'Category record' TO mtitle
  444.       STORE 'Category    Description' TO mheading
  445.     CASE m0file = 'PREMPL'
  446.       STORE 'Employee' TO mtitle
  447.       STORE 'Employee' TO mheading
  448.   ENDCASE
  449.   DO CASE
  450.     CASE EOF() .AND. SUBSTR(m0key,1,1) = '?'
  451.       @ 4,1 SAY 'Displaying all ' + TRIM(mtitle) + 's...'
  452.       GO TOP
  453.       STORE '' TO mxkey
  454.     CASE EOF()
  455.       @ 4,1 SAY 'No ' + TRIM(mtitle) + 's similar to ' + LTRIM(TRIM(m0key)) + ;
  456.       ' found...'
  457.     OTHERWISE
  458.       @ 4,1 SAY TRIM(mtitle) + ' ' + LTRIM(TRIM(m0key)) + ' not found. ' + ;
  459.       'Displaying similar ' + TRIM(mtitle) + 's...'
  460.   ENDCASE
  461.   IF .NOT. EOF()
  462.     @ 6,1 SAY mheading
  463.     @ 7,1 SAY SUBSTR(m0border,10,78)
  464.   ENDIF
  465.   STORE .t. TO mfirst
  466.   STORE .f. TO mlast
  467.   STORE RECNO() TO mtoprec
  468.   DO WHILE .t.
  469.     STORE 8 TO mline
  470.     STORE RECNO() TO mrecno
  471.     DO WHILE mxkey = UPPER(SUBSTR(&m0field,1,LEN(mxkey))) ;
  472.       .AND. mline < 21 .AND. .NOT. EOF()
  473.       DO CASE
  474.         CASE m0file = 'APVEND'
  475.           @ mline,1 SAY company + ' ' + vendno + '     ' + ;
  476.           SUBSTR(city,1,15) + '   ' + SUBSTR(phone,1,12)
  477.         CASE m0file = 'APACCT'
  478.           @ mline,1 SAY account + '     ' + descrip + '    ' + lpaydate
  479.         CASE m0file = 'ARCUST'
  480.           @ mline,1 SAY company + ' ' + custno + '     ' + ;
  481.           SUBSTR(city,1,15) + '   ' + SUBSTR(phone,1,12)
  482.         CASE m0file = 'ARINVT'
  483.           @ mline,1 SAY descrip + '   ' + item + '   ' + vpartno
  484.         CASE m0file = 'ASSETS'
  485.           @ mline,1 SAY tagno + '   ' + SUBSTR(descrip,1,31) + '    ' + ;
  486.           STR(cost,10,2)
  487.         CASE m0file = 'DBCLNT'
  488.           @ mline,1 SAY custno + SPACE(8) + company
  489.         CASE m0file = 'JCPHAS'
  490.           @ mline,1 SAY phase + SPACE(8) + descrip
  491.         CASE m0file = 'JCCATG'
  492.           @ mline,1 SAY catg + SPACE(8) + descrip
  493.         CASE m0file = 'PREMPL'
  494.           @ mline,1 SAY prempl + '  ' + TRIM(prlast) + ', ' + prfirst
  495.       ENDCASE
  496.       SKIP
  497.       STORE mline + 1 TO mline
  498.     ENDDO
  499.     IF mxkey = UPPER(SUBSTR(&m0field,1,LEN(mxkey))) ;
  500.       .AND. .NOT. (EOF() .OR. BOF())
  501.       STORE .f. TO mlast
  502.     ELSE
  503.       STORE .t. TO mlast
  504.     ENDIF
  505.     IF SUBSTR(m0key,1,1) <> '?'
  506.       STORE 'Add new ' + TRIM(mtitle) + '/' TO msg
  507.       STORE 'A' TO moptns
  508.     ELSE
  509.       STORE '' TO msg, moptns
  510.     ENDIF
  511.     STORE 'R' TO mans
  512.     IF .NOT. mlast
  513.       STORE msg + 'Fwd/' TO msg
  514.       STORE moptns + 'F' TO moptns
  515.       STORE 'F' TO mans
  516.     ENDIF
  517.     IF .NOT. mfirst
  518.       STORE msg + 'Back/' TO msg
  519.       STORE moptns + 'B' TO moptns
  520.     ENDIF
  521.     @ 22,1 SAY 'Enter Choice (' + msg + 'Reenter) ' + ;
  522.     SUBSTR(m0border,181,5) GET mans PICTURE '!'
  523.     READ SAVE
  524.     DO WHILE .NOT. mans $ 'R' + moptns
  525.       ?? CHR(7)
  526.       READ SAVE
  527.     ENDDO
  528.     @ 22,0
  529.     CLEAR GETS
  530.     STORE .f. TO mfirst
  531.     DO CASE
  532.       CASE mans = 'B'
  533.         @ 22,1 SAY 'Paging Backwards in File.  Please wait..'
  534.         GO mrecno
  535.         SKIP -13
  536.         IF mxkey <> UPPER(SUBSTR(&m0field,1,LEN(mxkey))) .OR. BOF()
  537.           STORE .t. TO mfirst
  538.           GO mtoprec
  539.         ENDIF
  540.         IF .NOT. mfirst .AND. .NOT. BOF()
  541.           SKIP -1
  542.           IF mxkey <> UPPER(SUBSTR(&m0field,1,LEN(mxkey))) .OR. BOF()
  543.             STORE .t. TO mfirst
  544.             GO mtoprec
  545.           ELSE
  546.             SKIP
  547.           ENDIF
  548.         ENDIF
  549.       CASE mans = 'A'
  550.         STORE .t. TO m0new
  551.         EXIT
  552.       CASE mans = 'R'
  553.         STORE .f. TO m0new
  554.         EXIT
  555.     ENDCASE
  556.     @ 8,0 CLEAR
  557.   ENDDO && WHILE .t.
  558. RETURN
  559. * ' EOP - P0LSFILE
  560. *
  561. *
  562. * ' Procedure Name:       P0PASVAL
  563. * ' Purpose or Function:  Checks Password Access and displays entry screen
  564. * ' Parameters Passed:    maccess  = character, '1'-'15' to validate access
  565. * '                       or '0' to get a new password without validation
  566. * '                       mtitle   = Option title being validated (or null)
  567. * ' Variables Passed:     m0passf  = Password file name with drive/path
  568. * ' Environment Passed:   Password file assumed not to be open in other areas
  569. * ' Variables Returned:   mreturn    = logical, .t. if okay to continue
  570. * '                       m0pass   = character, password plus access fields
  571. * ' Example:              Called as DO P0pasval WITH '1', mchoice
  572. *
  573. PROCEDURE p0pasval
  574.   PARAMETER maccess, mtitle
  575.   PRIVATE mans, mpword
  576.   RELEASE mreturn
  577.   PUBLIC mreturn
  578.   STORE .f. TO mreturn
  579.   USE &m0passf
  580.   * ' If maccess hasn't been defined in calling program, something is wrong
  581.   IF TYPE('maccess') <> 'C'
  582.   RETURN
  583. ENDIF
  584. * ' If maccess doesn't relate to field in password file, something wrong
  585. * ' maccess of '0' is for changing logged in password
  586. IF maccess <> '0' .AND. TYPE('access&maccess') <> 'C'
  587.   RETURN
  588. ENDIF
  589. CLEAR
  590. @ 1,1 SAY DTOC(m0date)
  591. @ 1,40 - INT(LEN(m0system)/2) SAY m0system
  592. @ 1,73 SAY SUBSTR(m0company,79,6)
  593. @ 2,1 SAY SUBSTR(m0company,1,78)
  594. @ 3,40 - INT(LEN(mtitle)/2) SAY mtitle
  595. @ 7,1 SAY ' Please Enter Your Password ' + SUBSTR(m0border,177,9)
  596. @ 8,38 SAY SUBSTR(m0border,91,35)
  597. @ 9,38 SAY 'your password will not be displayed'
  598. DO WHILE .t.
  599.   @ 7,37 SAY ' '
  600.   SET CONSOLE OFF
  601.   ACCEPT TO mpword
  602.   SET CONSOLE ON
  603.   STORE UPPER(SUBSTR(TRIM(mpword) + SPACE(10),1,10)) TO mpword
  604.   * ' Entry of blanks escapes from option
  605.   IF mpword = SPACE(10)
  606.     STORE .f. TO mreturn
  607.     EXIT
  608.   ELSE
  609.     LOCATE FOR password = mpword .AND. .NOT. DELETED()
  610.     * ' maccess of '0' is for changing logged in password
  611.     IF maccess = '0'
  612.       IF .NOT. EOF()
  613.         STORE .t. TO mreturn
  614.         STORE password + access1 + access2 + access3 + access4 + access5 + ;
  615.         access6 + access7 + access8 + access9 + access10 + access11 + ;
  616.         access12 + access13 + access14 + access15 TO m0pass
  617.       ENDIF
  618.     ELSE
  619.       * ' If the relevant password (determined by maccess) has 'Y', passes
  620.       IF access&maccess = 'Y' .AND. .NOT. EOF()
  621.         STORE .t. TO mreturn
  622.       ENDIF
  623.     ENDIF
  624.     IF mreturn
  625.       EXIT
  626.     ENDIF
  627.     ?? CHR(7)
  628.     @ 13,2 SAY 'Invalid password.  Please try again...'
  629.   ENDIF
  630. ENDDO && WHILE .t.
  631. USE
  632. RETURN
  633. * ' EOP - P0PASVAL
  634. *
  635. *
  636. * ' Procedure Name:       P0REPTQU
  637. * ' Purpose or Function:  Prompts at end of displayed report
  638. * ' Parameters Passed:    None
  639. * ' Variables Passed:     None
  640. * ' Environment Passed:   File for report assumed to be selected
  641. * ' Variables Returned:   mcont = .t. if ok to continue report
  642. *
  643. PROCEDURE p0reptqu
  644.   PRIVATE mans
  645.   STORE .t. TO mcont
  646.   STORE ' ' TO mans
  647.   IF .NOT. EOF()
  648.     SKIP
  649.   ENDIF
  650.   IF .NOT. EOF()
  651.     ?
  652.     @ 23,1 SAY 'Press any key to continue or "Q" to Quit...' ;
  653.     GET mans PICTURE '!'
  654.     READ
  655.     IF mans = 'Q'
  656.       STORE .f. TO mcont
  657.     ENDIF
  658.   ELSE
  659.     ?
  660.     @ 23,1 SAY 'End of report. Press any key to continue...' GET mans
  661.     READ
  662.     STORE .f. TO mcont
  663.   ENDIF && .NOT. EOF()
  664. RETURN
  665. * ' EOP - P0REPTQU
  666. *
  667. *
  668. * ' Procedure Name:       P0SCGRID
  669. * ' Purpose or Function:  Displays Option Grid screen
  670. * ' Parameters Passed:    mtitle = character, screen title
  671. * '                       mbottom = numeric, bottom row for screen box
  672. * ' Variables Passed:     m0border, border string from MM record
  673. * ' Variables Returned:   None
  674. *
  675. PROCEDURE p0scgrid
  676.   PARAMETERS mtitle, mbottom
  677.   PRIVATE mline, mcline
  678.   STORE SUBSTR(m0border,7,1) TO medge
  679.   STORE SUBSTR(m0border,8,1) TO mcedge
  680.   STORE SUBSTR(m0border,90,20) + SUBSTR(m0border,127,1) + ;
  681.   REPLICATE(SUBSTR(m0border,91,1),36) +  SUBSTR(m0border,127,1) + ;
  682.   SUBSTR(m0border,148,18) TO mcline
  683.   CLEAR
  684.   @ 1,4 SAY mtitle
  685.   @ 2,2 SAY SUBSTR(m0border,1,1) + SUBSTR(m0border,10,19) + ;
  686.   SUBSTR(m0border,2,1) + SUBSTR(m0border,10,36) + SUBSTR(m0border,2,1) + ;
  687.   SUBSTR(m0border,10,17) + SUBSTR(m0border,3,1)
  688.   @ 3,2 SAY medge
  689.   @ 3,22 SAY mcedge
  690.   @ 3,59 SAY mcedge
  691.   @ 3,77 SAY medge
  692.   STORE 4 TO mline
  693.   DO WHILE mline < mbottom
  694.     @ mline,2 SAY mcline
  695.     @ mline + 1,2 SAY medge
  696.     @ mline + 1,22 SAY mcedge
  697.     @ mline + 1,59 SAY mcedge
  698.     @ mline + 1,77 SAY medge
  699.     STORE mline + 2 TO mline
  700.   ENDDO
  701.   @ mline,2 SAY SUBSTR(m0border,4,1) + SUBSTR(m0border,10,19) + ;
  702.   SUBSTR(m0border,5,1) + SUBSTR(m0border,10,36) + SUBSTR(m0border,5,1) + ;
  703.   SUBSTR(m0border,10,17) + SUBSTR(m0border,6,1)
  704. RETURN
  705. * ' EOP - P0SCGRID
  706. *
  707. *
  708. * ' Procedure Name:       P0SETPRN
  709. * ' Purpose or Function:  Sets CONSOLE, DEVICE, and PRINT on request
  710. * ' Parameters Passed:    mcon = 'ON' or 'OFF' - desired CONSOLE
  711. * '                       mdev = 'SCREEN' or 'PRINT' - desired DEVICE
  712. * '                       mprt = 'ON' or 'OFF' - desired PRINT
  713. * '                       mprtno = number, user definable, default is 0
  714. * ' Variables Passed:     m0prnesc = .t. if using printer <ESC> handler
  715. * ' Environment Passed:   None
  716. * ' Variables Returned:   m0con = 'ON' or 'OFF' - new current CONSOLE
  717. * '                       m0dev = 'SCREEN' or 'PRINT' - new current DEVICE
  718. * '                       m0prt = 'ON' or 'OFF' - new current PRINT
  719. * '                       m0prnerr = .t. from P0ERRORS on printer error
  720. * ' Example:              Called as DO P0setprn WITH 'OFF', 'PRINT', 'ON', 0
  721. *
  722. PROCEDURE p0setprn
  723.   PARAMETERS mcon, mdev, mprt, mprtno
  724.   RELEASE m0con, m0dev, m0prt, m0prnerr
  725.   PUBLIC m0con, m0dev, m0prt, m0prnerr
  726.   STORE .f. TO m0con, m0dev, m0prt, m0prnerr
  727.   SET TALK OFF
  728.   SET CONSOLE ON
  729.   SET DEVICE TO SCREEN
  730.   SET PRINT OFF
  731.   * ' Store settings made so we can recover if printer error occurs
  732.   IF UPPER(mcon) = 'OFF'
  733.     STORE 'OFF' TO m0con
  734.     SET CONSOLE OFF
  735.   ELSE
  736.     STORE 'ON' TO m0con
  737.     SET CONSOLE ON
  738.   ENDIF
  739.   IF UPPER(mdev) = 'PRINT'
  740.     STORE 'PRINT' TO m0dev
  741.     SET DEVICE TO PRINT
  742.   ELSE
  743.     STORE 'SCREEN' TO m0dev
  744.     SET DEVICE TO SCREEN
  745.   ENDIF
  746.   IF UPPER(mprt) = 'ON'
  747.     STORE 'ON' TO m0prt
  748.     SET PRINT ON
  749.   ELSE
  750.     STORE 'OFF' TO m0prt
  751.     SET PRINT OFF
  752.   ENDIF
  753.   * ' m0prnesc is set by those calling pgms which allow escaping from printing
  754.   IF TYPE('m0prnesc') = 'L'
  755.     IF m0prnesc
  756.       DO p0prnesc
  757.     ENDIF
  758.   ENDIF
  759.   IF UPPER(mdev) = 'PRINT' .OR. UPPER(mprt) = 'ON'
  760.     * ' Add custom printer setup routine here using mprtno
  761.   ENDIF
  762. RETURN
  763. * ' EOP - P0SETPRN
  764. *
  765. *
  766. * ' Procedure Name:       P0AVCOST
  767. * ' Purpose or Function:  Performs Average Weighted Cost calculation.
  768. * ' Parameters Passed:    m0linkf = link file to be updated
  769. * '                       mwrk    = work area containing ARINVTnn.DBF
  770. * '                       mgllink = .t. if linked to GL, .f. if not linked
  771. * '                       mtdate  = Transaction date
  772. * '                       mvendno = Vendor/supplier number for item
  773. * '                       mbatch  = Current batch number
  774. * '                       mcost = old cost of inventory item
  775. * '                       ncost = new cost at which item received
  776. * '                       mqty  = current onhand qty of item
  777. * '                       nqty  = qty of item received
  778. * '                       minvtacc = GL inventory account
  779. * '                       miadjacc = GL Inventory Adjustment account
  780. * ' Environment Passed:   ARINVTnn.DBF must be open in work area defined
  781. * '                       with parameter MWRK, with pointer on correct item
  782. * '                       ARITRNnn.DBF must not be open
  783. * '                       xxGLLKnn.DBF must not be open
  784. * '                       Files open in work areas H and I will be closed
  785. * ' Variables Passed:     None
  786. * ' Variable Returned:    mavcost = new average weighted cost for item
  787. * ' Example:              Called as DO P0avcost WITH m0apgllkf, 'c', mlkgl,
  788. * '                       SUBSTR(DTOC(m0date)), mvendno, mbatch, mcost,
  789. * '                       ncost, mqty, nqty, minvtacc, miadjacc
  790. *
  791. PROCEDURE p0avcost
  792.   PARAMETERS m0linkf, mwrk, mgllink, mtdate, mvendno, mbatch, mcost, ;
  793.   ncost, mqty, nqty, minvtacc, miadjacc
  794.   * ' Initialize MVALUE to contain total inventory value (old + new)
  795.   PRIVATE mvalue
  796.   * ' Initialize MAVCOST to contain new average-weighted cost for item
  797.   RELEASE mavcost
  798.   PUBLIC mavcost
  799.   STORE 0.00 TO mavcost
  800.   * ' MWRK contains work area definition for ARINVTnn.DBF
  801.   STORE mwrk + '->' TO mwrk
  802.   * ' Calculate total value of inventory after receipt
  803.   STORE (mqty * mcost) + (nqty * ncost) TO mvalue
  804.   * ' Define cost for item; update ARITRN and xxGLLK if necessary
  805.   DO CASE
  806.     CASE &mwrk.stkcode <> 'Y'
  807.       * ' If item is non-stock, cost = new cost; no update to ARITRN or xxGLLK
  808.       STORE ncost TO mavcost
  809.     CASE mqty < 0 .AND. mcost <> ncost
  810.       * ' If onhand below zero and new cost <> old cost, update ARITRN and
  811.       * ' xxGLLK; calculate cost for item
  812.       SELECT h
  813.       USE &m0itrnf INDEX &m0itrnf..ndx
  814.       DO p0flockn
  815.       * ' Make adjusting entries to ARITRNnn.DBF
  816.       APPEND BLANK
  817.       REPLACE item WITH &mwrk.item, class WITH &mwrk.class, ref WITH ;
  818.       'Adjust Entry', cost WITH (mcost - ncost), qty WITH ;
  819.       MIN(ABS(mqty),nqty), vendno WITH mvendno
  820.       REPLACE code WITH 'A', seq WITH &mwrk.seq, tdate WITH mtdate, ;
  821.       glasst WITH &mwrk.gllink, batch WITH mbatch
  822.       IF mgllink
  823.         * ' If linked to GL, make adjusting entry to xxGLLKnn.DBF
  824.         SELECT i
  825.         USE &m0linkf INDEX &m0linkf..ndx
  826.         DO p0flockn
  827.         * ' Make adjusting entry to GL Inventory account (debit)
  828.         SEEK minvtacc
  829.         IF EOF()
  830.           APPEND BLANK
  831.           REPLACE account WITH minvtacc
  832.         ENDIF
  833.         IF amount + (h->cost * h->qty) > 0
  834.           REPLACE amount WITH amount + .001 * INT(1000 * h->cost * ;
  835.           h->qty + .5)
  836.         ELSE
  837.           REPLACE amount WITH amount + .001 * INT(1000 * h->cost * ;
  838.           h->qty - .5)
  839.         ENDIF
  840.         * ' Make adjusting entry to GL Inventory Adj account (credit)
  841.         SEEK miadjacc
  842.         IF EOF()
  843.           APPEND BLANK
  844.           REPLACE account WITH miadjacc
  845.         ENDIF
  846.         IF amount + (0 - (h->cost * h->qty)) > 0
  847.           REPLACE amount WITH amount + (0 - .001 * INT(1000 * ;
  848.           h->cost * h->qty + .5))
  849.         ELSE
  850.           REPLACE amount WITH amount + (0 - .001 * INT(1000 * ;
  851.           h->cost * h->qty - .5))
  852.         ENDIF
  853.         USE
  854.         SELECT h
  855.       ENDIF && mgllink
  856.       IF mqty + nqty >= 0.00 .OR. mvalue = 0.00
  857.         * ' If new qty + old qty >= 0 or value = 0, cost = new cost
  858.         STORE ncost TO mavcost
  859.       ELSE
  860.         * ' Leave cost the same if new onhand < 0
  861.         STORE mcost TO mavcost
  862.       ENDIF
  863.       USE
  864.     CASE mqty + nqty = 0.00 .OR. mvalue = 0.00
  865.       * ' If new onhand or new value is zero, cost = new cost
  866.       STORE ncost TO mavcost
  867.     OTHERWISE
  868.       * ' Cost = average weighted cost if onhand > 0.00
  869.       IF mvalue / (mqty + nqty) < 0
  870.         STORE .001 * INT(1000 * mvalue / (mqty + nqty) - .5) TO mavcost
  871.       ELSE
  872.         STORE .001 * INT(1000 * mvalue / (mqty + nqty) + .5) TO mavcost
  873.       ENDIF
  874.   ENDCASE
  875. RETURN
  876. * ' EOP - P0AVCOST
  877. *
  878. *
  879. * ' Procedure Name:       P0PRNESC
  880. * ' Purpose or Function:  Printer <ESC> control, allows graceful exit
  881. * ' Parameters Passed:    None
  882. * ' Variables Passed:     m0prt  =  set printer 'ON' or 'OFF'
  883. * '                       m0stpprn = Print error msg if printing stopped
  884. * ' Environment Passed:   Sets value for ON ESCAPE
  885. * ' Variables Returned:   m0prnesc = back to .f. if printer being turned off
  886. * '                       m0stpprn = back to .f. if .t. and print off
  887. *
  888. * ' This procedure to be used ONLY for non-clipper code
  889. *
  890. PROCEDURE p0prnesc
  891.   DO CASE
  892.     CASE m0prt = 'ON' .OR. m0dev = 'PRINT'
  893.       ON ESCAPE STORE .t. TO m0stpprn
  894.     CASE m0prt = 'OFF'
  895.       ON ESCAPE DO p0escape
  896.       STORE .f. TO m0prnesc
  897.       IF m0stpprn
  898.         ?? CHR(7)
  899.         STORE .f. TO m0stpprn
  900.         STORE ' ' TO mans
  901.         @ 23,0 CLEAR
  902.         @ 23,2 SAY 'Printing interrupted by <ESC>.  Press any key to ' + ;
  903.         'return to menu....' GET mans
  904.         READ
  905.       ENDIF
  906.   ENDCASE
  907. RETURN
  908. * ' EOP - P0PRNESC
  909. *
  910. *
  911. * ' Procedure Name:       P0ESCAPE
  912. * ' Purpose or Function:  Escape Key event handler (from ON ESCAPE call)
  913. * ' Parameters Passed:    None
  914. * ' Variables Passed:     None
  915. * ' Environment Passed:   None
  916. * ' Variables Returned:   None
  917. *
  918. PROCEDURE p0escape
  919.   PRIVATE mln, moptns, msg, mwait
  920.   SET TALK OFF
  921.   SET CONSOLE ON
  922.   SET DEVICE TO SCREEN
  923.   SET PRINT OFF
  924.   CLEAR TYPEAHEAD
  925.   STORE ' ' TO mwait
  926.   STORE 24 TO mln
  927.   IF TYPE('m0switchar') = 'C'
  928.     STORE IIF(m0switchar = '/',23,24) TO mln
  929.   ENDIF
  930.   @ mln,0
  931.   ?? CHR(7) + CHR(7)
  932.   IF 'OFF' $ UPPER(GETE('ONERROR'))
  933.     * ' if debugging variable set, allow SUSPEND on S
  934.     STORE 'Esc key pressed.  (Ignore/Suspend/Quit) ' TO msg
  935.     STORE 'ISQ' TO moptns
  936.   ELSE
  937.     STORE 'Esc key pressed.  (Ignore/Quit) ' TO msg
  938.     STORE 'IQ' TO moptns
  939.   ENDIF
  940.   @ mln,38 - INT(LEN(msg)/2) SAY msg GET mwait PICTURE '!'
  941.   READ SAVE
  942.   DO WHILE .NOT. mwait $ moptns
  943.     ?? CHR(7)
  944.     READ SAVE
  945.   ENDDO
  946.   @ mln,0
  947.   CLEAR GETS
  948.   DO CASE
  949.     CASE mwait = 'S'
  950.       SUSPEND
  951.       DO p0clrprn
  952.     CASE mwait = 'I'
  953.       DO p0clrprn
  954.       RETRY
  955.     CASE mwait = 'Q'
  956.       DO p0clrenv
  957.       QUIT
  958.   ENDCASE
  959. RETURN
  960. * ' EOP - P0ESCAPE
  961. *
  962. *
  963. * ' Procedure Name:       P0ERRORS
  964. * ' Purpose or Function:  Error handling
  965. * ' Parameters Passed:    errornum = Error Number (from ON ERROR)
  966. * '                       errormes = Error Message (from ON ERROR)
  967. * ' Variables Passed:     None
  968. * ' Environment Passed:   None
  969. * ' Variables Returned:   m0prnerr = .t. if printer error occured
  970. *
  971. PROCEDURE p0errors
  972.   PARAMETER errornum, errormes
  973.   CLEAR GETS
  974.   SET TALK OFF
  975.   PRIVATE mans, mln, mretry, mreturn, mrecno, mwait, mxcon, mxdev, mxprt
  976.   RELEASE m0prnerr
  977.   PUBLIC m0prnerr
  978.   STORE .f. TO m0prnerr
  979.   * ' Store printer condition for print errors, use to restore environment
  980.   STORE m0con TO mxcon
  981.   STORE m0dev TO mxdev
  982.   STORE m0prt TO mxprt
  983.   * ' Force set screen/print environment to display error messages
  984.   SET CONSOLE ON
  985.   SET DEVICE TO SCREEN
  986.   SET PRINT OFF
  987.   * ' And store the new environment
  988.   STORE 'ON' TO m0con
  989.   STORE 'SCREEN' TO m0dev
  990.   STORE 'OFF' TO m0prt
  991.   * ' If you have an error, discard assumptions leading to typeahead
  992.   CLEAR TYPEAHEAD
  993.   * ' In case of gets still open on error
  994.   CLEAR GETS
  995.   STORE ' ' TO mwait
  996.   STORE .f. TO mreturn
  997.   STORE 24 TO mln
  998.   * ' Move error line for 23 line Xenix screens
  999.   IF TYPE('m0switchar') = 'C'
  1000.     STORE IIF(m0switchar = '/',23,24) TO mln
  1001.   ENDIF
  1002.   @ mln,0
  1003.   * ' Error Handling Section - specific errors first
  1004.   DO CASE
  1005.     CASE errornum = 1
  1006.       * ' file does not exist
  1007.       DO syshelp WITH errornum
  1008.       ON ERROR
  1009.       RETRY
  1010.     CASE errornum = 5
  1011.       * ' record out of range - damaged index file
  1012.       DO syshelp WITH errornum
  1013.       DO p0clrenv
  1014.       QUIT
  1015.     CASE errornum = 6
  1016.       * ' too many files open error
  1017.       CLOSE DATABASES
  1018.       DO syshelp WITH errornum
  1019.       DO p0clrenv
  1020.       QUIT
  1021.     CASE errornum = 10
  1022.       * ' syntax error
  1023.       DO syshelp WITH errornum
  1024.       ON ERROR
  1025.       RETRY
  1026.     CASE errornum = 12
  1027.       * ' variable not found
  1028.       DO syshelp WITH errornum
  1029.       ON ERROR
  1030.       RETRY
  1031.     CASE errornum = 15
  1032.       * ' not a dBASE III database file or corrupted
  1033.       DO syshelp WITH errornum
  1034.       DO p0clrenv
  1035.       QUIT
  1036.     CASE errornum = 16
  1037.       * ' unrecognized command verb
  1038.       DO syshelp WITH errornum
  1039.       ON ERROR
  1040.       RETRY
  1041.     CASE errornum = 19
  1042.       * ' index file does not match data file
  1043.       DO syshelp WITH errornum
  1044.       DO p0clrenv
  1045.       QUIT
  1046.     CASE errornum = 29
  1047.       * ' file not accessible or filename is illegal
  1048.       DO syshelp WITH errornum
  1049.       DO p0clrenv
  1050.       QUIT
  1051.     CASE errornum = 43
  1052.       * ' insufficient memory
  1053.       DO syshelp WITH errornum
  1054.       DO p0clrenv
  1055.       QUIT
  1056.     CASE errornum = 56
  1057.       * ' disk full on attempted write
  1058.       DO syshelp WITH errornum
  1059.       DO p0clrenv
  1060.       QUIT
  1061.     CASE errornum = 111
  1062.       * ' attempted write to read only file
  1063.       DO syshelp WITH errornum
  1064.       DO p0clrenv
  1065.       QUIT
  1066.     CASE errornum = 114
  1067.       * ' index file corrupted
  1068.       DO syshelp WITH errornum
  1069.       DO p0clrenv
  1070.       QUIT
  1071.     CASE errornum = 125 .OR. errornum = 126
  1072.       * ' printer not ready/not installed error - retry
  1073.       ?? CHR(7)
  1074.       STORE 'Y' TO mans
  1075.       @ mln,0 SAY 'Printer Not Ready. Please correct problem. ' + ;
  1076.       'Ready to Print? (Y/N) ' GET mans PICTURE 'Y'
  1077.       READ
  1078.       IF mans = 'N'
  1079.         DO p0clrenv
  1080.         QUIT
  1081.       ENDIF
  1082.       STORE .t. TO m0prnerr
  1083.       STORE .f. TO mreturn
  1084.     CASE errornum = 108 .AND. '' <> DBF()
  1085.       * ' file locked and cannot access - wait and retry
  1086.       @ mln,0 SAY TRIM(UPPER(DBF())) + ;
  1087.       ' in EXCLUSIVE use by another. Retrying...'
  1088.       STORE 1 TO mretry
  1089.       DO WHILE mretry < 100
  1090.         STORE mretry + 1 TO mretry
  1091.       ENDDO
  1092.       STORE .f. TO mreturn
  1093.     CASE errornum = 109
  1094.       * ' record locked and cannot access - wait and retry
  1095.       @ mln,0 SAY TRIM(UPPER(DBF())) + ' Rec in use by another. ' + ;
  1096.       'Retrying...'
  1097.       STORE 1 TO mretry
  1098.       DO WHILE mretry < 100
  1099.         STORE mretry + 1 TO mretry
  1100.       ENDDO
  1101.       STORE .f. TO mreturn
  1102.     CASE errornum = 110 .AND. '' <> DBF()
  1103.       * ' file operation requires exclusive use
  1104.       STORE 'Y' TO mans
  1105.       @ mln,0 SAY TRIM(UPPER(DBF())) + '. EXCLUSIVE USE needed. ' + ;
  1106.       'Retry? (Y/N) ' GET mans PICTURE 'Y'
  1107.       READ
  1108.       IF mans = 'N'
  1109.         DO p0clrenv
  1110.         QUIT
  1111.       ENDIF
  1112.       STORE RECNO() TO mrecno
  1113.       DO CASE
  1114.         CASE '' <> NDX(1) .AND. '' <> NDX(2) .AND. '' <> NDX(3)
  1115.           STORE DBF() + ' INDEX ' + NDX(1) + ', ' + NDX(2) + ', ' + NDX(3) TO ;
  1116.           mans
  1117.         CASE '' <> NDX(1) .AND. '' <> NDX(2)
  1118.           STORE DBF() + ' INDEX ' + NDX(1) + ', ' + NDX(2) TO mans
  1119.         CASE '' <> NDX(1)
  1120.           STORE DBF() + ' INDEX ' + NDX(1) TO mans
  1121.         OTHERWISE
  1122.           STORE DBF() TO mans
  1123.       ENDCASE
  1124.       USE &mans EXCLUSIVE
  1125.       STORE .f. TO mreturn
  1126.     CASE errornum = 128
  1127.       * ' skip to locked record
  1128.       ?? CHR(7)
  1129.       @ mln,0 SAY TRIM(UPPER(DBF())) + '. Skip to locked record.  Retrying...'
  1130.       STORE 1 TO mretry
  1131.       DO WHILE mretry < 200
  1132.         STORE mretry + 1 TO mretry
  1133.       ENDDO
  1134.       STORE .f. TO mreturn
  1135.     CASE errornum = 130
  1136.       * ' record not locked error - do locking without display procedure
  1137.       ?? CHR(7)
  1138.       @ mln,0 SAY ;
  1139.       TRIM(UPPER(DBF())) + '. Unlocked REPLACE attempted.  Retrying...'
  1140.       DO p0rlockn
  1141.       STORE .f. TO mreturn
  1142.     OTHERWISE
  1143.       * ' General Errors Section
  1144.       DO WHILE .NOT. mwait $ 'IRSQ'
  1145.         ?? CHR(7)
  1146.         @ mln,0 CLEAR
  1147.         @ mln,0 SAY 'Error: ' + LTRIM(STR(errornum,4,0)) + ;
  1148.         ', ' + TRIM(errormes)
  1149.         @ mln,48 SAY ' (Ignore/Retry/Suspend/Quit) 'GET mwait PICTURE '!'
  1150.         READ
  1151.       ENDDO
  1152.       @ mln,0 CLEAR
  1153.       DO CASE
  1154.         CASE mwait = 'I'
  1155.           DO p0clrprn
  1156.           STORE .t. TO mreturn
  1157.         CASE mwait = 'R'
  1158.           DO p0clrprn
  1159.           STORE .f. TO mreturn
  1160.         CASE mwait = 'S'
  1161.           ?
  1162.           ? 'Error/Escape trapping disabled.'
  1163.           ON ERROR
  1164.           ON ESCAPE
  1165.           SUSPEND
  1166.           STORE .f. TO mreturn
  1167.         CASE mwait = 'Q'
  1168.           DO p0clrenv
  1169.           QUIT
  1170.       ENDCASE
  1171.   ENDCASE
  1172.   @ mln,0
  1173.   STORE mxcon TO m0con
  1174.   STORE mxdev TO m0dev
  1175.   STORE mxprt TO m0prt
  1176.   DO p0clrprn
  1177.   IF mreturn
  1178.   RETURN
  1179. ELSE
  1180.   RETRY
  1181. ENDIF
  1182. * ' EOP - P0ERRORS
  1183. *
  1184. *
  1185. * ' Procedure Name:       P0FLOCKD
  1186. * ' Purpose or Function:  Locks file with display of prompt
  1187. * ' Parameters Passed:    None
  1188. * ' Variables Passed:     None
  1189. * ' Environment Passed:   File to be locked open in current area
  1190. * ' Variables Returned:   lockedf = logical, .t. if file locked
  1191. *
  1192. PROCEDURE p0flockd
  1193.   PRIVATE mwait, mln, msg
  1194.   RELEASE lockedf
  1195.   PUBLIC lockedf
  1196.   STORE .f. TO lockedf
  1197.   STORE '' TO msg
  1198.   DO CASE
  1199.     CASE LEN(DBF()) = 0
  1200.       STORE 'FLOCK Attempt with no file open. ' TO msg
  1201.     CASE FLOCK()
  1202.       STORE .t. TO lockedf
  1203.   ENDCASE
  1204.   IF .NOT. lockedf
  1205.     SET CONSOLE ON
  1206.     SET DEVICE TO SCREEN
  1207.     SET PRINT OFF
  1208.     STORE 24 TO mln
  1209.     IF TYPE('m0switchar') = 'C'
  1210.       STORE IIF(m0switchar = '/',23,24) TO mln
  1211.     ENDIF
  1212.     @ mln,0
  1213.     IF LEN(msg) > 0
  1214.       ?? CHR(7)
  1215.       STORE ' ' TO mwait
  1216.       @ mln,0 SAY msg + ' Press any key...' GET mwait
  1217.       READ
  1218.     ELSE
  1219.       STORE 'Y' TO mwait
  1220.       DO WHILE .NOT. lockedf
  1221.         ?? CHR(7)
  1222.         @ mln,0 SAY TRIM(UPPER(DBF())) + ' in use. Retry File Lock? (Y/N) ' ;
  1223.         GET mwait PICTURE 'Y'
  1224.         READ
  1225.         IF mwait = 'N'
  1226.           EXIT
  1227.         ENDIF
  1228.         STORE FLOCK() TO lockedf
  1229.       ENDDO
  1230.     ENDIF && LEN(msg) > 0
  1231.     @ mln,0
  1232.     DO p0clrprn
  1233.   ENDIF && .NOT. lockedf
  1234. RETURN
  1235. * ' EOP - P0FLOCKD
  1236. *
  1237. *
  1238. * ' Procedure Name:       P0FLOCKN
  1239. * ' Purpose or Function:  Locks file WITHOUT display of prompt
  1240. * ' Parameters Passed:    None
  1241. * ' Variables Passed:     None
  1242. * ' Environment Passed:   File to be locked open in current area
  1243. * ' Variables Returned:   lockedf = logical, .t. if file locked
  1244. *
  1245. PROCEDURE p0flockn
  1246.   PRIVATE mwait, mln, msg
  1247.   RELEASE lockedf
  1248.   PUBLIC lockedf
  1249.   STORE .f. TO lockedf
  1250.   STORE '' TO msg
  1251.   DO CASE
  1252.     CASE LEN(DBF()) = 0
  1253.       STORE 'FLOCK Attempt with no file open. ' TO msg
  1254.     CASE FLOCK()
  1255.       STORE .t. TO lockedf
  1256.   ENDCASE
  1257.   IF .NOT. lockedf
  1258.     IF TYPE ('m0color') = 'C'
  1259.       SET CONSOLE ON
  1260.       SET DEVICE TO SCREEN
  1261.       SET PRINT OFF
  1262.       STORE 24 TO mln
  1263.       IF TYPE('m0switchar') = 'C'
  1264.         STORE IIF(m0switchar = '/',23,24) TO mln
  1265.       ENDIF
  1266.       @ mln,0
  1267.     ENDIF
  1268.     IF LEN(msg) > 0
  1269.       STORE .t. TO lockedf
  1270.       ?? CHR(7)
  1271.       STORE ' ' TO mwait
  1272.       @ mln,0 SAY msg + ' Press any key...' GET mwait
  1273.       READ
  1274.     ELSE
  1275.       DO WHILE .NOT. lockedf
  1276.         IF TYPE ('m0color') = 'C'
  1277.           @ mln,0 SAY ;
  1278.           TRIM(UPPER(DBF())) + ' in use. Attempting to lock file...'
  1279.         ENDIF
  1280.         STORE FLOCK() TO lockedf
  1281.       ENDDO
  1282.     ENDIF && LEN(msg) > 0
  1283.     IF TYPE ('m0color') = 'C'
  1284.       @ mln,0
  1285.       DO p0clrprn
  1286.     ENDIF
  1287.   ENDIF && .NOT. lockedf
  1288. RETURN
  1289. * ' EOP - P0FLOCKN
  1290. *
  1291. *
  1292. * ' Procedure Name:       P0RLOCKD
  1293. * ' Purpose or Function:  Locks Record with display of prompt
  1294. * ' Parameters Passed:    None
  1295. * ' Variables Passed:     None
  1296. * ' Environment Passed:   Record to be locked open in current area
  1297. * ' Variables Returned:   lockedr = logical, .t. if record locked
  1298. *
  1299. PROCEDURE p0rlockd
  1300.   PRIVATE mwait, mln, msg
  1301.   RELEASE lockedr
  1302.   PUBLIC lockedr
  1303.   STORE .f. TO lockedr
  1304.   STORE '' TO msg
  1305.   DO CASE
  1306.     CASE LEN(DBF()) = 0
  1307.       STORE 'RLOCK Attempt with no file open. ' TO msg
  1308.     CASE BOF() .OR. EOF()
  1309.       STORE 'RLOCK at E/BOF() of ' + TRIM(UPPER(DBF())) TO msg
  1310.     CASE RLOCK()
  1311.       STORE .t. TO lockedr
  1312.   ENDCASE
  1313.   IF .NOT. lockedr
  1314.     SET CONSOLE ON
  1315.     SET DEVICE TO SCREEN
  1316.     SET PRINT OFF
  1317.     STORE 24 TO mln
  1318.     IF TYPE('m0switchar') = 'C'
  1319.       STORE IIF(m0switchar = '/',23,24) TO mln
  1320.     ENDIF
  1321.     @ mln,0
  1322.     IF LEN(msg) > 0
  1323.       ?? CHR(7)
  1324.       STORE ' ' TO mwait
  1325.       @ mln,0 SAY msg + ' Press any key...' GET mwait
  1326.       READ
  1327.     ELSE
  1328.       STORE 'Y' TO mwait
  1329.       DO WHILE .NOT. lockedr
  1330.         ?? CHR(7)
  1331.         @ mln,0 SAY TRIM(UPPER(DBF())) + ' in use. Retry Rec Lock? (Y/N) ' ;
  1332.         GET mwait PICTURE 'Y'
  1333.         READ
  1334.         IF mwait = 'N'
  1335.           EXIT
  1336.         ENDIF
  1337.         STORE RLOCK() TO lockedr
  1338.       ENDDO
  1339.     ENDIF && LEN(msg) > 0
  1340.     @ mln,0
  1341.     DO p0clrprn
  1342.   ENDIF && .NOT. lockedr
  1343. RETURN
  1344. * ' EOP - P0RLOCKD
  1345. *
  1346. *
  1347. * ' Procedure Name:       P0RLOCKN
  1348. * ' Purpose or Function:  Locks record WITHOUT display of prompt
  1349. * ' Parameters Passed:    None
  1350. * ' Variables Passed:     None
  1351. * ' Environment Passed:   Record to be locked open in current area
  1352. * ' Variables Returned:   lockedr = logical, .t. if record locked
  1353. *
  1354. PROCEDURE p0rlockn
  1355.   PRIVATE mwait, mln, msg
  1356.   RELEASE lockedr
  1357.   PUBLIC lockedr
  1358.   STORE .f. TO lockedr
  1359.   STORE '' TO msg
  1360.   DO CASE
  1361.     CASE LEN(DBF()) = 0
  1362.       STORE 'RLOCK Attempt with no file open. ' TO msg
  1363.     CASE BOF() .OR. EOF()
  1364.       STORE 'RLOCK at E/BOF() of ' + TRIM(UPPER(DBF())) TO msg
  1365.     CASE RLOCK()
  1366.       STORE .t. TO lockedr
  1367.   ENDCASE
  1368.   IF .NOT. lockedr
  1369.     STORE 24 TO mln
  1370.     IF TYPE('m0switchar') = 'C'
  1371.       STORE IIF(m0switchar = '/',23,24) TO mln
  1372.     ENDIF
  1373.     IF TYPE ('m0color') = 'C'
  1374.       SET CONSOLE ON
  1375.       SET DEVICE TO SCREEN
  1376.       SET PRINT OFF
  1377.       @ mln,0
  1378.     ENDIF
  1379.     IF LEN(msg) > 0
  1380.       STORE .t. TO lockedr
  1381.       ?? CHR(7)
  1382.       STORE ' ' TO mwait
  1383.       @ mln,0 SAY msg + ' Press any key...' GET mwait
  1384.       READ
  1385.     ELSE
  1386.       DO WHILE .NOT. lockedr
  1387.         IF TYPE ('m0color') = 'C'
  1388.           @ mln,0 SAY ;
  1389.           TRIM(UPPER(DBF())) + ' in use. Attempting to lock record...'
  1390.         ENDIF
  1391.         STORE RLOCK() TO lockedr
  1392.       ENDDO
  1393.     ENDIF && LEN(msg) > 0
  1394.     IF TYPE ('m0color') = 'C'
  1395.       @ mln,0
  1396.       DO p0clrprn
  1397.     ENDIF
  1398.   ENDIF && .NOT. lockedr
  1399. RETURN
  1400. * ' EOP - P0RLOCKN
  1401. *
  1402. *
  1403. * ' Procedure Name:       P0REREAD
  1404. * ' Purpose or Function:  Checks signature field of file before updating
  1405. * ' Parameters Passed:    msignature = numeric, previous signature value
  1406. * ' Variables Passed:     None
  1407. * ' Environment Passed:   Record to be checked open in current area
  1408. * ' Variables Returned:   unaltered = logical, .f. if record been altered
  1409. *
  1410. PROCEDURE p0reread
  1411.   PARAMETER msignature
  1412.   PRIVATE mwait, mln
  1413.   STORE 24 TO mln
  1414.   IF TYPE('m0switchar') = 'C'
  1415.     STORE IIF(m0switchar = '/',23,24) TO mln
  1416.   ENDIF
  1417.   RELEASE unaltered
  1418.   PUBLIC unaltered
  1419.   STORE ' ' TO mwait
  1420.   STORE .t. TO unaltered
  1421.   * ' Skip multiuser function if setup as single user
  1422.   IF .NOT. m0single
  1423.     IF signature <> msignature
  1424.       UNLOCK
  1425.       @ mln,0
  1426.       ?? CHR(7)
  1427.       @ mln,3 SAY 'Record has been altered by another user. Press any key...' ;
  1428.       GET mwait
  1429.       READ
  1430.       @ mln,0
  1431.       STORE .f. TO unaltered
  1432.     ENDIF
  1433.   ENDIF
  1434. RETURN
  1435. * ' EOP - P0REREAD
  1436. *
  1437. *
  1438. * ' Procedure Name:       P0SYSMNT
  1439. * ' Purpose or Function:  Checks for other users and sets Sys Maint. flag
  1440. * ' Parameters Passed:    mflag   = logical with .t. = entering
  1441. * '                                              .f. = leaving
  1442. * ' Variables Passed:     m0sysdr = System Drive for SYSDATA.DBF
  1443. * ' Environment Passed:   SYSDATA.DBF assumed not to be open in other areas
  1444. * ' Variables Returned:   mreturn = logical, .t. if okay to continue
  1445. *
  1446. PROCEDURE p0sysmnt
  1447.   PARAMETER mflag
  1448.   RELEASE mreturn
  1449.   PUBLIC mreturn
  1450.   PRIVATE mok, mans
  1451.   STORE .t. TO mok
  1452.   * ' Skip multiuser function if setup as single user
  1453.   IF .NOT. m0single
  1454.     STORE .f. TO mreturn
  1455.     IF TYPE('m0sysdr') <> 'C'
  1456.       STORE '' TO m0sysdr
  1457.     ENDIF
  1458.     IF FILE('&m0sysdr.sysdata.dbf')
  1459.       USE &m0sysdr.sysdata
  1460.       LOCATE FOR UPPER(sysid) = 'MM  '
  1461.       IF EOF()
  1462.         STORE .f. TO mok
  1463.       ELSE
  1464.         DO p0rlockd
  1465.         IF .NOT. lockedr
  1466.           USE
  1467.         RETURN
  1468.       ENDIF
  1469.       IF mflag
  1470.         IF num10 > 1
  1471.           STORE ' ' TO mans
  1472.           USE
  1473.           * ' Display 'Requires only one user...' error message
  1474.           DO syshelp WITH 10001
  1475.           RETURN
  1476.         ENDIF
  1477.         IF SUBSTR(str10,1,1) = 'Y'
  1478.           STORE ' ' TO mans
  1479.           USE
  1480.           * ' Display 'System Maintenance operation...' error message
  1481.           DO syshelp WITH 10002
  1482.           RETURN
  1483.         ENDIF
  1484.         REPLACE str10 WITH 'Y' + SUBSTR(str10,2,9)
  1485.       ELSE
  1486.         REPLACE str10 WITH 'N' + SUBSTR(str10,2,9)
  1487.       ENDIF
  1488.     ENDIF
  1489.   ENDIF
  1490.   IF .NOT. mok
  1491.     STORE ' ' TO mans
  1492.     USE
  1493.     * ' Display 'SYSDATA record or file missing...' error message
  1494.     DO syshelp WITH 9001
  1495.     DO p0clrenv
  1496.     CANCEL
  1497.   ENDIF
  1498. ENDIF
  1499. STORE .t. TO mreturn
  1500. USE
  1501. RETURN
  1502. * ' EOP - P0SYSMNT
  1503. *
  1504. *
  1505. * ' Procedure Name:       P0USRCNT
  1506. * ' Purpose or Function:  Maintains count of users in all modules
  1507. * ' Parameters Passed:    mincr   = logical, .t. = increment, .f. = decrement
  1508. * ' Variables Passed:     m0sysdr = System Drive for SYSDATA.DBF
  1509. * ' Environment Passed:   SYSDATA.DBF assumed not to be open in other areas
  1510. * ' Variables Returned:   none
  1511. *
  1512. PROCEDURE p0usrcnt
  1513.   PARAMETER mincr
  1514.   * ' Skip multiuser function if setup as single user
  1515.   IF .NOT. m0single
  1516.     IF TYPE('m0sysdr') <> 'C'
  1517.       STORE '' TO m0sysdr
  1518.     ENDIF
  1519.     IF FILE('&m0sysdr.sysdata.dbf')
  1520.       USE &m0sysdr.sysdata
  1521.       LOCATE FOR UPPER(sysid) = 'MM  '
  1522.       IF .NOT. EOF()
  1523.         DO p0rlockn
  1524.         IF mincr
  1525.           REPLACE num10 WITH num10 + 1
  1526.         ELSE
  1527.           REPLACE num10 WITH IIF(num10 - 1 >= 0, num10 - 1, 0)
  1528.         ENDIF
  1529.         UNLOCK
  1530.       ENDIF
  1531.     ENDIF
  1532.   ENDIF
  1533. RETURN
  1534. * ' EOP - P0USRCNT
  1535. *
  1536. *
  1537. *
  1538. * ' Procedure Name:       P0ARRAYS
  1539. * ' Purpose or Function:  Create arrays for menu litebars
  1540. * ' Environment:          Opens SYS??MN.DBF in area I
  1541. * ' Parameters Passed:    None
  1542. * ' Variables Passed:     None
  1543. * ' Variables Returned:   a0?????? = Arrays with names of menu prgs
  1544. *
  1545. * ' Data Structure for SYS??MN.DBF
  1546. * ' Field Name  Type       Width
  1547. *
  1548. * ' MENUPRG     Character      8  = Calling menu program (e.g. ARMENU)
  1549. * ' COND        Character     55  = Condition for prompt to be active;
  1550. * '                                 .t. = Always active
  1551. * ' TITLE       Character     43  = Prompt contents (including option #)
  1552. * ' DISPROW     Numeric        2  = Row to display prompt
  1553. * ' DISPCOL     Numeric        2  = Column to display prompt
  1554. * ' OPPCOL      Numeric        2  = Count for opposite column, 0 if none
  1555. *
  1556. PROCEDURE p0arrays
  1557.   * ' Clear path and set default to dbf drive first
  1558.   SET PATH TO
  1559.   SET DEFAULT TO &m0dbfdr
  1560.   IF FILE('&m0passf..dbf')
  1561.     @ 22,0
  1562.     @ 22,8 SAY 'Building Arrays for Light Bar Menus...'
  1563.     * ' Turn off ESCAPE in routine to prevent odd INKEY interactions
  1564.     SET ESCAPE OFF
  1565.     * ' Initialize menu file variables
  1566.     STORE 'SYS' + m0pgmid + 'MN' TO menuf
  1567.     STORE 'SYS' + m0pgmid + 'MO' TO menuo
  1568.     * ' columns in arrays NB: Col 5 used in row 1 to store array size (msize)
  1569.     STORE 1 TO ztitle
  1570.     STORE 2 TO zrow
  1571.     STORE 3 TO zcol
  1572.     STORE 4 TO zoppcol
  1573.     * ' Open Menu file with index by location in work area I
  1574.     SELECT i
  1575.     USE &m0sysdr.&menuf INDEX &m0sysdr.&menuo..ndx
  1576.     * ' Primary Index:  menuprg+SUBSTR(STR(1000 + disprow + dispcol,4,0),2,3)
  1577.     IF EOF()
  1578.       * ' call error message if empty file
  1579.       DO syshelp WITH 9006
  1580.       CANCEL
  1581.     ENDIF
  1582.     DO WHILE .NOT. EOF()
  1583.       STORE i->menuprg TO mmenu
  1584.       * ' define name of the array
  1585.       STORE 'a0' + TRIM(i->menuprg) TO zmenu
  1586.       * ' count the number of options in this menu
  1587.       COUNT TO msize WHILE i->menuprg = mmenu
  1588.       * ' Two-dimensional array. Array is # menu options by # fields in file.
  1589.       * ' Release array memvars before defining public
  1590.       RELEASE &zmenu
  1591.       PUBLIC &zmenu(msize,5)
  1592.       SEEK mmenu
  1593.       STORE 1 TO mcount
  1594.       * ' Add values to array from MENU file for current menu
  1595.       DO WHILE i->menuprg = mmenu .AND. .NOT. EOF()
  1596.         * ' Add values to sub-arrays from MENU file for current menu
  1597.         STORE i->title TO &zmenu(mcount,ztitle)
  1598.         STORE i->cond TO mcond
  1599.         IF &mcond .AND. .NOT. DELETED()
  1600.           * ' Add to array if menu option availbl under current system choices
  1601.           STORE i->disprow TO &zmenu(mcount,zrow)
  1602.           STORE i->dispcol TO &zmenu(mcount,zcol)
  1603.           IF TYPE('&zmenu(mcount,zoppcol)') = 'L'
  1604.             * ' If opposite column not yet initialized to 0 by unavailable option
  1605.             STORE i->oppcol TO &zmenu(mcount,zoppcol)
  1606.           ENDIF
  1607.         ELSE
  1608.           * ' Create zeroed entry if menu option not available
  1609.           STORE 0 TO &zmenu(mcount,zrow)
  1610.           STORE 0 TO &zmenu(mcount,zcol)
  1611.           STORE 0 TO &zmenu(mcount,zoppcol)
  1612.           IF i->oppcol <> 0
  1613.             * ' Define current option unavailable from opposite option
  1614.             STORE 0 TO &zmenu(i->oppcol,zoppcol)
  1615.           ENDIF
  1616.         ENDIF
  1617.         STORE mcount + 1 TO mcount
  1618.         SKIP
  1619.       ENDDO && WHILE i->menuprg = mmenu .AND. .NOT. EOF()
  1620.       STORE msize TO &zmenu(1,5)
  1621.       STORE 0 TO &zmenu(2,5)
  1622.     ENDDO && WHILE .NOT. EOF()
  1623.     * ' Create memfile if not running under Clipper
  1624.     IF TYPE('m0arrayf') = 'C'
  1625.       SAVE ALL LIKE a0* TO &m0arrayf..mem
  1626.     ENDIF
  1627.     RELEASE ztitle, zrow, zcol, zoppcol
  1628.     * ' Close menu file and reopen primary work area
  1629.     USE
  1630.     SELECT a
  1631.     @ 22,0
  1632.   ENDIF
  1633.   IF m0switchar $ m0cmddr
  1634.     SET PATH TO &m0cmddr
  1635.     SET DEFAULT TO &m0sysdr
  1636.   ELSE
  1637.     SET DEFAULT TO &m0cmddr
  1638.   ENDIF
  1639. RETURN
  1640. * ' EOP - P0ARRAYS
  1641. *
  1642. *
  1643. *
  1644. * ' Procedure Name:       P0SELECT
  1645. * ' Purpose or Function:  Provides hilighted bar options for menu programs
  1646. * ' Parameters Passed:    mmenu    = name of calling program
  1647. * '                       mstart   = the default choice when entering
  1648. * '                                  (Usually 'Q')
  1649. * '                       mvalopts = valid choices for the menu involved
  1650. * '                       choice   = initial choice value (usually ' ')
  1651. * '                       mcol1    = left column
  1652. * '                       mcol2    = right column (zero if single col menu)
  1653. * ' Variables Passed:     None
  1654. * ' Variables Returned:   choice   = The option chosen
  1655. *
  1656. * ' Example:  DO p0select WITH 'ARMENU', 'Q', 'Q12345FICUABCPR', ' ', 5, 42
  1657. *
  1658. PROCEDURE p0select
  1659.   PARAMETERS mmenu, mstart, mvalopts, choice, mcol1, mcol2
  1660.   * ' Turn off ESCAPE in routine to prevent odd INKEY interactions
  1661.   SET ESCAPE OFF
  1662.   * ' most lite bars should be 33 characters long.  If longer mbarlen is fed
  1663.   IF TYPE('mbarlen') = 'U'
  1664.     STORE 33 TO mbarlen
  1665.   ENDIF
  1666.   * ' Get array size from first entry for current menu
  1667.   STORE 'a0' + TRIM(mmenu) TO zmenu
  1668.   * ' Col 5 used in row 1 to store array size (msize)
  1669.   STORE &zmenu(1,5) TO msize
  1670.   STORE 1 TO ztitle
  1671.   STORE 2 TO zrow
  1672.   STORE 3 TO zcol
  1673.   STORE 4 TO zoppcol
  1674.   *
  1675.   DO WHILE .NOT. choice $ mvalopts
  1676.     * ' While value of 'choice' is not valid
  1677.     STORE 'Highlight' TO mmess1
  1678.     @ 22,14 GET mmess1
  1679.     @ 22,24 SAY 'and <Enter> or Press Menu Letter to Select'
  1680.     CLEAR GETS
  1681.     * ' Initialize counter to array location of default entry
  1682.     STORE msize TO mcount
  1683.     * ' Go to first available menu option in array
  1684.     DO WHILE (&zmenu(mcount,zrow) = 0 .AND. &zmenu(mcount,zcol) = 0) ;
  1685.       .AND. mcount > 1
  1686.       STORE mcount - 1 TO mcount
  1687.     ENDDO
  1688.     * ' Action loop, highlight current menu option and move to next option
  1689.     DO WHILE .t.
  1690.       STORE 0 TO mkey
  1691.       IF TYPE('&zmenu(mcount,ztitle)') <> 'L'
  1692.         * ' If current location defined member of array
  1693.         STORE SUBSTR(&zmenu(mcount,ztitle),1,mbarlen) TO mtitle
  1694.         @ &zmenu(mcount,zrow),&zmenu(mcount,zcol) GET mtitle
  1695.         @ &zmenu(mcount,zrow),&zmenu(mcount,zcol) SAY ''
  1696.         CLEAR GETS
  1697.         DO WHILE mkey = 0
  1698.         * ' Set inkey parameter to 10 to minimize delays
  1699.         * ' on single processor systems (Xenix, PCMOS, etc)
  1700.           STORE MAX(INKEY(10),0) TO mkey
  1701.         ENDDO
  1702.         @ &zmenu(mcount,zrow),&zmenu(mcount,zcol) SAY mtitle
  1703.       ENDIF
  1704.       DO CASE
  1705.         CASE UPPER(CHR(mkey)) $ mvalopts
  1706.           * ' If letter in valid option list was entered, use that
  1707.           STORE UPPER(CHR(mkey)) TO choice
  1708.           IF .NOT. choice $ '.'
  1709.             * ' Highlight choice from menu file entry
  1710.             STORE 1 TO mcount
  1711.             DO WHILE mcount <= msize .AND. (choice <> ;
  1712.               SUBSTR(&zmenu(mcount,ztitle),1,1) .OR. (choice = ;
  1713.               SUBSTR(&zmenu(mcount,ztitle),1,1) .AND. ;
  1714.               (&zmenu(mcount,zrow) = 0 .AND. &zmenu(mcount,zcol) = 0)))
  1715.               STORE mcount + 1 TO mcount
  1716.             ENDDO
  1717.             STORE SUBSTR(&zmenu(mcount,ztitle),1,mbarlen) TO mtitle
  1718.           ENDIF
  1719.           EXIT
  1720.         CASE mkey = 4 .OR. mkey = 19
  1721.           * ' If left or right arrow, move to opposite column
  1722.           IF mcol2 <> 0
  1723.             * ' if there is a 2nd column
  1724.             STORE IIF(&zmenu(mcount,zoppcol) = 0, ;
  1725.             mcount,&zmenu(mcount,zoppcol)) TO mcount
  1726.           ENDIF
  1727.         CASE mkey = 5
  1728.           * ' Up arrow key
  1729.           STORE IIF(mcount > 1,mcount - 1,msize) TO mcount
  1730.           DO WHILE (&zmenu(mcount,zrow) = 0 .AND. &zmenu(mcount,zcol) = 0) ;
  1731.             .AND. mcount > 1
  1732.             * ' Go to next available menu option in array
  1733.             STORE IIF(mcount > 1,mcount - 1,msize) TO mcount
  1734.           ENDDO
  1735.         CASE mkey = 24
  1736.           * ' Down arrow key
  1737.           STORE IIF(mcount < msize,mcount + 1,1) TO mcount
  1738.           DO WHILE (&zmenu(mcount,zrow) = 0 .AND. &zmenu(mcount,zcol) = 0) ;
  1739.             .AND. mcount > 1
  1740.             * ' Go to next available menu option in array
  1741.             STORE IIF(mcount < msize,mcount + 1,1) TO mcount
  1742.           ENDDO
  1743.         CASE mkey = 13
  1744.           * ' Enter key selects hilighted option
  1745.           IF SUBSTR(mtitle,1,1) $ mvalopts
  1746.             STORE SUBSTR(mtitle,1,1) TO choice
  1747.             STORE mcount TO &zmenu(2,5)
  1748.             EXIT
  1749.           ENDIF
  1750.         OTHERWISE
  1751.           * ' Invalid keystroke/option
  1752.           ?? CHR(7)
  1753.       ENDCASE
  1754.     ENDDO && WHILE .t.
  1755.     CLEAR GETS
  1756.   ENDDO && WHILE .NOT. choice $ mvalopts
  1757.   IF .NOT. choice $ '.'
  1758.     * ' Highlight choice on menu
  1759.     @ &zmenu(mcount,zrow),&zmenu(mcount,zcol) GET mtitle
  1760.     @ &zmenu(mcount,zrow),&zmenu(mcount,zcol) SAY ''
  1761.     CLEAR GETS
  1762.   ENDIF
  1763.   RELEASE ALL LIKE z*
  1764.   SET ESCAPE ON
  1765. RETURN
  1766. * ' EOP - P0SELECT
  1767. * '
  1768. PROCEDURE p0memclr
  1769.   * ' Dummy stub; used in Clipper - compiled, Alink - linked Payroll.
  1770. RETURN
  1771. *
  1772. *
  1773. *
  1774. * ' Procedure Name:          p0txarry
  1775. * ' Purpose or Function:     Builds arrays for storing tax rates and accumu-
  1776. * '                          lated tax liabilities by tax code
  1777. * '         
  1778. * ' Parameters Passed        mtaxrate - tax  rate from form header
  1779. * '                          mselarea - work area selected upon entry into proc
  1780. * ' Variables Passed:     
  1781. * '                       
  1782. * ' Example:              Called as DO p0txarry WITH mtaxrate, 'c'
  1783. *
  1784. PROCEDURE p0txarry
  1785. PARAMETERS mtaxrate, mselarea
  1786. IF m0lntax
  1787.   PUBLIC a0taxrate(26), a0taxable(26), a0taxsubt(26), a0taxacct(26)
  1788.   SELECT i
  1789.   USE &m0sysvatf
  1790.   STORE 1 TO mcode
  1791.   DO WHILE .NOT. EOF()
  1792.     * ' tax rate is -1 for undefined codes
  1793.     STORE IIF(i->taxcode <> ' ', i->taxrate, -1) TO a0taxrate(mcode)
  1794.     STORE i->acctout TO a0taxacct(mcode)
  1795.     STORE 0.00 TO a0taxable(mcode), a0taxsubt(mcode)
  1796.     SKIP
  1797.     STORE mcode + 1 TO mcode
  1798.   ENDDO
  1799.   USE
  1800.   SELECT &mselarea
  1801. ELSE
  1802.   PUBLIC a0taxrate(2), a0taxable(2), a0taxsubt(2)
  1803.   STORE mtaxrate TO a0taxrate(1)
  1804.   STORE 0.00 TO a0taxrate(2), a0taxable(1), a0taxable(2), a0taxsubt(1), ;
  1805.   a0taxsubt(2)
  1806. ENDIF
  1807. RETURN
  1808. * ' EOP p0txarray
  1809. *
  1810. * ' Procedure Name:          p0frmclc
  1811. * ' Purpose or Function:     Calculates taxable and tax totals for each tax
  1812. * '                          type on an invoice, purchase order, or sales order
  1813. * ' Parameters Passed        mcond - condition under which processing of line
  1814. * '                          items continues
  1815. * '                          mformsub - sum of extended prices of lines on 
  1816. * '                          form
  1817. * '                          mformtax - total tax on form
  1818. * '                          mformtotl - total of form
  1819. * ' Variables Passed:     
  1820. * ' Environment Passed:      transaction file selected and record pointer 
  1821. * '                          positioned on first record of form
  1822. * ' Variables Returned: 
  1823. * '                       
  1824. * ' Example:            Called as DO p0frmclc WITH 'custno = mcust .AND.
  1825. * '                     sono = msono .AND. .NOT. EOF()', mordsub, mtax, mordamt
  1826. *
  1827. *
  1828. PROCEDURE p0frmclc
  1829. PARAMETER mcond, mformsub, mformtax, mformtotl
  1830. IF .NOT. EOF()
  1831.   * ' Condition essentially protects against data errors.  Should never be true
  1832.   STORE RECNO() TO mrec
  1833.   DO WHILE &mcond
  1834.     * ' Determine array subscript of this tran record's tax code
  1835.     DO CASE
  1836.       CASE .NOT. m0lntax
  1837.         STORE IIF(taxable = 'Y', 1, 2) TO mcode 
  1838.       CASE m0lntax .AND. ASC(UPPER(taxcode)) > 64 .AND. ASC(UPPER(taxcode)) < 91
  1839.         * ' Valid tax code which maps to a valid array subscript
  1840.         STORE ASC(UPPER(taxcode)) - 64 TO mcode
  1841.       OTHERWISE
  1842.         * ' Invalid tax codes are accumulated in rate 'Z'
  1843.         STORE 26 TO mcode
  1844.     ENDCASE
  1845.     * ' Calculate subtotal for each tax code in a0taxable(mcode)
  1846.     STORE a0taxable(mcode) + extprice TO a0taxable(mcode)
  1847.     * ' Update taxable and tax for current code plus form total tax and total
  1848.     STORE a0taxsubt(mcode) TO moldtax
  1849.     * ' Use taxrate from tran record for calculation of tax on current code
  1850.     * ' The stored rate may no longer be the same as the rate in the table.
  1851.     STORE .01 * INT(taxrate * a0taxable(mcode) + ;
  1852.     IIF(taxrate * a0taxable(mcode) < 0, -.5, .5)) TO a0taxsubt(mcode)
  1853.     * ' Calculate the totals for current form
  1854.     STORE mformsub + extprice TO mformsub
  1855.     STORE mformtax - moldtax + a0taxsubt(mcode) TO mformtax
  1856.     STORE mformsub + mformtax TO mformtotl
  1857.     SKIP
  1858.   ENDDO
  1859.   GOTO mrec
  1860. ENDIF
  1861. RETURN
  1862. * ' EOP p0frmclc
  1863. *
  1864. * ' Procedure Name:          p0linclc
  1865. * ' Purpose or Function:     Calculates taxable and tax totals for each tax
  1866. * '                          type on an invoice, purchase order, or sales order
  1867. * '                          when line is added or edited
  1868. * '         
  1869. * ' Parameters Passed        maction - 'A': item being added to form
  1870. * '                            'D': item being deleted from form
  1871. * '                            'E':  item being edited
  1872. * '                          form, rather than being edited
  1873. * '                          mformsub - sum of extended prices of lines on 
  1874. * '                          form
  1875. * '                          mformtax - total tax on form
  1876. * '                          mformtotl - total of form
  1877. * '                          mextprice - extprice of new line item or new
  1878. * '                          extended price of line item after edit
  1879. * ' Variables Passed:     
  1880. * ' Environment Passed:      if editing or deleting, transaction file 
  1881. * '                          selected and record pointer positioned on record
  1882. * '                          being edited/deleted; if adding, memvar copy
  1883. * '                          of detail record in memory
  1884. * '                       
  1885. * ' Example:              Called as DO p0linclc WITH 'A', iordsub, itax,
  1886. * '                       iordamt, 'b', iextprice, itaxcode
  1887. *
  1888. PROCEDURE p0linclc
  1889. PARAMETERS maction, mformsub, mformtax, mformtotl, mextprice, mtaxcode
  1890. * ' Determine array subscript of this line's tax code and of its previous
  1891. * ' tax code, if its being edited
  1892. DO CASE
  1893.   CASE .NOT. m0lntax
  1894.     STORE IIF(mtaxcode = 'Y', 1, 2) TO mcode
  1895.     STORE mcode TO mocode
  1896.     IF maction = 'E'
  1897.       STORE IIF(taxable = 'Y', 1, 2) TO mocode 
  1898.     ENDIF
  1899.   CASE ASC(UPPER(mtaxcode)) > 64 .AND. ASC(UPPER(mtaxcode)) < 91
  1900.     STORE ASC(UPPER(mtaxcode)) - 64 TO mcode
  1901.     STORE mcode TO mocode
  1902.     IF maction = 'E' .AND. ASC(UPPER(taxcode)) > 64 .AND. ASC(UPPER(taxcode)) < 91
  1903.       * ' Protection against invalid stored code
  1904.       STORE ASC(UPPER(taxcode)) - 64 TO mocode
  1905.     ENDIF
  1906.   OTHERWISE
  1907.     STORE 26 TO mcode, mocode
  1908.     IF maction = 'E' .AND. ASC(UPPER(taxcode)) > 64 .AND. ASC(UPPER(taxcode)) < 91
  1909.       * ' Protection against invalid stored code
  1910.       STORE ASC(UPPER(taxcode)) - 64 TO mocode
  1911.     ENDIF
  1912. ENDCASE
  1913. *
  1914. IF maction = 'E' && editing line on current form
  1915.   STORE mformsub - extprice TO mformsub
  1916.   * ' Calculate subtotal and tax for taxcode before the edit (backing out line)
  1917.   STORE a0taxable(mocode) - extprice TO a0taxable(mocode)
  1918.   * ' Save the previous tax for this taxcode for difference calculation below
  1919.   STORE a0taxsubt(mocode) TO moldtax1
  1920.   * ' Calculate the new tax on the taxable after the original line is backed out
  1921.   * ' Use stored rate when editing a line
  1922.   STORE .01 * INT(taxrate * a0taxable(mocode) + ;
  1923.   IIF(taxrate * a0taxable(mocode) < 0, -.5, .5)) TO a0taxsubt(mocode)
  1924. ENDIF
  1925. *
  1926. * ' Calculate new subtotal and tax for taxcode after the add/edit
  1927. STORE a0taxable(mcode) + mextprice TO a0taxable(mcode)
  1928. * ' Save the previous tax for this taxcode for difference calculation below
  1929. STORE a0taxsubt(mcode) TO moldtax2
  1930. IF maction $ 'AD'
  1931.   STORE moldtax2 TO moldtax1
  1932. ENDIF
  1933. * ' Calculate the new tax on the new taxable for this code
  1934. IF maction = 'A' .OR. mcode <> mocode
  1935.   STORE .01 * INT(a0taxrate(mcode) * a0taxable(mcode) + ;
  1936.   IIF(a0taxrate(mcode) * a0taxable(mcode) < 0, -.5, .5)) TO a0taxsubt(mcode)
  1937. ELSE
  1938.   * ' Use stored tax rate if editing line
  1939.   STORE .01 * INT(taxrate * a0taxable(mcode) + ;
  1940.   IIF(taxrate * a0taxable(mcode) < 0, -.5, .5)) TO a0taxsubt(mcode)
  1941. ENDIF
  1942. *
  1943. * ' Calculate new subtotal for all taxes and total for form
  1944. * ' If tax code has not changed or this is a new line, add difference between
  1945. * ' tax for code after add/edit and tax for code before add/edit.  if tax code
  1946. * ' has changed add difference in tax subtotals for old and new tax codes 
  1947. IF mocode = mcode
  1948.   STORE mformtax + a0taxsubt(mcode) - moldtax1 TO mformtax
  1949. ELSE
  1950.   STORE mformtax + (a0taxsubt(mcode) - moldtax2) + (a0taxsubt(mocode) - ;
  1951.   moldtax1) TO mformtax
  1952. ENDIF
  1953. STORE mformsub + mextprice TO mformsub
  1954. STORE mformsub + mformtax TO mformtotl
  1955. RETURN
  1956. * ' EOP p0linclc
  1957. *
  1958. *
  1959. * ' Procedure Name:          p0psttax
  1960. * ' Purpose or Function:     Posts tax to link file for line item transactions
  1961. * '         
  1962. * ' Parameters Passed        mlnkarea - work area in which xxGLLK is open
  1963. * '                          mliabt - sales tax liability account, non-VAT
  1964. * ' Variables Passed:        a0taxsubt - Array of tax totals by taxcode
  1965. * '                          26 elements for VAT, 2 for non-VAT
  1966. *
  1967. PROCEDURE p0psttax
  1968. PARAMETERS mlnkarea, mliabt
  1969. STORE 1 TO mcnt
  1970. DO WHILE mcnt <= IIF(m0lntax, 26, 1)
  1971.   IF a0taxsubt(mcnt) <> 0
  1972.     SELECT &mlnkarea
  1973.     SEEK IIF(m0lntax, a0taxacct(mcnt), mliabt)
  1974.     IF EOF()
  1975.       APPEND BLANK
  1976.       REPLACE account WITH IIF(m0lntax, a0taxacct(mcnt), mliabt)
  1977.     ENDIF
  1978.     REPLACE amount WITH amount - a0taxsubt(mcnt)
  1979.   ENDIF
  1980.   STORE mcnt + 1 TO mcnt
  1981. ENDDO
  1982. RETURN
  1983. * ' EOP p0psttax 
  1984. *
  1985. * ' Procedure Name:       p0prntax
  1986. * ' Purpose or Function:  Prints VAT table
  1987. * ' Parameters Passed:    mline: line to start printing table on
  1988. * '                       mcol: column to start printing table on
  1989. * '                       mvars: string of two variables separated by '|'
  1990. *
  1991. * '  Example:  Called as DO p0prntax WITH mline, micol1, 'msub|mtax'
  1992. *
  1993. PROCEDURE p0prntax
  1994. PARAMETERS mline, mcol, mvars
  1995. STORE 1 TO mcnt
  1996. * ' Set up and print VAT summary table
  1997. STORE SUBSTR(mvars, 1, AT('|', mvars) - 1) TO mvatsub
  1998. STORE SUBSTR(mvars, AT('|', mvars) + 1, LEN(TRIM(mvars))) TO mvatamt
  1999. * ' Reinitializes variables passed in string
  2000. STORE 0 TO &mvatsub
  2001. STORE 0 TO &mvatamt
  2002. @ mline,mcol + 1 SAY 'VAT Code  Description   % Rate  ' + ;
  2003. '    Subtotal      Total Tax'
  2004. @ mline + 1,mcol + 1 SAY '--------  ------------  ------  ' + ;
  2005. '------------   ------------'
  2006. STORE mline + 2 TO mline
  2007. * ' Print body of VAT summary table
  2008. DO WHILE mcnt <= 26
  2009.   IF a0taxsubt(mcnt) <> 0 .OR. a0taxable(mcnt) <> 0 
  2010.     LOCATE FOR i->taxcode = CHR(mcnt + 64)
  2011.     @ mline,mcol + 4 SAY i->taxcode
  2012.     @ mline,mcol + 11 SAY i->taxdesc
  2013.     @ mline,mcol + 26 SAY i->taxrate PICTURE '99.99'
  2014.     @ mline,mcol + 33 SAY a0taxable(mcnt) PICTURE '99999999.99'
  2015.     @ mline,mcol + 48 SAY a0taxsubt(mcnt) PICTURE '99999999.99'
  2016.     * ' Accumulates running total of summary variables
  2017.     STORE &mvatsub + a0taxable(mcnt) TO &mvatsub
  2018.     STORE &mvatamt + a0taxsubt(mcnt) TO &mvatamt
  2019.     STORE mline + 1 TO mline
  2020.   ENDIF
  2021.   STORE mcnt + 1 TO mcnt
  2022. ENDDO
  2023. USE
  2024. * ' Print totals of VAT summary table
  2025. @ mline,mcol + 33 SAY '------------   ------------'
  2026. @ mline + 1,mcol + 1 SAY 'Totals'
  2027. @ mline + 1,mcol + 33 SAY &mvatsub PICTURE '99999999.99'
  2028. @ mline + 1,mcol + 48 SAY &mvatamt PICTURE '99999999.99'
  2029. * ' EOP p0prntax
  2030. *
  2031. * ' Procedure Name:       f0numtax
  2032. * ' Purpose or Function:  calculates how many codes in tax table
  2033. * '                       have non-zero entries
  2034. * ' Parameters Passed:    
  2035. * '
  2036. * '  Returns        mcount = for mchoice = 1, # of codes with non-zero entries
  2037. * '  Example:  Called as STORE f0numtax TO mrecs
  2038. *
  2039. PROCEDURE f0numtax
  2040. STORE 0 TO mcount
  2041. STORE 1 TO mcnt
  2042. DO WHILE mcnt <= 26
  2043.   IF a0taxsubt(mcnt) <> 0 .OR. a0taxable(mcnt) <> 0
  2044.     STORE mcount + 1 TO mcount
  2045.   ENDIF
  2046.   STORE mcnt + 1 TO mcnt
  2047. ENDDO
  2048. RETURN mcount
  2049. * ' EOP f0numtax
  2050. *
  2051. * ' Procedure Name:       f0taxval
  2052. * ' Purpose or Function:  returns single value from tax array
  2053. * ' Parameters Passed:    mval: value you want to retrieve, either 'rate',
  2054. * '                       'acct', 'taxable', or 'subtax' 
  2055. * '                       mrow: row of the array you want a value for
  2056. * '  Returns        mvalue = value of selected array entry
  2057. * '  Example:  Called as STORE f0taxval('subtax', 4) TO mtaxd
  2058. * '
  2059. PROCEDURE f0taxval
  2060. PARAMETERS mval, mrow
  2061. IF mrow < 1 .OR. mrow > 26
  2062.   * ' Protection against invalid taxcodes
  2063.   STORE 26 TO mrow
  2064. ENDIF
  2065. DO CASE
  2066.   CASE mval = 'rate'
  2067.     STORE a0taxrate(mrow) TO mvalue
  2068.   CASE mval = 'acct'
  2069.     STORE a0taxacct(mrow) TO mvalue
  2070.   CASE mval = 'taxable'
  2071.     STORE a0taxable(mrow) TO mvalue
  2072.   CASE mval = 'subtax'
  2073.     STORE a0taxsubt(mrow) TO mvalue
  2074. ENDCASE
  2075. RETURN mvalue
  2076. * ' EOP f0taxval
  2077. *
  2078. * ' Procedure Name:          f0extlin
  2079. * ' Purpose or Function:     Calculates extended cost or price for line item
  2080. * '         
  2081. * ' Parameters Passed        mqty - quantity on current line
  2082. * '                          mprice - price or cost of item on current line
  2083. * '                          mdisc - discount rate for current line
  2084. * ' Variables Passed:     
  2085. * ' Environment Passed:      
  2086. * ' Returns:                 Calculated extended price or cost
  2087. * '                       
  2088. * ' Example:      STORE f0extline(iqtyshp, iprice, idisc) TO iextprice
  2089. *
  2090. *
  2091. PROCEDURE f0extlin
  2092. PARAMETERS mqty, mprice, mdisc
  2093. IF mqty * mprice * (100 - mdisc) < 0
  2094.   STORE .01 * INT(mqty * mprice * (100 - mdisc) - .5) TO mextprice
  2095. ELSE
  2096.   STORE .01 * INT(mqty * mprice * (100 - mdisc) + .5) TO mextprice
  2097. ENDIF
  2098. RETURN mextprice
  2099. * ' EOP f0extline
  2100. *
  2101. * ' Procedure Name:       P0GRDLIN
  2102. * ' Purpose or Function:  Displays Single Line of Option Grid
  2103. * ' Parameters Passed:    mline = current line number
  2104. * '                       moption = first column option
  2105. * '                       mchoices = Choice list
  2106. * '                       mgetvars = Variables to GET choice into
  2107. * '                       mgetpict = picture clause
  2108. *
  2109. * '  Example:  Called as DO p0grdline WITH mline, 'Beginning Account', 
  2110. * '             '(blank for all)', 'mbaccnt', '#####-###'
  2111. *
  2112. PROCEDURE p0grdlin
  2113. PARAMETERS mline, moption, mchoices, mgetvars, mgetpict
  2114. @ mline,4 SAY moption
  2115. @ mline,24 SAY mchoices
  2116. IF .NOT. '|' $ mgetpict
  2117.   STORE mgetpict TO mgetpict1, mgetpict2
  2118. ELSE
  2119.   STORE SUBSTR(mgetpict, 1, AT('|', mgetpict) - 1) TO mgetpict1
  2120.   STORE SUBSTR(mgetpict, AT('|', mgetpict) + 1, LEN(TRIM(mgetpict))) ;
  2121.   TO mgetpict2
  2122. ENDIF
  2123. IF .NOT. '|' $ mgetvars
  2124.   @ mline, 61 GET &mgetvars PICTURE '&mgetpict1'
  2125. ELSE
  2126.   STORE SUBSTR(mgetvars, 1, AT('|', mgetvars) - 1) TO mgetvar1
  2127.   STORE SUBSTR(mgetvars, AT('|', mgetvars) + 1, LEN(TRIM(mgetvars))) TO mgetvar2
  2128.   @ mline,60 GET &mgetvar1 PICTURE '&mgetpict1'
  2129.   @ mline, COL() + 1 GET &mgetvar2 PICTURE '&mgetpict2'
  2130. ENDIF
  2131. STORE mline + 2 TO mline
  2132. RETURN
  2133. * ' EOP p0grdlin
  2134. *
  2135. * ' Procedure Name:       P0REGET
  2136. * ' Purpose or Function:  Allows data entry into single GET; typically used
  2137. * '                       after field validation fails
  2138. * ' Parameters Passed:    mbellon = logical, beep
  2139. * '                       mmsgrow = Row to display error message
  2140. * '                       mmsgcol = column to start message on
  2141. * '                       mgetrow = row to reGET variable
  2142. * '                       mgetcol = column to reGET variable
  2143. * '                       mgetvar = variable to GET
  2144. * '                       mgetpict = picture clause
  2145. * '                       merrmsg = error message
  2146. *
  2147. * '  Example:  Called as DO p0reget WITH .t., 23, 0, mline, 61, mrange, '!',
  2148. * '             'Must be B, S, or A.  Please reenter...'
  2149. *
  2150. PROCEDURE p0reget
  2151. PARAMETERS mbellon, mmsgrow, mmsgcol, mgetrow, mgetcol, mgetvar, mgetpict, ;
  2152. merrmsg
  2153. IF mbellon
  2154.   ?? CHR(7)
  2155. ENDIF
  2156. @ mmsgrow, mmsgcol
  2157. @ mmsgrow, mmsgcol SAY merrmsg
  2158. @ mgetrow, mgetcol GET mgetvar PICTURE '&mgetpict'
  2159. READ
  2160. @ mmsgrow, mmsgcol SAY SPACE(LEN(merrmsg))
  2161. RETURN
  2162. * ' EOP p0reget
  2163. *
  2164. * ' Procedure Name:          f0wkdays
  2165. * ' Purpose or Function:     Calculates number of working days in a month
  2166. * '                          up to and including the passed date
  2167. * '         
  2168. * ' Parameters Passed:       mlast - date through which to calculate number
  2169. * '                          of working days        
  2170. * '                          
  2171. * ' Returns:                 Calculated number of working days through mlast
  2172. * '                       
  2173. * ' Example:      STORE f0wkdays(m0date) TO mwkday1
  2174. * '
  2175. PROCEDURE f0wkdays
  2176. PARAMETERS mlast
  2177. PRIVATE mmonth, myear, mdays, mfirst
  2178. STORE MONTH(mlast) TO mmonth
  2179. STORE YEAR(mlast) TO myear
  2180. STORE DAY(mlast) TO mdays
  2181. * ' Determine day of week number
  2182. STORE DOW(CTOD(LTRIM(STR(mmonth)) + '/01/' + LTRIM(STR(myear)))) TO mfirst
  2183. * ' Determine number of working days to mlast
  2184. STORE mdays - (INT(mdays/7) * 2) - IIF(mfirst = 1 .OR. mfirst = 7, ;
  2185. 1, 0) TO mwkdays
  2186. DO CASE
  2187.   * ' February and day is greater than day on which Wash b-day is observed
  2188.   CASE mmonth = 1
  2189.     STORE mwkdays - 1 TO mwkdays
  2190.   CASE mmonth = 2 .AND. mdays > IIF(mfirst > 2, 24 - mfirst, 17 - mfirst)
  2191.     STORE mwkdays - 1 TO mwkdays
  2192.   CASE mmonth = 5 .AND. mdays > IIF(mfirst > 2, 31 - mfirst, 24 - mfirst)
  2193.     STORE mwkdays - 1 TO mwkdays
  2194.   CASE mmonth = 7 .AND. mdays >= 4 
  2195.     STORE mwkdays - 1 TO mwkdays
  2196.   CASE mmonth = 9 .AND. mdays > IIF(mfirst > 2, 10 - mfirst, 3 - mfirst)
  2197.     STORE mwkdays - 1 TO mwkdays
  2198.   CASE mmonth = 11 .AND. mdays > 27 - mfirst
  2199.     STORE mwkdays - 1 TO mwkdays
  2200.   CASE mmonth = 12 .AND. mdays > 25
  2201.     STORE mwkdays - 1 TO mwkdays
  2202. ENDCASE
  2203. RETURN mwkdays
  2204. * EOF f0wkdays
  2205. *
  2206. * ' Procedure Name:          f0wkmnth
  2207. * ' Purpose or Function:     Calculates number of working days in a month
  2208. * '         
  2209. * ' Parameters Passed:       mmonth - number of the month to calculate working
  2210. * '                          days for, myear - last two digits of year to 
  2211. * '                          calculate working days for         
  2212. * '                          
  2213. * ' Returns:                 Number of working days in month 
  2214. * '                          represented by mmonth, myear
  2215. * '                       
  2216. * ' Example:      STORE f0wkmnth(4,90) TO mwkday1
  2217. * '
  2218. * Function to return number of working days in the month
  2219. * ' Example:      STORE f0wkmth(MONTH(m0date), YEAR(m0date)) TO mwkday2
  2220. PROCEDURE f0wkmnth
  2221. PARAMETERS mmonth, myear
  2222. * ' Build last day of the month
  2223. STORE CTOD(LTRIM(STR(mmonth + 1)) + '/01/' + LTRIM(STR(myear))) -1 TO mlast
  2224. * ' Call f0wkdays function to calculate working days through last day
  2225. STORE f0wkdays(mlast) TO mwkdays
  2226. RETURN mwkdays
  2227. * ' EOF f0wkmnth
  2228. ** ' $Revision:   1.60  $
  2229. * ' $Date:   21 May 1990 12:37:22  $
  2230. **********************
  2231. ** ' SYSMULT.PRG  ' **
  2232. ** ' 2235 Lines   ' **
  2233. **********************
  2234.