1 SUB M11SLC (PRT.CODE%) & 2 !******************************************************************** & ! & ! & ! M11SLC & ! & ! Sets up the system for printing & ! & ! & !******************************************************************** & ! 3 ! Program : M11SLC & ! Version : 00 26-FEB-82 & ! Programmer : Jean Fullerton & ! Releaser : & ! & !--------------------------------------------------------------------- 11 ! & ! & ! C O P Y R I G H T & ! & ! & !--------------------------------------------------------------------- 20 ! ! Modification History ! ! rev date by ! 1.1 4-May-84 Mike Brown ! Modified this and related modules to use RFA access to ! mailing list files. This improves performance compared ! to access by primary ID. MAPRFA, MAPSRI, lines 5545, ! 5547, 5561 - 5566, 5600. ! ! 1.1 17-May-84 Mike Brown ! Implemented flag to supress/enable printing of break labels. ! Lines 5840, 5860, COMVAR. ! ! 1.1 21-Sep-84 Mike Brown ! Modified lines 5550 - 5630 to allow multiple sort keys. ! !--------------------------------------------------------------------- 100 ! & ! & ! & ! Description: & ! & ! This routine is used to set up the printing of addresses on labels & ! or on a listing. SMAIL then calls either M11PRT or M11LB1/M11LB2. & ! & ! future enhancements: allow multiple answers to the sort question & ! (for example, "S,A" means sort by State, & ! then do a subsort by Alternate ID). & ! & !--------------------------------------------------------------------- 200 ! & ! & ! Interfaces: & ! & ! Arguments: & ! PRT.CODE% = 0% no sort & ! 1% finished selecting, need to sort & ! (set by M11SLC) & ! & !--------------------------------------------------------------------- 300 ! & ! & ! Input / Output: & ! & ! & ! Channel Filename Map name Status at entry/exit & ! ------- --------- -------- -------------------- & ! & ! CH.SORT% closed / closed & ! & !--------------------------------------------------------------------- 400 ! & ! & ! Variable and Array Definitions: & ! & ! & ! ERL Line in which error occurred & ! & ! ERR Set to error number after error & ! & !--------------------------------------------------------------------- 600 !-------------------------------------------------------------------- & ! & ! & ! COMMON Statements & ! & ! & !--------------------------------------------------------------------- 650 !-------------------------------------------------------------------- & ! & ! & ! MAP Statements & ! & ! & !--------------------------------------------------------------------- 700 ! & ! & ! Subprograms: & ! & ! & ! & !-------------------------------------------------------------------- & ! 800 ! Subroutines: & ! & !-------------------------------------------------------------------- & ! & ! Functions: & ! & !-------------------------------------------------------------------- & 1000 !******************************************************************** & ! & ! & ! S T A R T P R O G R A M L O G I C & ! & ! & !******************************************************************** & 1010 ON ERROR GOTO 19000 & \ ERR.CALLNAM$ = ERR.PROGNAM$ & \ ERR.PROGNAM$ = "M11SLC VER:00" & \ ERR.SUBNAM$ = "" & \ ERR.MSG$ = "Unexpected fatal error" & \ PLEASE.WAIT$ = "The next address is in use by another user. Please wait." & ! Set standard error trap. Set up common for error reporting. & & 1040 AND% = 1% & \ OR% = 2% & & \ ALL.SP% = 2% & & \ CALL.SORT% = 1% & \ PRT.CODE% = 0% & & ! Initialize constants. & 5500 !-------------------------------------------------------------------- & ! & ! Select Addresses to Sort & ! & !-------------------------------------------------------------------- & 5520 GO TO 9000 IF M11.SORT.CODE$ = "P" & OR M11.SORT.CODE$ = "A" & ! Skip all sorting selection if none requested. & 5530 IF M11.PRESORT% THEN & ZIP.ERR% = 0% & \ STATE.ERR% = 0% & \ CITY.ERR% = 0% & \ VALID% = 0% & \ INVALID% = 0% & \ LONGEST.ZIP% = 5% & \ ST$="/AK/AL/AR/AZ/CA/CO/CT/DC/DE/FL/GA/GU/HI/IA/ID/IL/IN/KS" & +"/KY/LA/MA/MD/ME/MI/MN/MO/MS/MT/NC/ND/NE/NH/NJ/NM/NV/NY" & +"/OH/OK/OR/PA/PR/RI/SC/SD/TN/TX/UT/VA/VI/VT/WA/WI/WV/WY/" & \ M11.OUTPUT.FORM$ = "L" & \ GO SUB 13700 & ! Set up PRESORT variables- error counters, zip length, label format. & ! Then go check the first selected address. & 5540 DIM TRMNO.STR%(30%) & \ CHANGE SYS (CHR$(6%)+CHR$(26%)+CHR$(0%)+CHR$(0%)) TO TRMNO.STR% & \ TRMNO% = TRMNO.STR%(4%) - ((TRMNO.STR%(4%)/10%)*10%) & ! Now we've got the last digit of the keyboard number. & 5545 M11.SORT.FILE$ = EDIT$ (PRM.LOC.WORK.FILES$, ALL.SP%) & + NUM1$ (TRMNO%) + NUM1$ (TIME(0%)) + ".TMP" & \ SLEEP 2% & \ M11.SORTED.FILE$ = EDIT$ (PRM.LOC.WORK.FILES$, ALL.SP%) & + NUM1$ (TRMNO%) + NUM1$ (TIME(0%)) + ".TMP" & & ! Define sort file names. & 5547 OPEN M11.SORT.FILE$ FOR OUTPUT AS FILE #CH.SORT% & ,ORGANIZATION SEQUENTIAL VARIABLE & ,ACCESS WRITE & ,ALLOW NONE & ,MAP MAPSRI & \ RECORD_RFA = FIRST_RECORD_RFA & \ GO TO 5550 & ! Open file to contain data to sort. & ! The first qualifying record's RFA was determined by M11SET & 5549 M11.MSG$ = "Trouble opening sort work files ... check system parameter file" & \ GOSUB 14900 & \ M11.EXIT.STATUS% = TRUE% & \ GO TO 9000 & ! Couldn't open the sort work files. Tell user what to do and just & ! get out. 5550 M11.MSG$ = 'Selecting addresses to sort ... please wait' & \ GO SUB 14800 & \ CLOSE #CH.KB% & \ OPEN "KB:" AS FILE #CH.KB% & \ C = CTRLC & ! Open keyboard (not in echo control mode) to enable ^C trapping & 5555 M11.SORT.FIELD.SIZE% = 0% ! Initialize size of sort field. FOR I% = 1% TO M11.SORT.OPTIONS% SORT.CODE% = POS ("PACN???TSZ123456",EDIT$(M11.SORT.CODE$(I%),128%),1%) SORT.CODE% = 5% IF M11.SORT.CODE$ = "L1" SORT.CODE% = 6% IF M11.SORT.CODE$ = "L2" SORT.CODE% = 7% IF M11.SORT.CODE$ = "L3" FIELD.SIZE% = HDR.FIELD.LEN%(SORT.CODE%) FIELD.SIZE% = 10% IF M11.PRESORT% M11.SORT.FIELD.SIZE% = M11.SORT.FIELD.SIZE% + FIELD.SIZE% NEXT I% SIZE% = 6% + M11.SORT.FIELD.SIZE% ! Determine total size of the sort field. NAMES% = 0% 5558 FOR I% = 1% TO M11.SORT.OPTIONS% ! For each record selected, loop through the sort options ! and set up the string to be sorted. SORT.CODE$ = SEG$ (EDIT$ (M11.SORT.CODE$(I%), ALL.SP%), 1%, 1%) & \ SORT.CDE% = 1% IF SORT.CODE$ = "N" & OR SORT.CODE$ = "L" & OR SORT.CODE$ = "T" & \ SORT.CDE% = 2% IF SORT.CODE$ = "S" & \ SORT.CDE% = 3% IF SORT.CODE$ = "Z" & \ SORT.CDE% = 4% IF SORT.CODE$ = "C" & \ SORT.CDE% = 5% IF SORT.CODE$ = "1" & OR SORT.CODE$ = "2" & OR SORT.CODE$ = "3" & OR SORT.CODE$ = "4" & OR SORT.CODE$ = "5" & OR SORT.CODE$ = "6" & \ SORT.CDE% = 6% IF SORT.CODE$ = "P" & \ NUM% = POS ("123", SEG$ (M11.SORT.CODE$(I%), 2%, 2%), 1%) & \ NUM% = 4% IF SORT.CODE$ = "T" & & \ IF SORT.CDE% = 5% THEN & CAT% = POS ("123456", SORT.CODE$, 1%) & \ CAT.TYPE$ = "AY" IF HDR.CAT.TYPE$(CAT%) = "A" & OR HDR.CAT.TYPE$(CAT%) = "Y" & OR HDR.CAT.TYPE$(CAT%) = "C" & \ CAT.TYPE$ = "N" IF HDR.CAT.TYPE$(CAT%) = "N" & \ CAT.TYPE$ = "D" IF HDR.CAT.TYPE$(CAT%) = "D" & ! Initialize and notify user that selection is being done. & ! Determine the type of sort (SORT.CDE%), and the number of the & ! field for the address (N,L1,L2,L3,T) and categories (1,2,3,4,5,6). & ! ("C" type added 18-Apr-84.) & 5560 ON SORT.CDE% GO TO 5561 ! name, lines, city & ,5562 ! state/country & ,5563 ! zip code & ,5564 ! counter & ,5565 ! categories 1,2,3,4,5,6 & ,5566 ! PRESORT 5561 DATA$ = DATA$ + EDIT$ (ADD.ADDR$(NUM%), 32%) \ GO TO 5570 5562 DATA$ = DATA$ + EDIT$ (ADD.STATE$, 32%) & \ GO TO 5570 5563 DATA$ = DATA$ + EDIT$ (ADD.ZIP$, 32%) & \ GO TO 5570 5564 DATA$ = DATA$ + FN.RJZF$ (NUM1$(ADD.COUNTER), 4%) & \ GO TO 5570 5565 IF CAT.TYPE$ = "AY" & THEN DATA$ = DATA$ + & EDIT$ (ADD.CATEGORIES$(CAT%-1%), 32%) & \ GO TO 5570 & ELSE IF CAT.TYPE$ = "N" & THEN DATA$ = DATA$ + & FN.RJZF$ (ADD.CATEGORIES$(CAT%-1%), 10%) & \ GO TO 5570 & ELSE IF CAT.TYPE$ = "D" & THEN DATA$ = DATA$ + & FN.DATE.CNV$ (ADD.CATEGORIES$(CAT%-1%)) & \ GO TO 5570 5566 DATA$ = DATA$ + ZIP$ + SPACE$( 10% - LEN(ZIP$)) & ! Pad with spaces to ensure fixed length fields 5570 NEXT I% 5575 DATA.TO.SORT$ = DATA$ DATA$ = "" ! Move the data to sort into MAPSRI ! and wipe out DATA$ for reuse. ! MAPSRI now contains the record's RFA and the data to write to ! the temporary sort file. 5580 PUT #CH.SORT%, COUNT SIZE% & \ NAMES% = NAMES% + 1% & \ IF (NAMES% / 10% * 10%) = NAMES% & THEN M11.MSG$ = "Addresses Selected = " + STR$(NAMES%) & \ CALL M11SCW (M11.MSG$, 16%, 10%) & ! Store away the record to be sorted in a temporary file. & ! Notify user every ten records printed. & 5600 GET #CH.ADD% & \ RECORD_RFA = GETRFA ( CH.ADD% ) & ! Get the next address. & 5610 MOVE FROM #CH.ADD%, REC$ = RECOUNT & \ CALL M11UPK (REC$) & \ GO TO 5620 IF M11.LIST.CODE$ = "A" & \ GO SUB 13500 & \ GO TO 5600 UNLESS MATCH% & ! Go get (and unpack) the next address to check. & 5620 GO SUB 13700 IF M11.PRESORT% & ! Now that we know it is acceptable, also check it for PRESORT & ! (if the user has requested that). & & \ GO TO 5558 & ! Loop back for the next address. & ! For each acceptable address, write out a sort record. & 5630 CALL M11SCW(PLEASE.WAIT$,24%,1%) & \ SLEEP 2% & \ CALL M11SCW(ERASE.EOL$,24%,1%) & \ GO TO 5600 & ! Handle a locked record at 5600. & 5700 UNLOCK #CH.ADD% & \ M11.MSG$ = 'Total selected addresses = ' + NUM1$(NAMES%) & + BEL + BEL & \ GO SUB 14800 & ! Finished searching for addresses to sort, show user total count. & 5800 GO TO 5900 UNLESS M11.PRESORT% & \ CLOSE #CH.KB% & \ OPEN "KB:" AS FILE #CH.KB%, MODE 8% & & \ M11.MSG$ = "Of these, " + NUM1$(VALID%) + " are valid addresses" & + " for PRESORT; " + NUM1$(INVALID%) + " are invalid." & \ CALL M11SCW (M11.MSG$, 17%, 5%) & & \ M11.MSG$ = "bad zip code = " + NUM1$ (ZIP.ERR%) & + ", blank city = " + NUM1$ (CITY.ERR%) & + ", bad state code = " + NUM1$ (STATE.ERR%) & \ CALL M11SCW (M11.MSG$, 18%, 5%) & \ SLEEP 3% & & \ GO TO 5860 IF (VALID% => 500% AND M11.SORT.CODE$ = "PRE") & OR (VALID% => 200% AND M11.SORT.CODE$ = "PR2") & \ M11.MSG$ = "There are not enough valid addresses to qualify for PRESORT." & \ CALL M11SCW (M11.MSG$, 22%, 5%) & ! Notify the user of the situation and the bad PRESORT records. & & \ M11.MSG$ = "Do you wish to continue with PRESORT?" & \ CALL M11SCW (M11.MSG$, 23%, 5%) & ! Since there are not enough addresses, ask user to confirm going on. & 5820 CALL M11SCR (ANS$, 23%, 45%, 1%, "N", "Y", F.END%) & \ F.END% = TRUE% IF ANS$ = "N" & \ IF ANS$ = "?" THEN & M11.MSG$ = "Type 'Y' to continue, press RETURN to go back to the Main Menu." & \ CALL M11SCW (M11.MSG$, 24%, 1%) & \ GO TO 5820 ELSE & IF F.END% OR ANS$ = "N" THEN & CLOSE #CH.SORT% & \ KILL M11.SORT.FILE$ & \ CLOSE #CH.PRT% & \ KILL PRT.FILE$ & \ GO TO 9000 & ! Ask the user if she wants to continue, & ! If not, then delete the sort file and go back to the Main Menu. & & 5840 CALL M11SCW ( ERASE.EOS$, 22%, 1% ) 5860 M11.MSG$ = "Should break labels be printed?" CALL M11SCW ( M11.MSG$, 23%, 5% ) CALL M11SCR (ANS$, 23%, 37%, 1%, "Y", "Y", F.END%) IF ANS$ = "?" THEN M11.MSG$ = "Type 'N' to supress printing of break labels, or " & + "press RETURN." CALL M11SCW ( M11.MSG$, 24%, 1% ) GOTO 5860 ELSE M11.PRT.BREAK.LAB$ = ANS$ END IF ! If PREsort has been selected ask the user if break labels ! should be printed. Store the answer in COMVAR for reference ! in M11LB2. 5900 M11.MSG$ = 'Sorting addresses ... please wait' & \ GO SUB 14800 & \ CLOSE #CH.SORT% & \ WORK$ = SYS (CHR$(11%) + CHR$(CH.KB%)) & \ CLOSE #CH.KB% & \ PRT.CODE% = CALL.SORT% & ! Close of sort file, tell MAIN to call sort routine, notify user. & & 9000 !******************************************************************** & ! & ! & ! E N D O F P R O C E S S I N G & ! & ! & !******************************************************************** & & 9990 ERR.PROGNAM$ = ERR.CALLNAM$ & \ UNLOCK #CH.ADD% & \ M11.EXIT.STATUS% = TRUE% IF F.END% & \ GO TO 32767 & ! Jump around the junk and leave. & 10000 !*************************************************************** & ! & ! & ! S U B R O U T I N E S L O C A L T O & ! & ! T H I S P R O G R A M & ! & ! & !*************************************************************** & & & 13700 !-------------------------------------------------------------------- & ! & ! Validate an address for PRESORT & ! & !-------------------------------------------------------------------- & ! & ! checks for: blank city & ! state not a valid 2 character abbreviation & ! zip code not 5 or 9 digits long & ! (form xxxxx, or xxxxx-xxxx) & ! & !-------------------------------------------------------------------- & ! & ! input: VALID% initialized to 0 & ! INVALID% initialized to 0 & ! ADD.- address record & ! ZIP.ERR% initialized to 0 & ! STATE.ERR% initialized to 0 & ! CITY.ERR% initialized to 0 & ! ST$ list of acceptable state codes & ! & ! output: VALID% count of valid addresses & ! INVALID% count of invalid addresses & ! ZIP$ zip code (without trailing blanks) & ! (="00000" if address is invalid) & ! ZIP.ERR% count of invalid zip codes & ! STATE.ERR% count of invalid state codes & ! CITY.ERR% count of invalid cities (ie, blank) & ! & ! local: A.STATE$ converted state var for searching & ! & ! assumptions: & ! & ! * the first record has already been read & ! & ! * count variables have all been initialized & ! & !-------------------------------------------------------------------- & 13710 A.STATE$ = EDIT$ (ADD.STATE$, 32%) & \ A.STATE$ = "/" + EDIT$ (A.STATE$, ALL.SP%) + "/" & ! Set up search string for state. & 13720 IF FN.BAD.ZIP% THEN & ZIP.ERR% = ZIP.ERR% + 1% & \ GO TO 13790 & 13730 IF POS (ST$, A.STATE$, 1%) = 0% THEN & STATE.ERR% = STATE.ERR% + 1% & \ GO TO 13790 & 13740 IF EDIT$ (ADD.CITY$, ALL.SP%) = "" THEN & CITY.ERR% = CITY.ERR% + 1% & \ GO TO 13790 & & ! Check for specific errors. & 13780 LONGEST.ZIP% = LEN.ZIP% IF LEN.ZIP% > LONGEST.ZIP% & \ VALID% = VALID% + 1% & \ RETURN & ! Handle good addresses. & 13790 ZIP$ = "00000" & \ INVALID% = INVALID% + 1% & \ RETURN & ! Handle bad addresses. & & 15000 !******************************************************************** & ! & ! & ! F U N C T I O N S L O C A L T O & ! & ! T H I S P R O G R A M & ! & ! & !******************************************************************** & & & 19000 !******************************************************************** & ! & ! & ! S T A N D A R D E R R O R H A N D L I N G & ! & ! & !******************************************************************** & 19010 GO TO 19990 IF ERN$ <> SEG$ (ERR.PROGNAM$,1%,6%) & ! Only tracing back an error from another subprogram. & 19015 IF ERR = 154% & THEN RESUME 5630 IF ERL = 5600% & ! Handle record locking for addresses. & 19020 RESUME 5700 IF ERL = 5600 AND ERR = 11 & \ RESUME 5549 IF ERL = 5547 & ! Non-fatal I/O errors against the address file. & ! Record/bucket locked (154); Record not found (155); & ! EOF on device (11). & 19900 ERR.ERL% = ERL & \ ERR.ERR% = ERR & \ ERR.CODE% = FATAL.ERROR% & ! On fatal error, set the error code. & 19990 ON ERROR GO BACK & ! Return to calling program for fatal error processing. & & 32767 SUBEND