sams_teach_yourself_cobol_in_24_hours_-_hour_20_advanced_reporting

Sams Teach Yourself COBOL in 24 Hours - Hour 20 Advanced Reporting

Return to Teach Yourself COBOL in 24 Hours, COBOL bibliography, COBOL, COBOL DevOps, Awesome COBOL, Awesome IBM Mainframe, IBM Mainframe development, IBM Mainframe bibliography, Fortran

“ (TYCb24H 1998)

Hour 20 Advanced Reporting

To make good use of the data collected on a daily basis, the data must be analyzed and reported. Quick reactions to trends and activity can lead to greater profits or prevent disaster. However, simple reports showing detailed activity do not always help businesses react. Consequently, you frequently need to produce more than a report of detailed data items.

This hour covers concepts relating to advanced reporting, including topics such as

• The definition of control breaks

• Determining the proper hierarchy of control breaks

• Subtotaling

• Walking through a program with control breaks

Advanced reports often contain summary information that is gathered from individual transactions. This summary reporting can yield a tremendous amount of information in a short, concise format, usually in the form of totals and subtotals. A single report might contain several levels of information. For example, the transactions that are applied to the dealer file might be analyzed before the update is applied, thus accomplishing several tasks.

The business owner can see the impact of the transactions before they are applied. Any invalid data is exposed, and the problem can be corrected before the actual update is applied. The totals from the report can be compared with the totals produced by the update process as an audit to ensure that both processes are operating properly.

The example for this hour reports totals for quantity, amount, and commission for each transaction type, within each date, for each dealer. It also reports a grand total. There may be multiple transactions for a particular transaction type for a specific day, and because this report is a summary report, the individual record detail is not printed. This type of reporting involves control breaks.

Image

A control break is what happens in a program that produces the types of totals just described. The program branches out and performs the special subtotal processing when a change or break occurs in the sequence of data items being tested. This break in sequence causes the control break.

Reporting with Control Breaks Control breaks are directly related to the sequence that is desired for the report. Examine the report layout designed for the current example.

Created by: CHAPT20A Transaction Summary by Dealer Page ZZZ9 Created on: MM/DD/YY At: HH:MM:SS

                                          Qty     Amount  Commission

  • Total XXXXXXXXXXX Tran Type XXX…XXX ZZZZ9 $$$,$$$.99- $$$,$$$.99-
    • Total XXXXXXXXXXX Tran Date XXX…XXX ZZZZ9 $$$,$$$.99- $$$,$$$.99-

**

  • Total XXXXXXXXXXX Dealer Name XXX…XXX ZZZZ9 $$$,$$$.99- $$$,$$$.99-

****Grand Totals ZZZZ9 $$$,$$$.99- $$$,$$$.99-

Determining the Number and Hierarchy of Control Breaks The subtotal levels determine the number and hierarchy of control breaks. This sequence is one of the most fundamental to the process. In this hour’s example, the levels are grand totals, dealer totals, transaction date totals, and transaction type totals. They are listed from highest level to smallest level to help explain what is happening in the program.

The grand total is the only total not dependent on the contents of the data. It is generated after all of the data is processed. However, this condition counts as the highest level control break. The next level is the dealer level. Anytime a new dealer is encountered in the data, this break is triggered. The third break is the transaction date break. If a new transaction date is encountered, then this control break is activated. The final level is the transaction type level. This break occurs whenever a new transaction type is encountered in the data. To summarize, the program has four control-break levels. The highest level is the grand total level. The next level is the dealer level. The level that occurs under the dealer level is the date level, and the level under that is the type level.

This hierarchy might appear to be reversed. Because transaction type appears on the report first, you might think that transaction type is the first level. This is a common conceptual error. As you examine the logic in the example program, it will become apparent why you must think of these levels as proceeding from the highest level to the lowest and not the lowest to the highest.

One important issue relating to control breaks is the Sort sequence. The data must be sorted in sequence of the control-break hierarchy. The Sort sequence for the example is dealer name, transaction date, and then transaction type. As you can see, the control-break levels required for the report determine this sequence. If you attempt to create control-break levels that differ from the Sort sequence of the Input data, your report program will not function properly. The data will be out of order, or items that should be grouped together will instead appear multiple times.

Subtotaling When control breaks are used, subtotals are usually associated with each level of control break. Programmers use several methods to accumulate these subtotals. Some programmers, after retrieving a record, Add the item to every subtotal field defined for the program. This process can be very inefficient. A better approach is to Add the subtotals to the next highest level of subtotal when the control break for that level is processed.

In the current example, when a type break occurs, the accumulated subtotals for type are added to the date subtotal field. When a date break occurs, the date field subtotals are added to the dealer subtotals. When a dealer break occurs, then the dealer subtotals are added to the grand totals. Each level feeds the preceding level, which makes for very efficient processing.

Image

One common mistake relating to subtotals involves the failure of the programmer to reset the value after using the subtotal. After the subtotal is added to the next highest level, the subtotal field should be cleared—reset to zero. Another mistake is not initializing the subtotal fields to zero in Working-Storage to begin with. The best and most efficient method for initializing these values at the start of the program is to use the Value clause when the item is defined.

