1 H EXAMP6 2 H* 3 H* PRINT CLASS ROLL AND ENROLLMENT REPORTS 4 H* 5 FROSTER IPE F4800 48 DISK14 S 6 FTABLE1 IT F 800 80 EDISK14 S 7 FTABLE2 IT F 800 80 EDISK14 S 8 FTABLE3 IT F 800 80 EDISK14 S 9 FREPORT1 O F1320 132 OF LPRINTER 10 FREPORT2 O F1320 132 OV LPRINTER 11 E TABLE1 TABDNR 1 50 2 0ATABDNA 40 12 E TABLE2 TABCNR 1 125 5 0ATABCNA 51 13 E TABLE3 TABSNR 1 250 6 0ATABSNA 20 14 LREPORT1 101 6012 15 LREPORT2 101 6012 16 IROSTER AA 01 17 I 1 20DEPT L3 18 I 3 50COURSEL2 19 I 1 50CTK 20 I 6 60SECT L1 21 I 1 60STK 22 I 7 13 STUID 23 I 14 48 NAME 24 C* 25 C* COUNT STUDENTS ENROLLED IN A SECTION 26 C* (THIS COUNT IS USED IN PRINTING THE CLASS ROLL) 27 C* 28 C 01 STCNTR ADD 1 STCNTR 40 29 C* 30 C* WHEN A LEVEL BREAK OCCURS, LOOK UP THE DEPARTMENT, 31 C* COURSE, AND SECTION IN THE APPROPRIATE TABLE TO 32 C* MAKE THE CORRESPONDING TEXT AVAILABLE FOR OUTPUT 33 C* 34 C L1 STK LOKUPTABSNR TABSNA 20 31 35 C L2 CTK LOKUPTABCNR TABCNA 51 32 36 C L3 DEPT LOKUPTABDNR TABDNA 40 33 37 C* 38 C* BECAUSE THE COURSE NAME CONTAINS THE CREDIT HOURS IN 39 C* THE RIGHTMOST POSITION OF THE FIELD, IF THE TABLE 40 C* LOOKUP WAS SUCCESSFUL, MOVE THE NAME TO A WORK FIELD 41 C* TO TRUNCATE THE HOURS 42 C* 43 C L2 32 MOVELTABCNA CRSNAM 50 44 C* 45 C* COUNT STUDENTS ENROLLED IN A SECTION 46 C* (THIS COUNT IS USED IN PRINTING THE ENROLLMENT REPORT) 47 C* 48 C 01 STCNT ADD 1 STCNT 40 49 C* 50 C* WHEN A LEVEL BREAK HAS OCCURRED, "ROLL UP" THE LOWER 51 C* LEVEL COUNT INTO THE NEXT HIGHER LEVEL COUNTER 52 C* (THESE COUNTS ARE USED IN PRINTING THE ENROLLMENT REPORT) 53 C* 54 CL1 STCNT2 ADD STCNT STCNT2 40 55 CL2 STCNT3 ADD STCNT2 STCNT3 40 56 OREPORT1 H 101 1P 57 O OR OF 58 O PAGE Z 72 59 O 68 'PAGE' 60 O 43 'ENROLLMENT REPORT' 61 O UDATE 8 '0 / / ' 62 O H 11 L3 63 O 33 TABDNA 55 64 O N33 32 '*** NOT FOUND ***' 65 O DEPT Z 14 66 O 11 'DEPARTMENT:' 67 O H 12 L2 68 O 32 CRSNAM 65 69 O N32 32 '*** NOT FOUND ***' 70 O COURSEZ 14 71 O 10 'COURSE:' 72 O T 1 L1 73 O STCNT B 63 ' , 0*' 74 O 31 TABSNA 37 75 O N31 34 '*** NOT FOUND ***' 76 O SECT Z 16 77 O 14 'SECTION:' 78 O T 11 L2 79 O 20 'COURSE ENROLLMENT' 80 O STCNT2 B 64 ' , 0**' 81 O T 11 L3 82 O 21 'DEPARTMENT ENROLLMENT' 83 O STCNT3 B 65 ' , 0***' 84 OREPORT2 H 101 L1 85 O OR OV 86 O 36 'CLASS ROLL' 87 O UDATE 8 '0 / / ' 88 O H 11 L1 89 O 31 TABDNA 55 90 O N31 32 '*** NOT FOUND ***' 91 O DEPT Z 14 92 O 11 'DEPARTMENT:' 93 O H 11 L1 94 O 32 CRSNAM 65 95 O N32 32 '*** NOT FOUND ***' 96 O COURSEZ 14 97 O 10 'COURSE:' 98 O H 12 L1 99 O 33 TABSNA 37 100 O N33 34 '*** NOT FOUND ***' 101 O SECT Z 16 102 O 14 'SECTION:' 103 O D 1 01 104 O STUID 16 105 O NAME 60 106 O T 31 L1 107 O STCNTR B 63 ' , 0*' 108 O 34 'STUDENTS ENROLLED:' 109 O 15 'NUMBER OF' |
Statement 5 is the File Description specification for the sorted class roster records (ROSTER), statements 6-8 are the File Description specifications for the files from which three tables will be loaded (TABLE1, TABLE2, TABLE3), and statements 9-10 are the File Description specifications for two reports to be printed (REPORT1, REPORT2). Notice that the file designation (column 16) for the three table files is T, for table file, and that they will each have an Extension specification (column 39 contains an E). Each of the report files has a unique overflow indicator (OF, OV), since each may have a report page reaching the overflow position independently.
Statements 11-13 are the Extension specifications for the three table files. Each specification defines a pair of tables. When tables are defined in pairs, the first table is considered the "argument" table and the second is considered the "function" table. The elements are loaded and accessed in synchronization. When you use the LOKUP operation to search for an element in one table, the internal mechanism that is the equivalent to an "index" for both tables is positioned to the same relative element. So, in this program where the first table is a department table - when I use the number '05' in a LOKUP operation on the argument table TABDNR, I can then move the element from TABDNA which contains 'ECONOMICS'. Table files are loaded automatically before any records are processed from any other input or update files. A table files is not closed until the end of the program, so it is not possible to load multiple table files from a single sequential medium, such as single tape volume.
Statements 16-23 define the record and fields to be read from the primary input, the sorted roster file. There is only one record type, so there was no necessity to use identifying characteristics. There are three control levels: Department, Course, and Section. Control levels in RPG are specified from lowest (L1) to highest (L9). When the value of a control level data item changes, that level indicator is set on. In addition, all lower number level indicators are turned on. So, when the Course number changes, L2 and L1 will both be turned on to indicate that control functions for both Section and Course should be carried out.
Even though using control levels causes special actions to be triggered when a control data item changes, there is still a distinction between detail time and total time. So, looking at the Calculation specifications, you can see that I have specified operations to occur both at detail time and at total time conditioned by the control level indicators.
Statements 54-55 are total time operations, so they will happen before detail time operations. I want to produce totals on one of the reports for all three control levels when the control level data items change. These two statements "roll" the current level total up into the next higher level when a level change has happened. STCNT is the count of students at the lowest level (Section), and it will be added to STCNT2, the count at the intermediate level (Course). STCNT2 will be added to STCNT3, the count at the highest level (Department).
Statements 34-36 are detail time operations, so they will happen after the totals have been "rolled up" and printed after a control level change has been detected. These three statements use data fields from the input record to LOKUP the corresponding table elements from each of the three paired tables. An indicator will be set on if the lookup was successful for each LOKUP (31, 32, and 33 respectively). Likewise, the indicator will be set off if the lookup was unsuccessful.
Statement 43 performs a special operation using the "function" element from the Course table pair. The elements of this table each contain two related, but separate, pieces of information: the name of the course and the credit hours. After retrieving the element with the LOKUP, I use a MOVEL to move just the course name to a new work field, truncating the credit hours off. If I needed the credit hours for this program, I could do a MOVE operation to a single character field to separate just the credit hours out.
The only other calculations (28 and 48) simply add 1 to a counter for each record read in from the class roster file.
The first report, the "Enrollment Report" is what is typically referred to as a summary report. No information is produced for individual records read from the input file. Instead, information from the input records is "summarized" and the resulting totals are produced when the control level data items change.
Two of the heading lines are produced when control levels change. Remember, these will be produced in the logic cycle after the totals have been produced which correspond to the data that was read in before the control level changed. The indicators that were used to signal success on the table LOKUP operations are used to either print the Department and Course name or a constant to signal an error has occurred.
The first total line looks pretty similar to the specifications for the two heading lines above, except that it will be produced at total time and will print the count of students that have been read in for the section number preceding the change in the data which caused the control level to change. Notice that when the STCNT field is printed (statement 73), Blank After (column 39) contains a 'B'. This causes the data field to be reset to zero after it is moved to print, so that it will be ready to accumulate the next control group.
The next two total line groups simply print the totals accumulated for the intermediate and highest control level, again with Blank After specified to reset the totals after printing.
The second report, the "Class Roll" contains a listing of each student enrolled in a class. Only the lowest control level (L1, Section number) is used to control this report. When the Section number changes, the count of students enrolled in the section is printed and then headings are printed for the next Section (the one causing the control level change).
When the last record is read from the input file, LR is set on. All of the control level indicators are also set on, so that the "final" control total activity is automatically triggered. RPG is really efficient for quickly putting together complex reports driven by multiple control levels.
The compiler listing and the output reports are available for viewing here: Example 6 SYSOUT.
The jobstream, complete with JCL and RPG source are available for download here: Example 6 jobstream. The tables files data is contained on a single AWSTape file - jay801.aws (also in the archive). The first step of the jobstream sorts the class roster (produced by Example Program 5) creating a temporary file. Steps two through four read the AWSTape files creating three temporary files. You will need to ensure that the volume serial numbers for both the tape and temporary disk datasets are correct for your MVT system before running the jobstream. Note also that the MVT Sort program cannot access files on DASD later than 2314's.
This page was last updated on January 17, 2015.