1 SUB M11PRT & 2 !******************************************************************** & ! & ! & ! M11PRT & ! & ! Prints out the Mailing List or Sublist & ! & ! & !******************************************************************** & ! 3 ! Program : M11PRT & ! Version : 00 26-FEB-82 & ! Programmer : Jean Fullerton & ! Releaser : & ! & !--------------------------------------------------------------------- 11 ! & ! C O P Y R I G H T & ! & !--------------------------------------------------------------------- 20 ! ! Modification history ! ! 21-Mar-84 Added MAP LSTMAX at line 695 and modified program ! to use the use the form length requested in ! M11SET. In earlier versions MAX.PRT.LINES% was ! local to this module and set to 55 lines. ! ! REV DATE BY ! 1.1 24-Apr-84 Mike Brown ! Modified this and related modules to use RFA access to ! mailing list files. MAPSRO, lines 3250, 3260, 10182, ! 10183. ! ! Changed line 10185 to prevent execution of selection ! subroutine for non-key sorts (because records have ! already been selected). ! ! 1.1 24-Sep-84 Mike Brown ! Modified lines 8040-8050 to print multiple sort keys on header. ! !--------------------------------------------------------------------- 100 ! & ! Description: & ! & ! M11PRT is called after M11SET by SMAIL to print out the addresses & ! in Full or Short form to a file or a printer. & ! & ! Assumptions: & ! & ! * M11PRT will not be called under PRESORT conditions. & ! Only M11LAB is called for PRESORT. & ! & !--------------------------------------------------------------------- 200 ! & ! & ! Interfaces: & ! & ! COMERR - Common Error buffer & ! COMCON - Common Constant buffer & ! COMVAR - Common Variable buffer & ! & ! MAPSCR - Screen buffer & ! MAPHDR - Mail file header buffer & ! MAPMLF - Address record buffer & ! MAPSUB - Sublist definition buffer & ! MAPADD - Unpacked address buffer & ! MAPSEL - Sublist definition array buffer & ! & ! & ! Arguments: & ! PRT.CODE% = 0% start of print (set by both) & ! 1% finished selecting, go sort & ! (set by M11SET) & ! & !--------------------------------------------------------------------- 300 ! & ! & ! Input / Output: & ! & ! & ! Channel Filename Map name Status at entry/exit & ! ------- --------- -------- -------------------- & ! & ! CH.KB% closed or open / open & ! CH.PRT% closed / closed & ! CH.SORTED% closed / killed & ! & !--------------------------------------------------------------------- 400 ! & ! & ! Variable and Array Definitions: & ! & ! & ! AND% Constant value for logical AND & ! ANS$ User keyboard response from M11SCR & ! CITY.STATE$ Formatted city, ST zip code line & ! COUNTER$ String form of counter & ! ERL Line in which error occurred & ! ERR Set to error number after error & ! F.END% Flag to tell if user typed 'END' or ^Z & ! KEY.SORT% Flag to tell if user requested Primary or Alt sorting & ! LINE.n$ Formatted address lines to be printed & ! LINES% Number of lines displayed on screen & ! MATCH% Logical value returned from SUBEXT (does & ! the address match the selection criteria & ! NAM$ Name of sublist selected by user & ! NAMES% Total number of addresses displayed & ! OR% Constant value for logical OR & ! REC$ Dynamic length buffer returned from M11UPK & ! SAV.PRIME.ID$ Variable to contain sublist def. record key & ! & !--------------------------------------------------------------------- 600 ! & ! COMMON Statements & ! & !--------------------------------------------------------------------- 650 !-------------------------------------------------------------------- & ! & ! MAP Statements & ! & !--------------------------------------------------------------------- 695 MAP (LSTMAX) MAX.PRT.LINES% ! This map is used to store the form length requested ! in M11SET 700 !-------------------------------------------------------------------- & ! & ! & ! Subprograms: & ! & ! & ! M11SCW Screen write (writes one line to screen) & ! M11SCR Screen read (reads one field from screen) & ! M11UPK Upacks one address record and leaves in & ! MAPADD & ! & !-------------------------------------------------------------------- & ! 800 ! Subroutines: & ! & ! & ! 12000 (SUBLSD) Load sublist definition into memory & ! 12100 (SUBCNV) Convert sublist definition numeric and date & ! fields & ! 13500 (SUBEXT) Determine if address record meets selection & ! criteria & ! 14800 (SUBNOT) Print an informational message on the screen & ! 14900 (SUBERR) Print an error message on the screen & ! & ! & !-------------------------------------------------------------------- & ! & ! Functions: & ! & ! & ! FN.DATE.CNV$ Convert a date from DD-MMM-YY to YYMMDD & ! FN.RJZF$ Right justify zero fill a numeric string & ! FN.DATE$ Return system date in dd-mmm-yy format & ! FN.TIME$ Return system time in hh:mm (military) format & ! & !-------------------------------------------------------------------- & 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$ = "M11PRT VER:00" & \ ERR.SUBNAM$ = "" & \ ERR.MSG$ = "Unexpected fatal error in M11PRT" & \ 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% & & & \ IF M11.SORT.CODE$ = "P" & OR M11.SORT.CODE$ = "A" THEN KEY.SORT% = TRUE% & ELSE KEY.SORT% = FALSE% & & ! Initialize constants. & 2900 OPEN PRT.FILE$ FOR OUTPUT AS FILE #CH.PRT% & \ OPEN "KB:" AS FILE #CH.KB% & \ C = CTRLC & ! Reopen the keyboard (not in echo control mode) to enable control C. & 3000 !-------------------------------------------------------------------- & ! & ! Get first address - using sorted file & ! & !-------------------------------------------------------------------- & 3100 GO TO 3300 IF KEY.SORT% & ! Jump to other section if sorting by ID's. & 3200 OPEN M11.SORTED.FILE$ FOR INPUT AS FILE #CH.SORTED% & ,ORGANIZATION SEQUENTIAL FIXED & ,ACCESS READ & ,ALLOW NONE & ,MAP MAPSRO & ! Open file with sorted Primary ID's. & 3250 GET #CH.SORTED% & ! Get the first RFA from the sorted input file. & 3260 GET #CH.ADD%, RFA SORTED_RFA & \ MOVE FROM #CH.ADD%, REC$ = RECOUNT & \ CALL M11UPK (REC$) & \ GO TO 8000 & & ! Get the address record using the RFA from the sorted input file, & ! then unpack the record. & 3280 CALL M11SCW(PLEASE.WAIT$,24%,1%) & \ SLEEP 2% & \ CALL M11SCW(ERASE.EOL$,24%,1%) & \ GO TO 3260 & ! Handle a locked record at 3260. & 3300 !-------------------------------------------------------------------- & ! & ! Get first address - using keys & ! & !-------------------------------------------------------------------- & 3320 IF M11.SORT.CODE$ = "A" & THEN RESTORE #CH.ADD%, KEY #1% & ELSE RESTORE #CH.ADD%, KEY #0% & ! First define the access key. & 3330 IF M11.SORT.CODE$ = "A" & THEN GET #CH.ADD%, KEY #1% GE " " & ELSE GET #CH.ADD%, KEY #0% GT SUB.CHR$ + "zzzzzzzzzzzzzzz" & ! Then get the first name record (after any header records). & 3340 \ MOVE FROM #CH.ADD%, REC$ = RECOUNT & \ CALL M11UPK (REC$) & \ GO TO 8000 IF M11.LIST.CODE$ = "A" & \ GO SUB 13500 & \ GO TO 8000 IF MATCH% & 3350 GET #CH.ADD% & & \ GO TO 3340 & ! Loop thru the Mailing List File, until the first acceptable & ! address is found. & 3400 CALL M11SCW(PLEASE.WAIT$,24%,1%) & \ SLEEP 2% & \ CALL M11SCW(ERASE.EOL$,24%,1%) & \ GO TO 3330 & ! Handle a locked record at 3330. & 3420 CALL M11SCW(PLEASE.WAIT$,24%,1%) & \ SLEEP 2% & \ CALL M11SCW(ERASE.EOL$,24%,1%) & \ GO TO 3350 & ! Handle a locked record at 3350. & 8000 !-------------------------------------------------------------------- & ! & ! & ! Print Information & ! & ! & !-------------------------------------------------------------------- & & M11.MSG$ = "generating listing... please wait" & \ GO SUB 14800 & ! Notify the user to wait. & 8040 PAGE% = 0% & \ NAMES% = 0% & \ LINE.1$ = "" & \ LINE.1$ = "Sublist name: " + M11.SUBLIST.NAME$ & IF M11.LIST.CODE$ <> "A" & \ LINE.2$ = "Mailing List: " + EDIT$ (M11.MAIL.FILE$, 128%) & ! Initialize heading information. & 8050 IF M11.SORT.CODE$ = "P" OR M11.SORT.CODE$ = "A" THEN LINE.3$ = "Sorted by: Primary ID" LINE.3$ = "Sorted by: Alternate ID" IF M11.SORT.CODE$ = "A" GOTO 8060 END IF LINE.3$ = "Sorted by: " FOR OPT% = 1% TO M11.SORT.OPTIONS% LINE.3$ = LINE.3$ + ", " IF OPT% > 1% LINE.3$ = LINE.3$ + "Name" IF M11.SORT.CODE$(OPT%) = "N" LINE.3$ = LINE.3$ + "Address line 1" IF M11.SORT.CODE$(OPT%) = "L1" LINE.3$ = LINE.3$ + "Address line 2" IF M11.SORT.CODE$(OPT%) = "L2" LINE.3$ = LINE.3$ + "Address line 3" IF M11.SORT.CODE$(OPT%) = "L3" LINE.3$ = LINE.3$ + "City/Town" IF M11.SORT.CODE$(OPT%) = "T" LINE.3$ = LINE.3$ + "State/Country" IF M11.SORT.CODE$(OPT%) = "S" LINE.3$ = LINE.3$ + "Zip code" IF M11.SORT.CODE$(OPT%) = "Z" LINE.3$ = LINE.3$ + "Counter" IF M11.SORT.CODE$(OPT%) = "C" LINE.3$ = LINE.3$ + & EDIT$(HDR.CAT.PROMPT$(VAL(M11.SORT.CODE$(OPT%))), 128%) & UNLESS POS ("123456", EDIT$ (M11.SORT.CODE$(OPT%),2%), 1%) = 0% NEXT OPT% ! Set up third header line. Up to three sort options are allowed. 8060 GO TO 8100 IF M11.OUTPUT.FORM$ = "F" ! full printout & \ GO TO 8400 IF M11.OUTPUT.FORM$ = "S" ! short printout & ! Dispatch to proper section of code depending on user request. & & 8100 !-------------------------------------------------------------------- & ! & ! Print Information - Full & ! & !-------------------------------------------------------------------- & & 8120 LINE.1$ = LINE.1$ +SPACE$(115%-LEN(LINE.1$))+"Date: "+FN.DATE$(0%) & \ LINE.2$ = LINE.2$ +SPACE$(115%-LEN(LINE.2$))+"Time: "+FN.TIME$(0%) & \ LINE.4$ = "Primary ID Name & Address Alter. ID Count" & \ LINE.4$ = LINE.4$ + " " + HDR.CAT.PROMPT$(I%) FOR I% = 1% TO 6% & ! Initialize heading information. & 8140 PAGE% = PAGE% + 1% & \ PRINT #CH.PRT%, FF; LF; SPACE$(55%); "Full Address Listing"; & SPACE$(40%); "Page "; PAGE% & \ PRINT #CH.PRT%, LF; LINE.1$ & \ PRINT #CH.PRT%, LINE.2$ & \ PRINT #CH.PRT%, LINE.3$ & \ PRINT #CH.PRT%, LF; SPACE$(66%); "-------------------------- Categories ---------------------------" & \ PRINT #CH.PRT%, LINE.4$ & \ PRINT #CH.PRT%, "---------------- ------------------------------ ---------- -----"; & \ PRINT #CH.PRT%, " ---------- ---------- ---------- ---------- ---------- ----------" & \ LINES% = 8% & ! Print out heading on each page. & 8160 CITY.STATE$ = "" & \ CITY.STATE$ = EDIT$ (ADD.CITY$, 136%) + ", " IF ADD.CITY$ > " " & \ CITY.STATE$ = CITY.STATE$ + EDIT$(ADD.STATE$,136%) +" " +ADD.ZIP$ & & \ COUNTER$ = NUM1$ (ADD.COUNTER%) & \ COUNTER$ = SPACE$(6% - LEN(COUNTER$)) + COUNTER$ + " " & & \ FOR CAT% = 1% TO 6% & \ IF HDR.CAT.TYPE$(CAT%) = "N" THEN & WORK$ = TRM$ (ADD.CATEGORIES$(CAT%-1%)) & \ WORK$ = " " + WORK$ UNTIL LEN(WORK$) = 10% & \ ADD.CATEGORIES$(CAT%-1%) = WORK$ 8161 NEXT CAT% & ! Adjust the format of the address information. & ! Right justify any numeric category information. & 8170 PRINT #CH.PRT% & \ PRINT #CH.PRT%, ADD.PRIME.ID$;" ";ADD.NAME$;" ";ADD.ALTERNATE.ID$; & COUNTER$; ADD.CAT1$; " ";ADD.CAT2$; " "; ADD.CAT3$; & " ";ADD.CAT4$;" ";ADD.CAT5$;" ";ADD.CAT6$ & \ PRINT #CH.PRT%, SPACE$(18%); ADD.ADDR1$ UNLESS ADD.ADDR1$ = "" & \ PRINT #CH.PRT%, SPACE$(18%); ADD.ADDR2$ UNLESS ADD.ADDR2$ = "" & \ PRINT #CH.PRT%, SPACE$(18%); ADD.ADDR3$ UNLESS ADD.ADDR3$ = "" & \ PRINT #CH.PRT%, SPACE$(18%); CITY.STATE$ UNLESS CITY.STATE$=" " & \ PRINT #CH.PRT%, LF;SPACE$(18%); ADD.COMMENT$ UNLESS ADD.COMMENT$="" & & \ NAMES% = NAMES% + 1% & \ LINES% = LINES% + 2% & \ LINES% = LINES% + 1% UNLESS ADD.ADDR1$ = "" & \ LINES% = LINES% + 1% UNLESS ADD.ADDR2$ = "" & \ LINES% = LINES% + 1% UNLESS ADD.ADDR3$ = "" & \ LINES% = LINES% + 1% UNLESS CITY.STATE$=" " & \ LINES% = LINES% + 2% UNLESS ADD.COMMENT$="" & ! Print address record contents. & ! Keep tack of the number of printed lines (for page breaks). & 8180 GO SUB 10180 & ! Retrieve the next usable address record. & 8186 IF LINES% < ( MAX.PRT.LINES% - 11% ) THEN GO TO 8160 & ELSE GO TO 8140 & ! Go get the next acceptable record, & ! Then go print it out (with or without a new page and header). & ! 8190 GO TO 8700 & ! Finish printout. & 8400 !-------------------------------------------------------------------- & ! & ! Print Information - Short & ! & !-------------------------------------------------------------------- & & 8420 LINE.1$ = LINE.1$ + SPACE$(64%-LEN(LINE.1$))+"Date: "+FN.DATE$(0%) & \ LINE.2$ = LINE.2$ + SPACE$(64%-LEN(LINE.2$))+"Time: "+FN.TIME$(0%) & \ LINE.4$ = "Primary ID Alter. ID Name State Zip Code" & ! Initialize heading information. & 8440 PAGE% = PAGE% + 1% & \ PRINT #CH.PRT%, FF; LF; SPACE$(29%); "Short Address Listing"; & SPACE$(14%); "Page "; PAGE% & \ PRINT #CH.PRT%, LF; LINE.1$ & \ PRINT #CH.PRT%, LINE.2$ & \ PRINT #CH.PRT%, LINE.3$ & \ PRINT #CH.PRT%, LF+LF; LINE.4$ & \ PRINT #CH.PRT%, "---------------- ---------- ----------------------------- ----------- ----------" & \ PRINT #CH.PRT% & \ LINES% = 9% & ! Print out heading on each page. & 8460 PRINT #CH.PRT%, ADD.PRIME.ID$; " "; ADD.ALTERNATE.ID$; " "; & ADD.NAME$; ADD.STATE$; ADD.ZIP$ & \ NAMES% = NAMES% + 1% & \ LINES% = LINES% + 1% & ! Print address record contents. & 8480 GO SUB 10180 & ! Retrieve the next usable address record. & 8486 IF LINES% < ( MAX.PRT.LINES% - 4% ) THEN GO TO 8460 & ELSE GO TO 8440 & ! Go print it out (with or without a new page and header). & & 8700 !-------------------------------------------------------------------- & ! & ! Finish Printing & ! & !-------------------------------------------------------------------- & 8720 UNLOCK #CH.ADD% & \ PRINT #CH.PRT%, FF IF LINES% > MAX.PRT.LINES% & \ PRINT #CH.PRT%, LF+LF+LF; "Total printed addresses = "; NAMES%; FF & \ CLOSE #CH.PRT% & \ KILL M11.SORTED.FILE$ IF NOT KEY.SORT% & ! Finish printout. & & 8800 !-------------------------------------------------------------------- & ! & ! Queue File to the Device & ! & !-------------------------------------------------------------------- & 8820 WORK$ = SYS (PRT.QUE.STRING$) IF PRT.QUEABLE% & ! Queue the temporary file to the printing device. & & 8890 M11.MSG$="task completed, total selected addresses = "+STR$(NAMES%) & \ GO SUB 14800 & ! Finalize listing. & ! Notify the user that task is done. & & 9000 !******************************************************************** & ! & ! & ! E N D O F P R O C E S S I N G & ! & ! & !******************************************************************** & & 9990 UNLOCK #CH.ADD% & \ ERR.PROGNAM$ = ERR.CALLNAM$ & \ 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 & ! & ! & !*************************************************************** & 10180 !-------------------------------------------------------------------- & ! & ! Get next acceptable record & ! & !-------------------------------------------------------------------- & 10181 IF KEY.SORT% THEN GET #CH.ADD% & \ GO TO 10185 & ! If this is a sort by Primary ID, or Alternate ID, then just get & ! the next record sequentially. & 10182 GET #CH.SORTED% & ! IF not a KEY sort, so get the next RFA from the sorted file. & 10183 GET #CH.ADD%, RFA SORTED_RFA & ! Then get the address record based on sorted RFA. & 10185 MOVE FROM #CH.ADD%, REC$ = RECOUNT & \ CALL M11UPK (REC$) & \ RETURN IF M11.LIST.CODE$ = "A" OR NOT KEY.SORT% & \ GO SUB 13500 & \ GO TO 10181 UNLESS MATCH% & \ GO TO 10190 & ! Move the address into the REC$ buffer, and unpack it. & ! Then check to see if it matches the sublist definition (if any). & ! If it does not match, then go get another record. & 10187 CALL M11SCW(PLEASE.WAIT$,24%,1%) & \ SLEEP 2% & \ CALL M11SCW(ERASE.EOL$,24%,1%) & \ GO TO 10181 & ! Handle a locked record at 10181. & 10189 CALL M11SCW(PLEASE.WAIT$,24%,1%) & \ SLEEP 2% & \ CALL M11SCW(ERASE.EOL$,24%,1%) & \ GO TO 10183 & ! Handle a locked record at 10183. & 10190 RETURN & 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. & 19020 RESUME 8700 IF ERL = 3250 AND ERR = 11 & ! End of input control file, terminate logically. & 19030 IF ERR = 154% & THEN RESUME 3280 IF ERL = 3260% & \ RESUME 3400 IF ERL = 3330% & \ RESUME 3420 IF ERL = 3350% & \ RESUME 10187 IF ERL = 10181% & \ RESUME 10189 IF ERL = 10183% & ! Handle a locked address record. & 19040 RESUME 8700 IF ERL = 3330 AND ERR = 11 & \ RESUME 8700 IF ERL = 3350 AND ERR = 11 & \ RESUME 8700 IF ERL = 10181 AND ERR = 11 & \ RESUME 8700 IF ERL = 10182 AND ERR = 11 & \ RESUME 8700 IF ERL = 10183 AND ERR = 11 & ! EOF on read of address file. & 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