The order of operations should be as follows: Write the subtotal record to the report, Add the subtotal to the next highest level, and then zero the subtotal field that was just processed. If this process occurs for every control break, the totals are always correct.

Walking Through a Program with Control Breaks Image

On several occasions in the previous hours, segments of a program were intermixed with the text. Most modern programming uses this procedure, called a program walk through, as a way to explain what a program is doing and why. The walk through is often used as a peer review of a programmer’s work. Sometimes the walk through finds programming inefficiencies that can be corrected; other times the activity uncovers serious programming flaws. Walk-through participants often discover interesting tips and techniques that they can use in other programs.

In this walk through of a program with multiple levels of control breaks, the reasons behind the code are explained in detail. In addition, tips and cautions that you can use in your future control break programming are presented.

Start the walk through by examining the initial program setup and the data files used by the program. As usual with a report program, you have an Input data file and an assignment to the printer file. This program also has a reference to the Indexed file Dealer.Dat and a Sort Work file. The Dealer.Dat file is required to retrieve the dealer name from the dealer file. The transaction data, on which the report is based, does not contain the dealer name. The Sort Work file is used by the Sort. The transaction data cannot possibly be in the correct sequence for the report, because it does not contain the dealer name. The Sort is used to prepare the Input file and get it in the same sequence as the control break hierarchy previously decided on.

000001 @OPTIONS MAIN,TEST 000002 Identification Division. 000003 Program-Id. Chapt20a. 000004* Control Breaks 000005 Environment Division. 000006 Configuration Section.

000007 Source-Computer. IBM-PC. 000008 Object-Computer. IBM-PC. 000009 Input-Output Section. 000010 File-Control. Access to the dealer file is Random. Because the Input data records are out of order, you need to Read a dealer record for each Input data record to fill in the corresponding dealer name.

000011 Select Dealer-File Assign To “Dealer.Dat” 000012 Organization Indexed 000013 Access Random 000014 Record Key Dealer-Number 000015 Alternate Record Key Dealer-Name Of Dealer-Record 000016 File Status Dealer-Status. 000017 Select Report-File Assign To Printer. The Input data file for this program is Trans1.Txt. This data file is provided on the CDROM in the \DATAFILE folder.

The file was carefully constructed and contains data for several dealers who are in the dealer master file. There are multiple dates, but not enough to make the report extremely large. One dealer in the transaction file does not correspond to an existing dealer in the dealer master file. The format of the transaction file is the same as that used in previous hours.

000018 Select Optional Trans-File Assign To “Trans1.TXT” 000019 Organization Is Line Sequential. 000020 Select Sort-File Assign To Sort-Work. 000021 Data Division. 000022 File Section. 000023 Fd Dealer-File. 000024 01 Dealer-Record. 000025 03 Dealer-Number Pic X(8). 000026 03 Dealer-Name. 000027 05 Last-Name Pic X(25). 000028 05 First-Name Pic X(15). 000029 05 Middle-Name Pic X(10). 000030 03 Address-Line-1 Pic X(50). 000031 03 Address-Line-2 Pic X(50). 000032 03 City Pic X(40). 000033 03 State-Or-Country Pic X(20). 000034 03 Postal-Code Pic X(15). 000035 03 Home-Phone Pic X(20). 000036 03 Work-Phone Pic X(20). 000037 03 Other-Phone Pic X(20). 000038 03 Start-Date Pic 9(8). 000039 03 Last-Rent-Paid-Date Pic 9(8). 000040 03 Next-Rent-Due-Date Pic 9(8). 000041 03 Rent-Amount Pic 9(4)v99.

000042 03 Consignment-Percent Pic 9(3). 000043 03 Last-Sold-Amount Pic S9(7)v99. 000044 03 Last-Sold-Date Pic 9(8). 000045 03 Sold-To-Date Pic S9(7)v99. 000046 03 Commission-To-Date Pic S9(7)v99. 000047 03 Filler Pic X(15). 000048 Fd Report-File. 000049 01 Report-Record Pic X(80). 000050 Fd Trans-File. 000051 01 Trans-Record. 000052 03 Transaction-Date Pic 9(8). 000053 03 Transaction-Date-X Redefines Transaction-Date. 000054 05 Trans-Month Pic 99. 000055 05 Trans-Day Pic 99. 000056 05 Trans-Year Pic 9(4). 000057 03 Transaction-Type Pic X(4). 000058 03 Transaction-Dealer Pic X(8). 000059 03 Transaction-Price Pic S9(7)v99. 000060 03 Transaction-Qty Pic 9(3). 000061 03 Filler Pic X(40). The Sort file is one of the most important areas of the program. It contains a single record for every record in the transaction file. Several fields in the record do not exist in the Input file. The record layout of the Sort file is not a copy of the Input file record. The Sort Key is also very important. Notice that the organization of the Sort Key matches the hierarchy that was previously discussed for the report.

The names chosen for the elementary items under the date field are significant. They match the names of the fields in the transaction record; however, they are in a different order. To Sort by date and to arrange the oldest date first in the file and the newest date last, you must use the date format as defined in the Sort record. You must use Year, Month, and then Day to force the Sort into the proper sequence.

Commission is also stored in this field, although that item is not included in the Input data record. The Commission field is computed during the Input Procedure of the Sort. Because the dealer record contains the consignment percentage that is used for computing this field and is read to retrieve the dealer name, calculating the commission at this point makes sense. You could also perform the calculation in the Output Procedure; however, that would mean an additional special Read of the dealer file, which is inefficient. Because you are already going to Sort on dealer name, the Read must be issued for the dealer file in the Input Procedure. While the dealer file record is available, the fields used by the program for calculating the commission are utilized.

000062 Sd Sort-File. 000063 01 Sort-Record. 000064 03 Sort-Key. 000065 05 Dealer-Name.

000066 10 Last-Name Pic X(25). 000067 10 First-Name Pic X(15). 000068 10 Middle-Name Pic X(10). 000069 05 Sort-Trans-Date. 000070 10 Trans-Year Pic 9(4). 000071 10 Trans-Month Pic 9(2). 000072 10 Trans-Day Pic 9(2). 000073 05 Sort-Trans-Type Pic X(4). 000074 03 Sort-Trans-Price Pic S9(6)v99. 000075 03 Sort-Trans-Qty Pic 9(3). 000076 03 Sort-Commission Pic S9(6)v99. The various heading lines are coded next.

000077 Working-Storage Section. 000078 01 Heading-Line-1. 000079 03 Filler Pic X(12) Value “Created by:”. 000080 03 Filler Pic X(8) Value “CHAPT20A”. 000081 03 Filler Pic X(8) Value Spaces. 000082 03 Filler Pic X(29) 000083 Value “Transaction Summary by Dealer”. 000084 03 Filler Pic X(7) Value Spaces. 000085 03 Filler Pic X(5) Value “Page”. 000086 03 Page-No Pic Z(4)9 Value Zeros. 000087 01 Heading-Line-2. 000088 03 Filler Pic X(12) Value “Created on:”. 000089 03 Date-MM Pic 99. 000090 03 Filler Pic X Value “/”. 000091 03 Date-DD Pic 99. 000092 03 Filler Pic X Value “/”. 000093 03 Date-YY Pic 99. 000094 01 Heading-Line-3. 000095 03 Filler Pic X(12) Value “At:”. 000096 03 Time-HH Pic 99. 000097 03 Filler Pic X Value “:”. 000098 03 Time-MM Pic 99. 000099 03 Filler Pic X Value “:”. 000100 03 Time-SS Pic 99. 000101 01 Heading-Line-4. 000102 03 Filler Pic X(51) Value Spaces. 000103 03 Filler Pic X(6) Value “ Qty”. 000104 03 Filler Pic X(12) Value “ Amount”. 000105 03 Filler Pic X(10) Value “Commission”. The Blank-Line data item is coded so that you can place blank lines after certain heading lines and not have to worry about the complexities introduced when Before Advancing is used with After Advancing on the Write statement.

000106 01 Blank-Line Pic X(80) Value Spaces. Some programmers use a separate total line description for every total line. This approach makes sense when the layout of the different columns of data is different. For example, one technique that makes reports more readable is to offset the totals by one or more positions from the column of detail data. This simple report does not require an offset, so a single total line is used.

Image

The total here uses numeric edited data items with the $ symbol, which displays the field on the report with a leading dollar sign. This edit pattern produces at least one dollar sign on the report and thereby limits the size of your data field to one position less that the total number of $ defined. For example, the dollar amounts in these examples can contain a maximum value of 99,999.99, which is one significant position smaller than the 999,999.99 you might expect when you examine the numeric edited data item Picture clause.

000107 01 Total-Line. 000108 03 Total-Description Pic X(51) Value Spaces. 000109 03 Total-Qty Pic Z(4)9. 000110 03 Filler Pic X Value Spaces. 000111 03 Total-Amt Pic $$$,$$$.99-. 000112 03 Filler Pic X Value Spaces. 000113 03 Total-Commission Pic $$$,$$$.99-. Because only a single total line is used, you must have different data items in which to build the different total descriptions. An alternative to this method is to String the various total descriptions together when required. As much as possible you should avoid this type of coding. The String statement requires much more computing overhead than the simple Move required to construct these descriptions.

000114 01 Desc-Type. 000115 03 Filler Pic X(11) Value “* Total”. 000116 03 Desc-Type-Type Pic X(4). Notice the use of Trans-Month, Trans-Day, and Trans-Year in the Desc-Date Group Level item. These field names are the same as those in the transaction record, the Sort record, and the save data areas that are defined shortly. This feature allows you to use Move with Corresponding to reverse the saved date so that it is presented to the users in a more familiar manner. End users feel more comfortable with reports that present data as they are used to seeing it; for example, MM/DD/YYYY instead of YYYY/MM/DD.

000117 01 Desc-Date. 000118 03 Filler Pic X(11) Value “** Total”. 000119 03 Trans-Month Pic 99. 000120 03 Filler Pic X Value “/”.

000121 03 Trans-Day Pic 99. 000122 03 Filler Pic X Value “/”. 000123 03 Trans-Year Pic 9(4). 000124 01 Desc-Dealer. 000125 03 Filler Pic X(11) Value “**

  • Total”.

000126 03 Desc-Dealer-Name Pic X(30). The save fields help detect the different control breaks. The High-Values assigned as values to the alphabetic data items ensure that the first record read causes a control break. When compared against these fields, the data record will be different. The program uses High-Values to detect the fact that this record is the first record read and that the save fields are to be initialized with the fields from this data record.

Some programmers handle this condition differently. They code a special Read for the first data record and initialize the control break save fields. This method requires two Read or Sort return statements for a file, instead of a single statement. Although this approach is conceptually correct, I have found that the single Read leads to programs that are clearer and easier to maintain. A common mistake that programmers make when using a special “seed” Read, as it is called, is the failure to process the first record in the file and Add its data values to the required subtotal. Failure to process the first and last records in a file are common mistakes programmers make when handling control breaks.

Notice that the save fields are defined in exactly the same order as the Sort Key in the Sort record. This feature permits an easier Move when initializing the fields the first time. The entire contents of the Sort Key can be moved instead of individually moving fields.

000127 01 Save-Fields. 000128 03 Save-Dealer-Name Value High-Values. 000129 05 Last-Name Pic X(25). 000130 05 First-Name Pic X(15). 000131 05 Middle-Name Pic X(10). 000132 03 Save-Date-X. 000133 05 Trans-Year Pic 9(4). 000134 05 Trans-Month Pic 9(2). 000135 05 Trans-Day Pic 9(2). 000136 03 Save-Type Pic X(4) Value High-Values. The Accumulators group contains the various fields that are used in the different levels of subtotal. Notice the use of the same name for every total field used. This feature allows an Add with Corresponding to accumulate the various subtotals. You will have a group of subtotals for every level of control break identified for the report.

000137 01 Accumulators. 000138 03 Grand-Totals. 000139 05 Total-Qty Pic 9(5) Value Zeros. 000140 05 Total-Amt Pic S9(6)v99 Value Zeros. 000141 05 Total-Commission Pic S9(5)v99 Value Zeros.

000142 03 Dealer-Totals. 000143 05 Total-Qty Pic 9(5) Value Zeros. 000144 05 Total-Amt Pic S9(6)v99 Value Zeros. 000145 05 Total-Commission Pic S9(5)v99 Value Zeros. 000146 03 Date-Totals. 000147 05 Total-Qty Pic 9(5) Value Zeros. 000148 05 Total-Amt Pic S9(6)v99 Value Zeros. 000149 05 Total-Commission Pic S9(5)v99 Value Zeros. 000150 03 Type-Totals. 000151 05 Total-Qty Pic 9(5) Value Zeros. 000152 05 Total-Amt Pic S9(6)v99 Value Zeros. 000153 05 Total-Commission Pic S9(5)v99 Value Zeros. As it did in Hour 19, “Reporting,” the line count starts at 99, thus causing a page break and the printing of headings when the first line of print is produced. The different date and time fields print, in the heading, the date and time the report is produced.

000154 01 Line-Count Pic 99 Value 99. 000155 01 Page-Count Pic 9(4) Value Zeros. 000156 01 Max-Lines Pic 99 Value 60. 000157 01 Date-And-Time-Area. 000158 03 Work-Date Pic 9(6). 000159 03 Work-Date-X Redefines Work-Date. 000160 05 Date-YY Pic 99. 000161 05 Date-MM Pic 99. 000162 05 Date-DD Pic 99. 000163 03 Work-Time Pic 9(8). 000164 03 Work-Time-X Redefines Work-Time. 000165 05 Time-HH Pic 99. 000166 05 Time-MM Pic 99. 000167 05 Time-SS Pic 99. 000168 05 Filler Pic XX. The String-Pointer field and the String statements assemble a single name from the three parts of the name that are stored in the Sort record. The name is assembled in the Output Procedure so that it can remain in Last, First, Middle name order during the Sort.

Two separate portions of the program use the Done-Flag field. The first controls the Input Procedure for the Sort, and the second controls the processing in the Output Procedure.

000169 01 String-Pointer Pic 99 Value Zeros. 000170 01 Done-Flag Pic X Value Spaces. 000171 88 All-Done Value “Y”. 000172 01 Dealer-Status Pic XX Value Zeros. 000173 88 Dealer-Success Value “00” Thru “09”. 000174 Procedure Division. Declaratives catch any unexpected problems that might occur in the Indexed dealer file.

000175 Declaratives. 000176 Dealer-File-Error Section. 000177 Use After Standard Error Procedure On Dealer-File 000178 . 000179 Dealer-Error-Paragraph. 000180 Display “Error on Dealer File “ Dealer-Status 000181 . 000182 End Declaratives. 000183 Chapt20a-Start. 000184 Display “Begin Process Chapt20A” The Sort statement ensures that the Input data is in the same order as the hierarchy of the control breaks. The Sort-Key Group Level item of Sort-Record defines this hierarchy. The Sort can be coded specifying the individual fields used in the Sort, but the method shown is slightly more efficient. The Sort needs to handle only the single field and does not need to compare multiple fields.

000185 Sort Sort-File Ascending Key Sort-Key 000186 Input Procedure Sort-In 000187 Output Procedure Print-Report 000188 Stop Run 000189 . The Input Procedure, Sort-In, handles the Input operations related to the file being sorted and constructs the Sort-Record that is to be sorted. The Process-Input-Records Paragraph is performed repeatedly until the All-Done condition is Set to true. This flag indicates that all records in the Input file have been processed and released to the Sort. After the Input Procedure is complete, the Input files are closed.

000190 Sort-In. 000191 Open Input Trans-File 000192 Dealer-File 000193 Perform Process-Input-Records Until All-Done 000194 Close Trans-File 000195 Dealer-File 000196 . This Paragraph performs the actual Read of the Input file and, if a record is retrieved, performs the Paragraph that processes the data and releases it to the Sort. If the end of file is reached, all records have been processed and the All-Done flag is set so that the Input Procedure will end.

000197 Process-Input-Records. 000198 Read Trans-File 000199 At End Set All-Done To True 000200 Not At End

000201 Perform Move-And-Release-Input 000202 End-Read 000203 . The Move-And-Release-Input Paragraph builds the individual Sort record from the available Input data. It reads the dealer file to retrieve the name and consignment percentage. The actual consignment amount for this transaction is then computed and moved to the appropriate Sort record field. This computation is done here instead of in the Output Procedure so that there can be a single Read of the dealer file for each record. Because the Sort requires the dealer name, it is read in the Input Procedure. If the commission were not computed here, another Read of the dealer master would be required in the Output Procedure to retrieve the consignment percentage.

Recall that the date format of the transaction date in the Sort record is the “reverse” of that in the Input record. The Sort record format is YYYYMMDD, and the Input record is MMDDYYYY.

After the necessary fields are moved, the record is released to the Sort.

000204 Move-And-Release-Input. 000205* Reverse The Date 000206 Move Corresponding Transaction-Date-X To 000207 Sort-Trans-Date 000208* Move The Data 000209 Move Transaction-Price To Sort-Trans-Price 000210 Move Transaction-Qty To Sort-Trans-Qty 000211 Move Transaction-Type To Sort-Trans-Type 000212* Read Dealer File To Retrieve Name And Consignment Percent 000213 Perform Retrieve-Dealer-Record 000214* Move The Name And Compute Consignment 000215 Move Dealer-Name Of Dealer-Record To 000216 Dealer-Name Of Sort-Record 000217 Compute Sort-Commission Rounded = 000218 (Transaction-Qty * Transaction-Price) * 000219 (Consignment-Percent / 100) 000220* Release The Record 000221 Release Sort-Record 000222 . The Retrieve-Dealer-Record Paragraph fills in the required information for the Sort. If the dealer record is not found, the word **UNKNOWN** is moved into the field, and a default consignment percentage of 10 is applied.

000223 Retrieve-Dealer-Record. 000224 Move Transaction-Dealer To Dealer-Number Of Dealer-Record 000225 Read Dealer-File 000226 Invalid Key 000227 Move “**UNKNOWN**” To 000228 Dealer-Name Of Dealer-Record

000229 Move 10 To Consignment-Percent 000230 End-Read 000231 . Print-Report is the Output Procedure from the Sort. It contains the meat of the control break program. After some initial housekeeping of opening the report file and filling in the date and time for the headings, each record from the sorted file is returned and processed until all records have been processed.

000232 Print-Report. 000233 Open Output Report-File 000234 Move Space To Done-Flag 000235 Perform Fill-Initial-Headings 000236 Perform Return-Process-Records Until All-Done 000237 Close Report-File 000238 . The Return-Process-Records Paragraph handles the actual returning of the Sort records and the decisions made based on the values of the various data fields in the Input records.

Image

Always include the final processing described here after the At End condition is encountered on your Input file. Programmers frequently fail to process the final required control breaks and instead terminate the program when this end-of-file condition occurs. Note the order of the break processing at the end of file. The lowest-level break is processed first, then the next highest, and so on. This sequence is required so that every subtotal on the report is properly printed and processed into the next level’s subtotal fields.

If the end of file is not reached, the program checks for a change in one of the fields that defines the control breaks.

000239 Return-Process-Records. 000240 Return Sort-File 000241 At End 000242 Perform Type-Break 000243 Perform Date-Break 000244 Perform Dealer-Break 000245 Perform Print-Grand-Totals 000246 Set All-Done To True 000247 Not At End 000248 Perform Check-For-Break 000249 End-Return 000250 . The Check-For-Break paragraph examines the values of the various data fields, comparing them against the save fields. If a control break occurs, the appropriate break is processed. The order of the checks is significant. The first check compares the save field value against High-Values. If it is High-Values, then this data record is the first record into the Output Procedure. The Key fields from this data record are moved to the save fields.

Next the different levels that were defined for this report are checked. The levels are checked in a particular order. The highest level item is checked first.

Image

The order of control break checks really is important. Many programmers check the lowest level of break first. This is a common mistake. In this example, the lowest level of break is the item type. If a new record is read with a different date but the same item type, a problem could occur if the breaks are checked from the lowest level. There would be no break at the item type level, and the program would continue as if there were no control break, producing erroneous results.

Notice that if a break is detected at a high level, the lower level breaks are performed. They are performed from lowest level to highest level. This sequence allows the individual lines that make up the report for the data records prior to the current record to be printed. Each subtotal is executed and accumulated into the next higher level. Performing each subtotal under the break, in order from lowest to highest, accounts for all accumulated records.

000251 Check-For-Break. 000252 Evaluate True 000253 When Save-Dealer-Name = High-Values 000254 Move Sort-Key To Save-Fields 000255 When Dealer-Name Of Sort-Record Not = Save-Dealer-Name 000256 Perform Type-Break 000257 Perform Date-Break 000258 Perform Dealer-Break 000259 When Sort-Trans-Date Not = Save-Date-X 000260 Perform Type-Break 000261 Perform Date-Break 000262 When Sort-Trans-Type Not = Save-Type 000263 Perform Type-Break 000264 When Other 000265 Continue 000266 End-Evaluate After any required control break processing, the data for the lowest level is accumulated. This accumulation occurs any time a valid Input record is returned. The only special computation at the detail level in this example is that of expanding the total amount based on the quantity and the individual price.

000267 Perform Accumulate-Details 000268 . 000269 Accumulate-Details. 000270 Add Sort-Trans-Qty To Total-Qty Of Type-Totals 000271 Add Sort-Commission To Total-Commission Of Type-Totals 000272 Compute Total-Amt Of Type-Totals = 000273 Total-Amt Of Type-Totals + 000274 (Sort-Trans-Qty * Sort-Trans-Price) 000275 . When a break occurs, the prior subtotals are printed first. The subtotals from the previous records are then added to the next higher level.

Image

Using Add with Corresponding on the various subtotals helps to eliminate coding errors. Programmers have a good habit of copying programming statements from other areas of code. This coding shortcut can, however, lead to errors. Imagine that instead of using Add with Corresponding, the individual subtotals were added. Then the programmer copied this code for the logic for the next control break but failed to change one of the data names in the Add statements. The program would compile and run because all the data names are properly declared, but the results would be wrong. Using Add with Corresponding also eliminates the possibility of forgetting to add one of the many subtotals. It also makes future maintenance of the program easier. Suppose the report is modified to add another subtotal. All the programmer has to do is add the field to the four different Group Level subtotal items in Working-Storage. The control break logic need not change. Writing programs for future maintainability is the goal of any good programmer.

After the next level of subtotal is added, the Initialize verb resets the current level of subtotal fields to zero. The sequence of events works because the last data record returned has not yet had its values added to any subtotals. That step occurs after any control break processing.

The final step of any control break logic is to set the value of the save field, which is used in comparisons to check for control breaks, to the value of the newly returned record.

All control breaks perform along the same lines. They print their appropriate data lines, increment the next higher subtotal, initialize their own subtotals, and move the data value that defines the break into the save area.

000276 Type-Break. 000277 Perform Print-Type-Total 000278 Add Corresponding Type-Totals To Date-Totals 000279 Initialize Type-Totals 000280 Move Sort-Trans-Type To Save-Type 000281 . 000282 Date-Break. 000283 Perform Print-Date-Total 000284 Add Corresponding Date-Totals To Dealer-Totals 000285 Initialize Date-Totals 000286 Move Sort-Trans-Date To Save-Date-X 000287 . 000288 Dealer-Break. 000289 Perform Print-Dealer-Total 000290 Add Corresponding Dealer-Totals To Grand-Totals 000291 Initialize Dealer-Totals 000292 Move Dealer-Name Of Sort-Record To Save-Dealer-Name 000293 . In Print-Type-Total, the subtotal line is created and written to the printer. The line count is checked and the heading lines are printed if necessary. Notice the use of Move with Corresponding. This statement ensures that all subtotal fields are moved to the subtotal line.

000294 Print-Type-Total. 000295 Move Corresponding Type-Totals To Total-Line 000296 Move Save-Type To Desc-Type-Type 000297 Move Desc-Type To Total-Description 000298 If Line-Count > Max-Lines 000299 Perform Heading-Routine 000300 End-If 000301 Write Report-Record From Total-Line After 1 000302 Add 1 To Line-Count 000303 . The Print-Date-Total Paragraph works like the Print-Type-Total Paragraph with the exception of the extra print line printed before and after the total. The line count is checked against two less than the maximum number of lines to allow for the extra lines and to ensure that no page contains more than 60 lines—the value defined as the maximum number of print lines. The Blank-Line is used to print a blank line after the total line. This blank line is required because the very next print line could be one of the single-spaced type subtotals, and you do not want that line to appear without spacing immediately after the date subtotal.

000304 Print-Date-Total. 000305 Move Corresponding Date-Totals To Total-Line 000306 Move Corresponding Save-Date-X To Desc-Date 000307 Move Desc-Date To Total-Description 000308 If Line-Count > Max-Lines - 2

000309 Perform Heading-Routine 000310 End-If 000311 Write Report-Record From Total-Line After 2 000312 Write Report-Record From Blank-Line After 1 000313 Add 3 To Line-Count 000314 . The Print-Dealer-Total Paragraph must perform the additional task of formatting the name field for printing. The multiple String statements allow for a normalized name even in the absence of a middle name in the data record. If the middle name is missing and a single String statement constructs the name, two spaces—the space that follows the first name and the one that should follow the middle name—separate the first and last names. By checking the value of the middle name before issuing the String verb, you can avoid this problem. String-Pointer controls and contains the position used in the next String statement.

000315 Print-Dealer-Total. 000316 Move Corresponding Dealer-Totals To Total-Line 000317 Move Spaces To Desc-Dealer-Name 000318 Move 1 To String-Pointer 000319 String First-Name Of Save-Dealer-Name 000320 Delimited By Space 000321 Into Desc-Dealer-Name 000322 With Pointer String-Pointer 000323 End-String 000324 If Middle-Name Of Save-Dealer-Name 000325 > Spaces 000326 String “ “ Delimited By Size 000327 Middle-Name Of Save-Dealer-Name 000328 Delimited By Spaces 000329 Into Desc-Dealer-Name 000330 With Pointer String-Pointer 000331 End-String 000332 End-If 000333 String “ “ Delimited By Size 000334 Last-Name Of Save-Dealer-Name 000335 Delimited By Spaces 000336 Into Desc-Dealer-Name 000337 With Pointer String-Pointer 000338 End-String 000339 Move Desc-Dealer To Total-Description 000340 If Line-Count > Max-Lines - 1 000341 Perform Heading-Routine 000342 End-If 000343 Write Report-Record From Total-Line After 1 000344 Write Report-Record From Blank-Line After 1 000345 Add 2 To Line-Count 000346 . The Print-Grand-Totals Paragraph simply moves and prints the grand totals for the report.

000347 Print-Grand-Totals. 000348 Move Corresponding Grand-Totals To Total-Line 000349 Move “****Grand Totals” To Total-Description 000350 If Line-Count > Max-Lines - 1 000351 Perform Heading-Routine 000352 End-If 000353 Write Report-Record From Total-Line After 2 000354 . The Heading-Routine Paragraph is performed when the maximum line count is exceeded. The page counter is incremented. If this page is the first page of the report, a page eject is not coded. For all subsequent pages in the report, a new page is started for each heading.

The Fill-Initial-Headings Paragraph is performed at the beginning of the Output Procedure to fill in the date and time that the report is created.

000355 Heading-Routine. 000356 Add 1 To Page-Count 000357 Move Page-Count To Page-No 000358 If Page-Count = 1 000359 Write Report-Record From Heading-Line-1 After Zero 000360 Else 000361 Write Report-Record From Heading-Line-1 After Page 000362 End-If 000363 Write Report-Record From Heading-Line-2 After 1 000364 Write Report-Record From Heading-Line-3 After 1 000365 Write Report-Record From Heading-Line-4 After 2 000366 Write Report-Record From Blank-Line After 1 000367 Move 6 To Line-Count 000368 . 000369 Fill-Initial-Headings. 000370 Accept Work-Date From Date 000371 Accept Work-Time From Time 000372 Move Corresponding Work-Date-X To 000373 Heading-Line-2 000374 Move Corresponding Work-Time-X To 000375 Heading-Line-3 000376 . The first page of the printed output follows.

Created by: CHAPT20A Transaction Summary by Dealer Page 1 Created on: 08/23/98 At: 21:38:43

                           Qty         Amount        Commission

  • Total CRAF 8 $558.88 $55.89

** Total 01/02/1999 8 $558.88 $55.89

  • Total ANTI 3 555.11 $55.51
  • Total CRAF 2 $195.40 $19.54
  • Total MISC 1 $96.25 $9.63

** Total 04/30/1999 16 $846.76 $84.68

  • Total ANTI 16 $1,542.11 $154.21
  • Total CRAF 6 $587.43 $58.74
  • Total JEWL 9 $1,652.13 $165.21
  • Total MISC 7 $711.34 $71.13

** Total 10/12/1999 38 $4,493.01 $449.29

  • Total HOLI 6 $244.08 $24.41
  • Total JEWL 1 $89.93 $8.99

** Total 01/03/2000 7 $334.01 $33.40

**

  • Total **UNKNOWN** 69 $6,232.66 $623.26
  • Total ANTI 12 $1,320.72 $858.46
  • Total HOLI 1 $131.19 $85.27
  • Total MISC 5 $383.50 $249.28
  • Total XMAS 3 $145.71 $94.71

** Total 01/02/1999 21 $1,981.12 $1,287.72

  • Total ANTI 9 $577.17 $375.16
  • Total CRAF 2 $85.94 $55.86
  • Total JEWL 3 $464.37 $301.84
  • Total XMAS 9 $751.31 $488.35

** Total 04/30/1999 23 $1,878.79 $1,221.21

  • Total ANTI 6 $727.74 $473.03
  • Total CRAF 5 $999.20 $649.48
  • Total JEWL 1 $97.48 $63.36

** Total 10/12/1999 12 $1,824.42 $1,185.87

  • Total CRAF 8 $1,291.36 $839.38
  • Total XMAS 1 $33.37 $21.69

** Total 01/03/2000 9 $1,324.73 $861.07

  • Total MISC 13 $1,387.05 $901.58

** Total 02/07/2000 13 $1,387.05 $901.58

**

  • Total Doug Mitchell Berg 78 $8,396.11 $5,457.45

The final report produced by the program has multiple dealers per page. If your business keeps a separate file for each dealer, you must start a new page for each new dealer. The simple solution might seem to be to perform the heading routine after a dealer break. This solution is not a good one, though, because the dealer being processed might be the last dealer in the file and you will produce a report where the last page contains headings only. Instead, after the dealer break, Move 99 to the line count field to cause a page break when the next line is printed. The result is a clean, clear report.

Control breaks can be a confusing subject for programmers. If the reporting requirements are not properly analyzed before the program is written, or if the programmer has a poor understanding of control breaks, these programs can become convoluted and difficult to debug and maintain.

A program based on properly analyzed reporting requirements, with clear, concise control break logic, produces reliable and accurate results and, compared to a report where the logic is based on an improper or incomplete analysis, is much easier to maintain.

Summary In this hour, you learned the following:

• Control breaks occur when the criteria defining the subtotal structure of a report change.

• Control breaks are a normal part of everyday business reporting.

• Proper analysis of the reporting requirements is required up-front to create a reliable reporting program that uses control breaks.

• The Input data for a program that uses control breaks must be sorted in the same hierarchy as that of the control breaks. The Sort proceeds from the highest control break level to the lowest.

• One common mistake is the failure to properly process the first record in the Input file.

• Another common mistake is the failure to properly add the subtotal fields at each control break. Using Add with Corresponding can help to eliminate this problem.

• Occasionally, programmers fail to program for the required processing that must occur at the end of the Input file. When the end of the Input file is reached, every level of control break should be triggered. Each must be processed from lowest level to highest level.

• When a control break occurs at a particular level, all the breaks for the lower levels must be processed first. They must be processed from lowest level to highest.

Q&A Q What are some of the important things I need to remember when creating a control break program?

A The data must be sorted in sequence of the hierarchy of your control breaks. A subtotal area must be defined for each level of control break. Save fields must be defined in order to check for a new control break. The subtotal fields must be reset each time they are printed.

Q How often are programs requiring control breaks used in the business world?

A Nearly every report used in business requires the use of some level of control break. Many of these reports contain only subtotal data. Some combine detail and subtotal data on the same report.

Q What are some common mistakes made when writing a program that uses control breaks?

A Failure to process the first and/or last data records are the most common errors. Failure to properly add and then initialize the subtotal fields are also common errors.

Workshop To help reinforce your understanding of the material presented in this hour, refer to the section “Quiz and Exercise Questions and Answers” that can be found on the CD. This section contains quiz questions and exercises for you to complete, as well as the corresponding answers.

Fair Use Sources

COBOL: COBOL Fundamentals, COBOL Inventor - COBOL Language Designer: 1959 by Howard Bromberg, Norman Discount, Vernon Reeves, Jean E. Sammet, William Selden, Gertrude Tierney, with indirect influence from Grace Hopper, CODASYL, ANSI COBOL, ISO/IEC COBOL; Modern COBOL - Legacy COBOL, IBM COBOL, COBOL keywords, COBOL data structures - COBOL algorithms, COBOL syntax, Visual COBOL, COBOL on Windows, COBOL on Linux, COBOL on UNIX, COBOL on macOS, Mainframe COBOL, IBM i COBOL, IBM Mainframe DevOps, COBOL Standards, COBOL Paradigms (Imperative COBOL, Procedural COBOL, Object-Oriented COBOL - COBOL OOP, Functional COBOL), COBOL syntax, COBOL installation, COBOL containerization, COBOL configuration, COBOL compilers, COBOL IDEs, COBOL development tools, COBOL DevOps - COBOL SRE, COBOL data science - COBOL DataOps, COBOL machine learning, COBOL deep learning, COBOL concurrency, COBOL history, COBOL bibliography, COBOL glossary, COBOL topics, COBOL courses, COBOL Standard Library, COBOL libraries, COBOL frameworks, COBOL research, Grace Hopper, COBOL GitHub, Written in COBOL, COBOL popularity, COBOL Awesome list, COBOL Versions. (navbar_cobol)


© 1994 - 2024 Cloud Monk Losang Jinpa or Fair Use. Disclaimers

SYI LU SENG E MU CHYWE YE. NAN. WEI LA YE. WEI LA YE. SA WA HE.


sams_teach_yourself_cobol_in_24_hours_-_hour_20_advanced_reporting.txt · Last modified: 2024/04/28 03:37 by 127.0.0.1