CHAPTER 18

image

The COBOL Report Writer

This chapter introduces the COBOL Report Writer. In a series of increasingly complex programs, you learn how to use the Report Writer to create control-break-based report programs. By examining these programs, you are gradually introduced to the new verbs, clauses, sections and concepts of the Report Writer. You see how to use the RD entry in the REPORT SECTION to specify control-break items and define the basic layout of the page. The chapter explores report groups and how to create report groups linked to the control-break items specified in the report’s RD entry. You learn how to use the SUM clause for subtotaling and rolling forward. The final program introduces declaratives and how to use them to extend the capabilities of the Report Writer. Once you’ve seen the capabilities of the Report Writer through the example programs, the chapter explores the verbs, clauses, and concepts of the Report Writer more formally.

Declaratives can be used to extend the capabilities of the Report Writer, but you can also use them to define exception-handling procedures for files. The final section explains how to create declaratives for file error handling.

Report Writer

Producing reports is an important aspect of business programming. Nowadays, reports may consist of rows and columns of figures and be supported by summary information in the form of a variety of charts and graphs. In the past, reports consisted solely of printed figures. You’ve probably seen such reports in old films, where a management person is poring over page after page of green-lined, fan-fold computer printout.

Although producing reports is important, unfortunately the report programs produced using standard COBOL print files (see Chapter 8) are often tedious to code. Report programs are long, achieving correct placement of horizontal and vertical print items is laborious, and the programs frequently consist of repetitions of the tasks and techniques (such as control-break processing) used in other report programs. In recognition of the importance of reports in the business domain, and to simplify the task of writing report programs, COBOL provides the Report Writer.

Like indexed files, the COBOL Report Writer used to be one of the jewels in COBOL’s crown. But today, just as relational databases have eroded the importance of indexed files, so off-the-shelf packages such as Crystal Reports with its array of charts and graphs have put COBOL’s Report Writer in the shade. Nevertheless, although summary information in the form of charts and graphs is very useful, there is still a need for printed reports; and you can learn a lot from a close acquaintance with the Report Writer.

I start by showing you an example of a report produced by the Report Writer. Then, through a series of increasingly complex report programs, you learn how to create the program that produced that report. The final example program takes the complexity one stage further.

Example Report: Solace Solar Solutions

This report shows the sales made by agents selling solar power products in each of the 50 American states. You see the program specification and the report, and then I follow up with a discussion that highlights the report’s features. After discussing the report, I show you the PROCEDURE DIVISION code that produced the report.

Problem Specification

Solace Solar Solutions is a company that sells solar power products through its sales agents all over the United States. Sales agents are paid a base salary (which is different from state to state) and a commission of 8% on the value of the products they sell.

The monthly report shows the value of the individual sales and the total sales made by each Solace sales agent. The total sales made for the state and the base salary for the state are also shown. The report is printed on ascending sales agent number within ascending state name.

The report is based on a sequential sales file, which contains details of each sale made in the country. The sales file is ordered on ascending sales agent number within ascending state number. Each record of the sales file has the following description:

Table18-1.jpg

Example Report

The first page of the example report is shown in Example 18-1. For ease of reference, I have attached line numbers to the report.

Example 18-1. Solace Solar Solutions Example Report: First Page

01                       Solace Solar Solutions
02         Sales Agent - Sales and Salary Report Monthly Report
03
04     State         Agent           Value
05     Name          Number         Of Sales
06    Alabama          38           $9,325.14
07                                 $11,839.19
08                                 $19,102.61
09                  Sales for sales agent  38   =   $40,266.94
10
11
12    Alabama          73           $4,503.71
13                                 $11,659.87
14                                 $19,540.19
15                  Sales for sales agent  73   =   $35,703.77
16
17                  Total sales for Alabama         $75,970.71
18                  Base salary for Alabama          $1,149.00
19    ----------------------------------------------------------
20
21
22    Alaska           55          $18,981.84
23                                  $3,065.97
24                                 $10,686.92
25                  Sales for sales agent  55   =   $32,734.73
26
27
28    Alaska           89          $11,187.72
29                                 $14,145.82
30                  Sales for sales agent  89   =   $25,333.54
31
32                                                                    
33    Alaska          104          $18,005.42
34                                 $17,614.20
35                  Sales for sales agent 104   =   $35,619.62
36
37                  Total sales for Alaska          $93,687.89
38                  Base salary for Alaska           $1,536.00
39    ----------------------------------------------------------
40
41
42    Arizona          23           $4,237.72
43
44
45
46
47
48
49    Programmer - Michael Coughlan                         Page :   1

Report Writer Tasks

To get a feel for what the Report Writer can do, let’s examine in some detail what it has to do to produce this report:

  • Print the report heading lines (lines 01–02). These are printed, once only, at the beginning of the report.
  • Print the subject heading lines (page headings). These are printed at the top of each page—on lines 04–05 on the first page and lines 01–02 on subsequent pages.
  • Print a footer at the bottom of each page (showing the name of the programmer and a page number: line 49). To print the page number, the Report Writer must keep a page count.
  • Keep a line count, and change the page when the count is greater than 42 (unless the next thing to print is a sales agent total line, a state total line, a base salary line, or the final total line).
  • Print the details of a sales agent’s sales (for example, as shown for sales agent 38 on lines 06–08). Because the sales file only contains a state number, the Report Writer must get the state name from a lookup table.
  • Suppress the sales agent number and state name after their first occurrence (but restore them if there is a change of page, sales agent, or state name: see lines 06, 12, 22, 28, 33, 42).
  • When the sales agent number changes, print the total sales accumulated for the sales agent (lines 15, 25, 35)
  • When the state number changes, print the total sales accumulated for the state (lines 17, 37).
  • When the state number changes, get the base salary for the state from a lookup table, and print it (lines 18, 38).
  • When the state number changes, print a line of hyphens to separate this state from the next (lines 19, 39).

Accumulate all the sales values, and print them as a final total at the end of the report (not shown on the example page).

Report Writer PROCEDURE DIVISION

If you had to create the Solace Solar Solutions sales report using the approach shown in Chapter 8 (that is, using a control-break program and the WRITE verb), you would probably write a program that had a PROCEDURE DIVISION with more than 100 lines of code. It is interesting to discover that the Report Writer can do all this work in just the 10 COBOL statements shown in Example 18-2.

Example 18-2. PROCEDURE DIVISION That Produces the Sales Report

PROCEDURE DIVISION.
Begin.
    OPEN INPUT SalesFile.
    OPEN OUTPUT PrintFile.
    READ SalesFile
         AT END SET EndOfFile TO TRUE
    END-READ.
    INITIATE SolaceSalesReport.
    PERFORM PrintSalaryReport
            UNTIL EndOfFile.
    TERMINATE SolaceSalesReport.
    CLOSE SalesFile, PrintFile.
    STOP RUN.
 
PrintSalaryReport.
    GENERATE DetailLine.
    READ SalesFile
          AT END SET EndOfFile TO TRUE
    END-READ.

So Much Work, So Little Code

How can so much work be done in so little PROCEDURE DIVISION code? How does the Report Writer know that page headings or page footers are required? If you wrote a program to print this report using WRITE statements, you would need a control-break program with a PERFORM UNTIL StateNum NOT EQUAL TO PrevStateNum loop to process each state and an inner loop PERFORM UNTIL SalesAgentNum NOT EQUAL TO PrevSalesAgentNum to process the sales for each sales agent. Without those loops, how does the Report Writer know it is time to print the sales agent totals or the state totals, and how does it accumulate those totals in the first place?

To achieve so much in so little PROCEDURE DIVISION code, the Report Writer uses a declarative approach to programming rather than the imperative (procedural) approach familiar to most programmers. In imperative programming, you tell the computer how to do what you want done. In declarative programming, you tell the computer what you would like done, and the computer works out how to do it. When you use the Report Writer, you declare what to print when a page heading, page footer, sales agent total, state total, or final total is required, and the Report Writer works out when to print these items. In keeping with the adage that “there is no such thing as a free lunch,” the PROCEDURE DIVISION of a Report Writer program is short because most of the work is done in the (greatly expanded) DATA DIVISION.

How the Report Writer Works

The Report Writer works by recognizing that many reports take (more or less) the same shape. There may be headings at the beginning of the report and footers at the end. There may be headings at the top of each page and footers at the bottom. Headings or footers may need to be printed whenever there is a control break (that is, when the value in a specified field changes, such as when the sales agent number or state number changes in Example 18-1). In addition, the detail lines that display the information summarized in control-break totals also need to be printed.

The Report Writer calls these different report items report groups. Reports are organized around report groups. The Report Writer recognizes the seven types of report group shown in Example 18-3; the indentation shows their relative importance/order of execution.

Example 18-3. Report Group Types

REPORT HEADING or RH group
- printed once at the beginning of the report
    PAGE HEADING or PH group
    - printed at the top of each page
        CONTROL HEADING or CH group
        - printed at the beginning of each control break
            DETAIL or DE group
            - printed each time the GENERATE statement is executed
        CONTROL FOOTING or CF group
        - printed at the end of each control break
    PAGE FOOTING or PF group
    - printed at the bottom of each page
REPORT FOOTING or RF group
- printed once at the end of the report.

For each report, there must be a Report Description (RD) entry in the REPORT SECTION of the DATA DIVISION that fully describes the report. The report groups that describe the report are defined as records in the RD entries. Most groups are defined once for each report, but control groups are defined for each control-break item. For instance, in the example program, control footings are defined on SalesAgentNum, StateNum, and FINAL. FINAL is a special control group that is invoked before or after the normal control groups (before if CONTROL HEADING FINAL is used, and after if CONTROL FOOTING FINAL is used).

Ordinary control groups are defined on a control-break data item. The Report Writer monitors the contents of the designated data item, and when the value changes, a control break is automatically initiated. When the control break is initiated, the CONTROL FOOTING group of the breaking item (if there is one) and the CONTROL HEADING group of the next item are printed.

Writing a report program consists of a number of tedious tasks such as keeping track of the line count to ensure that page headings or footers are printed when required, or simply moving data values into their corresponding items in the print line. In addition, when you write a report according to a program specification, you often have to adhere to the report layout specified in a print layout form such as that shown in Figure 18-1. When you have to adhere to such a form, it can be tricky to get the vertical and horizontal placement of printed items correct. Counting characters to figure out what size to make each of the fields that define a print line is tedious and time consuming.

9781430262534_Fig18-01.jpg

Figure 18-1. Print layout form showing the layout required for a report

The Report Writer makes it easier to write report programs by

  • Allowing simple vertical and horizontal placement of printed items using the LINE IS and COLUMN IS phrases in the data declaration
  • Automatically moving data values to output items using the SOURCE phrase
  • Keeping a line count, and automatically generating report and page headers and footers at the appropriate times
  • Keeping a page count that can be referenced in the report declaration
  • Recognizing control breaks, and automatically generating the appropriate control headings and footers
  • Automatically accumulating totals, subtotals, and final totals

Writing a Report Program

Let’s see how to write a report program using the Report Writer. I start with a simplified version of the program that produced the report in Example 18-1. Succeeding examples add to it to demonstrate additional Report Writer facilities. The final example demonstrates even more than the report in Example 18-1.

Modifying the Specification

This first example program creates a report program that does the following:

  • Prints a report heading
  • Prints a heading and a footer on each page
  • For each sale record, prints the state name (obtained from a table), the sales agent number, and the value of the sale
  • Prints the total value of the sales made by each sales agent
  • Prints a line of hyphens at the end of each state to separate the states from one another

The first page of the report produced by this program is shown in Example 18-4 (line numbers have been added). The program that produces the report is shown in Listing 18-1.

Example 18-4. Simplified Version of the Report Showing Only Sales Agent Totals

01                       Solace Solar Solutions
02         Sales Agent - Sales and Salary Report Monthly Report
03
04     State         Agent           Value
05     Name          Number         Of Sales
06    Alabama          38           $9,325.14
07    Alabama          38          $11,839.19
08    Alabama          38          $19,102.61
09                  Sales for sales agent  38   =   $40,266.94
10
11
12    Alabama          73           $4,503.71
13    Alabama          73          $11,659.87
14    Alabama          73          $19,540.19
15                  Sales for sales agent  73   =   $35,703.77
16    ----------------------------------------------------------
17
18
19    Alaska           55          $18,981.84
20    Alaska           55           $3,065.97
21    Alaska           55          $10,686.92
22                  Sales for sales agent  55   =   $32,734.73
23
24
25    Alaska           89          $11,187.72
26    Alaska           89          $14,145.82
27                  Sales for sales agent  89   =   $25,333.54
28
29
30    Alaska          104          $18,005.42
31    Alaska          104          $17,614.20
32                  Sales for sales agent 104   =   $35,619.62
33    ----------------------------------------------------------
34
35
36    Arizona          23           $4,237.72
37    Arizona          23          $13,315.00
38                  Sales for sales agent  23   =   $17,552.72
39
40
41    Arizona          90           $2,078.93
42    Arizona          90          $17,228.88
43    Arizona          90           $8,929.96
44                  Sales for sales agent  90   =   $28,237.77
45    ----------------------------------------------------------
46
47
48
49    Programmer - Michael Coughlan                         Page :   1

Listing 18-1. Simplified Report Program

IDENTIFICATION DIVISION.
PROGRAM-ID.  Listing18-1.
AUTHOR.  Michael Coughlan.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT SalesFile ASSIGN TO "Listing18-1-Sales.DAT"
           ORGANIZATION IS LINE SEQUENTIAL.
    SELECT PrintFile ASSIGN TO "Listing18-1.Rpt".
 
DATA DIVISION.
FILE SECTION.
FD  SalesFile.
01  SalesRecord.
    88 EndOfFile  VALUE HIGH-VALUES.
    02 StateNum         PIC 99.
    02 SalesAgentNum    PIC 999.
    02 ValueOfSale      PIC 9(5)V99.
 
FD  PrintFile
    REPORT IS SolaceSalesReport.
 
WORKING-STORAGE SECTION.
01  StateNameTable.
    02 StateNameValues.
       03 FILLER  PIC X(14) VALUE "Alabama".
       03 FILLER  PIC X(14) VALUE "Alaska".
       03 FILLER  PIC X(14) VALUE "Arizona".
       03 FILLER  PIC X(14) VALUE "Arkansas".
       03 FILLER  PIC X(14) VALUE "California".
       03 FILLER  PIC X(14) VALUE "Colorado".
       03 FILLER  PIC X(14) VALUE "Connecticut".
       03 FILLER  PIC X(14) VALUE "Delaware".
       03 FILLER  PIC X(14) VALUE "Florida".
       03 FILLER  PIC X(14) VALUE "Georgia".
       03 FILLER  PIC X(14) VALUE "Hawaii".
       03 FILLER  PIC X(14) VALUE "Idaho".
       03 FILLER  PIC X(14) VALUE "Illinois".
       03 FILLER  PIC X(14) VALUE "Indiana".
       03 FILLER  PIC X(14) VALUE "Iowa".
       03 FILLER  PIC X(14) VALUE "Kansas".
       03 FILLER  PIC X(14) VALUE "Kentucky".
       03 FILLER  PIC X(14) VALUE "Louisiana".
       03 FILLER  PIC X(14) VALUE "Maine".
       03 FILLER  PIC X(14) VALUE "Maryland".
       03 FILLER  PIC X(14) VALUE "Massachusetts".
       03 FILLER  PIC X(14) VALUE "Michigan".
       03 FILLER  PIC X(14) VALUE "Minnesota".
       03 FILLER  PIC X(14) VALUE "Mississippi".
       03 FILLER  PIC X(14) VALUE "Missouri".
       03 FILLER  PIC X(14) VALUE "Montana".
       03 FILLER  PIC X(14) VALUE "Nebraska".
       03 FILLER  PIC X(14) VALUE "Nevada".
       03 FILLER  PIC X(14) VALUE "New Hampshire".
       03 FILLER  PIC X(14) VALUE "New Jersey".
       03 FILLER  PIC X(14) VALUE "New Mexico".
       03 FILLER  PIC X(14) VALUE "New York".
       03 FILLER  PIC X(14) VALUE "North Carolina".
       03 FILLER  PIC X(14) VALUE "North Dakota".
       03 FILLER  PIC X(14) VALUE "Ohio".
       03 FILLER  PIC X(14) VALUE "Oklahoma".
       03 FILLER  PIC X(14) VALUE "Oregon".
       03 FILLER  PIC X(14) VALUE "Pennsylvania".
       03 FILLER  PIC X(14) VALUE "Rhode Island".
       03 FILLER  PIC X(14) VALUE "South Carolina".
       03 FILLER  PIC X(14) VALUE "South Dakota".
       03 FILLER  PIC X(14) VALUE "Tennessee".
       03 FILLER  PIC X(14) VALUE "Texas".
       03 FILLER  PIC X(14) VALUE "Utah".
       03 FILLER  PIC X(14) VALUE "Vermont".
       03 FILLER  PIC X(14) VALUE "Virginia".
       03 FILLER  PIC X(14) VALUE "Washington".
       03 FILLER  PIC X(14) VALUE "West Virginia".
       03 FILLER  PIC X(14) VALUE "Wisconsin".
       03 FILLER  PIC X(14) VALUE "Wyoming".
02 FILLER REDEFINES StateNameValues.
       03 State OCCURS 50 TIMES.
          04 StateName   PIC X(14).
 
REPORT SECTION.
RD  SolaceSalesReport
    CONTROLS ARE StateNum
                 SalesAgentNum
    PAGE LIMIT IS 54
    FIRST DETAIL 3
    LAST DETAIL 46
    FOOTING 48.
 
01  TYPE IS REPORT HEADING NEXT GROUP PlUS 1.
    02 LINE 1.
       03 COLUMN 20     PIC X(32)
                        VALUE "Solace Solar Solutions".
 
    02 LINE 2.
       03 COLUMN 6      PIC X(51)
          VALUE "Sales Agent - Sales and Salary Report Monthly Report".
 
01  TYPE IS PAGE HEADING.
    02 LINE IS PLUS 1.
       03 COLUMN 2      PIC X(5)  VALUE "State".
       03 COLUMN 16     PIC X(5)  VALUE "Agent".
       03 COLUMN 32     PIC X(8)  VALUE "Value".
 
    02 LINE IS PLUS 1.
       03 COLUMN 2      PIC X(4)  VALUE "Name".
       03 COLUMN 16     PIC X(6)  VALUE "Number".
       03 COLUMN 31     PIC X(8)  VALUE "Of Sales".
 
01  DetailLine TYPE IS DETAIL.
    02 LINE IS PLUS 1.
       03 COLUMN 1      PIC X(14)
                        SOURCE StateName(StateNum).
       03 COLUMN 17     PIC ZZ9
                        SOURCE SalesAgentNum.
       03 COLUMN 30     PIC $$$,$$$.99 SOURCE ValueOfSale.
 
01  SalesAgentGrp
    TYPE IS CONTROL FOOTING SalesAgentNum  NEXT GROUP PLUS 2.
    02 LINE IS PLUS 1.
       03 COLUMN 15     PIC X(21) VALUE "Sales for sales agent".
       03 COLUMN 37     PIC ZZ9 SOURCE SalesAgentNum.
       03 COLUMN 43     PIC X VALUE "=".
       03 TotalAgentSales COLUMN 45 PIC $$$$$,$$$.99 SUM ValueOfSale.
 
01  StateGrp TYPE IS CONTROL FOOTING StateNum NEXT GROUP PLUS 2.
    02 LINE IS PLUS 1.
       03 COLUMN 1      PIC X(58) VALUE ALL "-".
 
01  TYPE IS PAGE FOOTING.
    02 LINE IS 49.
       03 COLUMN 1      PIC X(29) VALUE "Programmer - Michael Coughlan".
       03 COLUMN 55     PIC X(6) VALUE "Page :".
       03 COLUMN 62     PIC ZZ9 SOURCE PAGE-COUNTER.
 
PROCEDURE DIVISION.
Begin.
    OPEN INPUT SalesFile.
    OPEN OUTPUT PrintFile.
    READ SalesFile
         AT END SET EndOfFile TO TRUE
    END-READ.
    INITIATE SolaceSalesReport.
    PERFORM PrintSalaryReport
            UNTIL EndOfFile.
    TERMINATE SolaceSalesReport.
    CLOSE SalesFile, PrintFile.
    STOP RUN.
 
PrintSalaryReport.
    GENERATE DetailLine.
    READ SalesFile
          AT END SET EndOfFile TO TRUE
    END-READ.

The first thing to note is that the PROCEDURE DIVISION for this program is the same as for the program that produced the report in Example 18-1. This is your first indication that most of the work is being done in the DATA DIVISION. As I add complexity to the program in the succeeding examples, eventually I have to make some changes to the PROCEDURE DIVISION code.

The second thing to note is that just like an ordinary print file, a Report Writer file must have a SELECT and ASSIGN clause in the ENVIRONMENT DIVISION and an FD entry in the DATA DIVISION. But look at the FD entry. Instead of a record description, you have a REPORT IS SolaceSalesReport entry. This entry tells you that the Report Writer is being used and that this particular report is called SolaceSalesReport. This entry links the PrintFile with the report described in the REPORT SECTION. That is the next thing to note; when you use the Report Writer, you describe the report in the REPORT SECTION.

The first entry in the REPORT SECTION is the RD entry, which is followed by the name of the report. This is the same name you use in the REPORT IS entry in the FD entry of the PrintFile. The RD entry has a number of clauses. The first is the CONTROLS ARE clause, which allows you to identify the control-break item(s) that the Report Writer must monitor in order to detect a control break. These entries usually identify fields in an input file, but they don’t have to. The remaining RD clauses specify information about the page, such as the size of the page, the first line where a detail line may be printed, and the line after which the footer may be printed.

The remaining entries identify the required report groups. Each report group is a record and must start with a 01 level number. As noted in Example 18-3, there are seven possible types of report groups, and the first entry in the report group must specify the type of the group. Listing 18-1 has the following report groups:

  • A REPORT HEADING group that specifies what is to be printed at the start of the report.
  • A PAGE HEADING group that specifies what is to be printed at the top of each page.
  • A DETAIL groupthat specifies what is to be printed for each sales record.
  • CONTROL FOOTING groups for the SalesAgentNum control-break item and the StateNum control-break item. These groups specify what is printed when a control break occurs on SalesAgentNum or StateNum.
  • A PAGE FOOTING group that specifies what is to be printed at the bottom of each page.

Report Groups

Let’s look at some of the entries in these report groups in more detail. The REPORT HEADING group is of interest because it demonstrates absolute position using the LINE clause. It also demonstrates the COLUMN clause, which you use to specify the horizontal placement of the material to be printed. The final item of interest in this group is the NEXT GROUP PLUS clause, which specifies that the next group will start one line down from this group. Although, as you see with the PAGE HEADING group, you can specify vertical placement using a relative reference rather than an absolute line number, that is not always sufficient for all your positioning needs. Sometimes you require a combination of the NEXT GROUP PLUS and the LINE IS PLUS clauses.

You might think that the PAGE HEADING group would also use absolute positioning, but in this example, the page headings are not printed on the same line on every page. On the first page, they are printed after the report heading lines; but on the other pages, they are printed on the first line. For this reason, LINE IS PLUS relative positioning is used for this group. Because the other groups, except the PAGE FOOTING group, are also printed on different lines on the page, they also use LINE IS PLUS relative positioning.

The main clause of interest in the DETAIL report group is the SOURCE clause. This clause specifies that the data for this print item is to come from some source data item. This is how the Report Writer gets values for the state name (from the table), the sales agent number, and the value of the sale.

SalesAgentGrp is a CONTROL FOOTING group. It is printed whenever there is a control break on SalesAgentNum. When you create a CONTROL group, you have to associate the group with a control item mentioned in the RD..CONTROLS ARE phrase. This is how the Report Write associates a particular control-break item with a CONTROL HEADING or FOOTING group. At the moment, this group only prints a line of hyphens; but the next program uses it to accumulate and print the total sales agent sales.

The final group to consider is the PAGE FOOTING group. The item of interest in this group is PAGE-COUNTER, which is identified as the source of the page number printed in this footer. PAGE-COUNTER is a special Report Writer register that automatically keeps a count of the pages printed.

PROCEDURE DIVISION Notes

Now that you have seen the role played by the DATA DIVISIONentries in producing the report, you need to know how the report is driven from the PROCEDURE DIVISION. The Report Writer introduces three new verbs: INITIATE, GENERATE, and TERMINATE.

When the INITIATE verb is executed, all the heading groups, such as REPORT HEADING and the first PAGE HEADING, are produced. All the system registers, such as PAGE-COUNTER, are set to their starting values.

When the TERMINATE verb is executed, all the relevant FOOTING groups, such as REPORT FOOTING and the last PAGE FOOTING, are produced.

The report is driven by the GENERATE verb. GENERATE is normally associated either with the DETAIL group (as it is in this example) or with the report name. When GENERATE is associated with a DETAIL group, each time the GENERATE statement is executed, the DETAIL group is printed. Obviously this makes sense only if each time GENERATE executes, the DETAIL group is fed new data. In this program, the new data is provided by reading the sales file.

Adding Features to the Report Program

Let’s add some features to the Solace Sales Report program. Let’s change the program so that the report now shows the total sales for the sales agent, total sales for the state, and a final total for the country. The report should also show the base salary paid to sales agents in each state. To do this, the state table has to be modified to include the salary information. One final thing needs to change. If you look at the report in Example 18-4, you see that each line that prints a sales value also prints the state name and the sales agent number. This looks unsightly. The state name and the sales agent number should be suppressed after their first occurrence. Instead of this

04     State         Agent           Value
05     Name          Number         Of Sales
06    Alabama          38           $9,325.14
07    Alabama          38          $11,839.19
08    Alabama          38          $19,102.61
09                  Sales for sales agent  38   =   $40,266.94
the report should print this:
04     State         Agent           Value
05     Name          Number         Of Sales
06    Alabama          38           $9,325.14
07                                 $11,839.19
08                                 $19,102.61
09                  Sales for sales agent  38   =   $40,266.94

You probably have realized by now that these specification changes are satisfied by the report shown in Example 18-1. Listing 18-2 is the program that produced that report.

Listing 18-2. Program to Create a Report with Sales Totals

IDENTIFICATION DIVISION.
PROGRAM-ID.  Listing18-2.
AUTHOR.  Michael Coughlan.
 
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT SalesFile ASSIGN TO "Listing18-2-Sales.DAT"
           ORGANIZATION IS LINE SEQUENTIAL.
            
    SELECT PrintFile ASSIGN TO "Listing18-2.Rpt".
 
DATA DIVISION.
FILE SECTION.
FD  SalesFile.
01  SalesRecord.
    88 EndOfFile  VALUE HIGH-VALUES.
    02 StateNum         PIC 99.
    02 SalesAgentNum    PIC 999.
    02 ValueOfSale      PIC 9(5)V99.
 
FD  PrintFile
    REPORT IS SolaceSalesReport.
 
WORKING-STORAGE SECTION.
01  StateNameTable.
    02 StateNameValues.
       03 FILLER  PIC X(18) VALUE "1149Alabama".
       03 FILLER  PIC X(18) VALUE "1536Alaska".
       03 FILLER  PIC X(18) VALUE "1284Arizona".
       03 FILLER  PIC X(18) VALUE "1064Arkansas".
       03 FILLER  PIC X(18) VALUE "1459California".
       03 FILLER  PIC X(18) VALUE "1508Colorado".
       03 FILLER  PIC X(18) VALUE "1742Connecticut".
       03 FILLER  PIC X(18) VALUE "1450Delaware".
       03 FILLER  PIC X(18) VALUE "1328Florida".
       03 FILLER  PIC X(18) VALUE "1257Georgia".
       03 FILLER  PIC X(18) VALUE "1444Hawaii".
       03 FILLER  PIC X(18) VALUE "1126Idaho".
       03 FILLER  PIC X(18) VALUE "1439Illinois".
       03 FILLER  PIC X(18) VALUE "1203Indiana".
       03 FILLER  PIC X(18) VALUE "1267Iowa".
       03 FILLER  PIC X(18) VALUE "1295Kansas".
       03 FILLER  PIC X(18) VALUE "1126Kentucky".
       03 FILLER  PIC X(18) VALUE "1155Louisiana".
       03 FILLER  PIC X(18) VALUE "1269Maine".
       03 FILLER  PIC X(18) VALUE "1839Maryland".
       03 FILLER  PIC X(18) VALUE "1698Massachusetts".
       03 FILLER  PIC X(18) VALUE "1257Michigan".
       03 FILLER  PIC X(18) VALUE "1479Minnesota".
       03 FILLER  PIC X(18) VALUE "0999Mississippi".
       03 FILLER  PIC X(18) VALUE "1236Missouri".
       03 FILLER  PIC X(18) VALUE "1192Montana".
       03 FILLER  PIC X(18) VALUE "1261Nebraska".
       03 FILLER  PIC X(18) VALUE "1379Nevada".
       03 FILLER  PIC X(18) VALUE "1571New Hampshire".
       03 FILLER  PIC X(18) VALUE "1743New Jersey".
       03 FILLER  PIC X(18) VALUE "1148New Mexico".
       03 FILLER  PIC X(18) VALUE "1547New York".
       03 FILLER  PIC X(18) VALUE "1237North Carolina".
       03 FILLER  PIC X(18) VALUE "1290North Dakota".
       03 FILLER  PIC X(18) VALUE "1256Ohio".
       03 FILLER  PIC X(18) VALUE "1155Oklahoma".
       03 FILLER  PIC X(18) VALUE "1309Oregon".
       03 FILLER  PIC X(18) VALUE "1352Pennsylvania".
       03 FILLER  PIC X(18) VALUE "1435Rhode Island".
       03 FILLER  PIC X(18) VALUE "1172South Carolina".
       03 FILLER  PIC X(18) VALUE "1206South Dakota".
       03 FILLER  PIC X(18) VALUE "1186Tennessee".
       03 FILLER  PIC X(18) VALUE "1244Texas".
       03 FILLER  PIC X(18) VALUE "1157Utah".
       03 FILLER  PIC X(18) VALUE "1374Vermont".
       03 FILLER  PIC X(18) VALUE "1607Virginia".
       03 FILLER  PIC X(18) VALUE "1487Washington".
       03 FILLER  PIC X(18) VALUE "1062West Virginia".
       03 FILLER  PIC X(18) VALUE "1393Wisconsin".
       03 FILLER  PIC X(18) VALUE "1393Wyoming".
02 FILLER REDEFINES StateNameValues.
       03 State OCCURS 50 TIMES.
          04 BaseSalary  PIC 9(4).
          04 StateName   PIC X(14).
 
REPORT SECTION..
RD  SolaceSalesReport
    CONTROLS AREFINAL
                 StateNum
                 SalesAgentNum
    PAGE LIMIT IS 54
    FIRST DETAIL 3
    LAST DETAIL 42
    FOOTING 48.
 
01  TYPE IS REPORT HEADING NEXT GROUP PlUS 1.
    02 LINE 1.
       03 COLUMN 20     PIC X(32)
                        VALUE "Solace Solar Solutions".
 
    02 LINE 2.
       03 COLUMN 6      PIC X(51)
          VALUE "Sales Agent - Sales and Salary Report Monthly Report".
      
01  TYPE IS PAGE HEADING.
    02 LINE IS PLUS 1.
       03 COLUMN 2      PIC X(5)  VALUE "State".
       03 COLUMN 16     PIC X(5)  VALUE "Agent".
       03 COLUMN 32     PIC X(8)  VALUE "Value".
 
    02 LINE IS PLUS 1.
       03 COLUMN 2      PIC X(4)  VALUE "Name".
       03 COLUMN 16     PIC X(6)  VALUE "Number".
       03 COLUMN 31     PIC X(8)  VALUE "Of Sales".
 
01  DetailLine TYPE IS DETAIL.
    02 LINE IS PLUS 1.
       03 COLUMN 1      PIC X(14)
                        SOURCE StateName(StateNum)GROUP INDICATE.
       03 COLUMN 17     PIC ZZ9
                        SOURCE SalesAgentNum  GROUP INDICATE.
       03 COLUMN 30     PIC $$$,$$$.99 SOURCE ValueOfSale.
        
 
01  SalesAgentGrp
    TYPE IS CONTROL FOOTING SalesAgentNum  NEXT GROUP PLUS 2.
    02 LINE IS PLUS 1.
       03 COLUMN 15     PIC X(21) VALUE "Sales for sales agent".
       03 COLUMN 37     PIC ZZ9 SOURCE SalesAgentNum.
       03 COLUMN 43     PIC X VALUE "=".
       03 TotalAgentSales COLUMN 45 PIC $$$$$,$$$.99 SUM ValueOfSale.
 
01  StateGrp TYPE IS CONTROL FOOTING StateNum NEXT GROUP PLUS 2.
    02 LINE IS PLUS 2.
       03 COLUMN 15     PIC X(15) VALUE "Total sales for".
       03 COLUMN 31     PIC X(14) SOURCE StateName(StateNum).
       03 TotalStateSales COLUMN 45  PIC $$$$$,$$$.99 SUM TotalAgentSales.
        
    02 LINE IS PLUS 1.
       03 COLUMN 15     PIC X(15) VALUE "Base salary for".
       03 COLUMN 31     PIC X(14) SOURCE StateName(StateNum).
       03 COLUMN 48     PIC $$,$$$.99 SOURCE BaseSalary(StateNum).
    02 LINE IS PLUS 1.
       03 COLUMN 1      PIC X(58) VALUE ALL "-".
 
01  TotalSalesGrp TYPE IS CONTROL FOOTING FINAL.
    02 LINE IS PLUS 2.
       03 COLUMN 15     PIC X(11)
                        VALUE "Total sales".
       03 COLUMN 46     PIC X VALUE "=".
       03 COLUMN 48     PIC $$,$$$,$$$.99 SUM TotalStateSales.
 
01  TYPE IS PAGE FOOTING.
    02 LINE IS 49.
       03 COLUMN 1      PIC X(29) VALUE "Programmer - Michael Coughlan".
       03 COLUMN 55     PIC X(6) VALUE "Page :".
       03 COLUMN 62     PIC ZZ9 SOURCE PAGE-COUNTER.
 
PROCEDURE DIVISION.
Begin.
    OPEN INPUT SalesFile.
    OPEN OUTPUT PrintFile.
    READ SalesFile
         AT END SET EndOfFile TO TRUE
    END-READ.
    INITIATE SolaceSalesReport.
    PERFORM PrintSalaryReport
            UNTIL EndOfFile.
    TERMINATE SolaceSalesReport.
    CLOSE SalesFile, PrintFile.
    STOP RUN.
 
PrintSalaryReport.
    GENERATE DetailLine.
    READ SalesFile
          AT END SET EndOfFile TO TRUE
    END-READ.

Let’s look at the changes. The major differences between Listing 18-1 and Listing 18-2 are shown in bold. The PROCEDURE DIVISION has not changed. But there is a new control group: in order to print the final total for the country, a CONTROL FOOTING group is required. This control group is controlled by a special control item called FINAL. Note that now the CONTROLS ARE phrase in the report’s RD contains the word FINAL. The FINAL control-break item activates when the report is terminated. You should also take note of the order of the control-break items in the CONTROLS ARE phrase. FINAL is the major control break, StateNum is next in importance, and SalesAgentNum is the least important. A break on a major control item causes a break on all the subordinate control items.

If you examine the report in Example 18-5, you’ll see that now StateName and SalesAgentNum are suppressed after their first occurrence. This is done by specifying the GROUP INDICATE clause for the data item.

Another change to the program was required to accumulate and print the total sales for the sales agent. The Report Writer has three ways of incrementing totals: subtotaling, rolling forward, and crossfooting. All these methods use the SUM clause but target different types of data item. Subtotaling targets data items in the FILE SECTION or the WORKING-STORAGE SECTION. Rolling forward targets data items in a subordinate CONTROL FOOTING group. Crossfooting targets data items in the same group. This example uses subtotaling and rolling forward.

Subtotaling is used in SalesAgentGrp to sum the sales made by the agent. A SUM clause is used that targets the ValueOfSale data item so that every time a GENERATE statement is executed, the current value of ValueOfSale is added to a sum counter. When the control break occurs, the CONTROL FOOTING group activates, and the value accumulated in the sum counter is printed.

There is something else here that you note. As you have no doubt noticed, in the REPORT SECTION you don’t have to follow a level number with a data-item name or even the word FILLER. This saves a lot of unnecessary work. But you can include a name if you want to. In the SalesAgentGrp, I have included the name TotalAgentSales. The reason for naming this item is shown in the StateGrp CONTROL FOOTING group, where it is used as the target of the SUM clause. Every time there is a control break on SalesAgentNum, the current value of TotalAgentSales is added to the sum counter in StateGrp. When there is a control break on StateNum, the accumulated value of the sum counter is printed. This is an example of rolling forward.

Rolling forward is also used with TotalStateSales in StateGrp. TotalStateSales is used as the target of the SUM clause in TotalSalesGrp to sum each state total into a final total. When the TERMINATE statement is executed, the final total is printed.

Adding More Features to the Report Program

In the specification at the start of this section, I mentioned that Solace sales agents are paid a base salary and a commission of 8% on the value of the products they sell. In Listing 18-3, each time the total sales for an agent are printed, the commission they have earned and their total salary (base salary + commission) should also be printed. The first page of the report produced by Listing 18-3 is shown in Example 18-5.

Listing 18-3. Adding the Sales Agent Commission and Salary to the Report

IDENTIFICATION DIVISION.
PROGRAM-ID.  Listing18-3.
AUTHOR.  Michael Coughlan.
 
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT SalesFile ASSIGN TO "Listing18-3-Sales.DAT"
           ORGANIZATION IS LINE SEQUENTIAL.
            
    SELECT PrintFile ASSIGN TO "Listing18-3.Rpt".
 
DATA DIVISION.
FILE SECTION.
FD  SalesFile.
01  SalesRecord.
    88 EndOfFile  VALUE HIGH-VALUES.
    02 StateNum         PIC 99.
    02 SalesAgentNum    PIC 999.
    02 ValueOfSale      PIC 9(5)V99.
 
FD  PrintFile
    REPORT IS SolaceSalesReport.
 
WORKING-STORAGE SECTION.
01  StateNameTable.
0    02 StateNameValues.
       03 FILLER  PIC X(18) VALUE "1149Alabama".
       03 FILLER  PIC X(18) VALUE "1536Alaska".
       03 FILLER  PIC X(18) VALUE "1284Arizona".
       03 FILLER  PIC X(18) VALUE "1064Arkansas".
       03 FILLER  PIC X(18) VALUE "1459California".
       03 FILLER  PIC X(18) VALUE "1508Colorado".
       03 FILLER  PIC X(18) VALUE "1742Connecticut".
       03 FILLER  PIC X(18) VALUE "1450Delaware".
       03 FILLER  PIC X(18) VALUE "1328Florida".
       03 FILLER  PIC X(18) VALUE "1257Georgia".
       03 FILLER  PIC X(18) VALUE "1444Hawaii".
       03 FILLER  PIC X(18) VALUE "1126Idaho".
       03 FILLER  PIC X(18) VALUE "1439Illinois".
       03 FILLER  PIC X(18) VALUE "1203Indiana".
       03 FILLER  PIC X(18) VALUE "1267Iowa".
       03 FILLER  PIC X(18) VALUE "1295Kansas".
       03 FILLER  PIC X(18) VALUE "1126Kentucky".
       03 FILLER  PIC X(18) VALUE "1155Louisiana".
       03 FILLER  PIC X(18) VALUE "1269Maine".
       03 FILLER  PIC X(18) VALUE "1839Maryland".
       03 FILLER  PIC X(18) VALUE "1698Massachusetts".
       03 FILLER  PIC X(18) VALUE "1257Michigan".
       03 FILLER  PIC X(18) VALUE "1479Minnesota".
       03 FILLER  PIC X(18) VALUE "0999Mississippi".
       03 FILLER  PIC X(18) VALUE "1236Missouri".
       03 FILLER  PIC X(18) VALUE "1192Montana".
       03 FILLER  PIC X(18) VALUE "1261Nebraska".
       03 FILLER  PIC X(18) VALUE "1379Nevada".
       03 FILLER  PIC X(18) VALUE "1571New Hampshire".
       03 FILLER  PIC X(18) VALUE "1743New Jersey".
       03 FILLER  PIC X(18) VALUE "1148New Mexico".
       03 FILLER  PIC X(18) VALUE "1547New York".
       03 FILLER  PIC X(18) VALUE "1237North Carolina".
       03 FILLER  PIC X(18) VALUE "1290North Dakota".
       03 FILLER  PIC X(18) VALUE "1256Ohio".
       03 FILLER  PIC X(18) VALUE "1155Oklahoma".
       03 FILLER  PIC X(18) VALUE "1309Oregon".
       03 FILLER  PIC X(18) VALUE "1352Pennsylvania".
       03 FILLER  PIC X(18) VALUE "1435Rhode Island".
       03 FILLER  PIC X(18) VALUE "1172South Carolina".
       03 FILLER  PIC X(18) VALUE "1206South Dakota".
       03 FILLER  PIC X(18) VALUE "1186Tennessee".
       03 FILLER  PIC X(18) VALUE "1244Texas".
       03 FILLER  PIC X(18) VALUE "1157Utah".
       03 FILLER  PIC X(18) VALUE "1374Vermont".
       03 FILLER  PIC X(18) VALUE "1607Virginia".
       03 FILLER  PIC X(18) VALUE "1487Washington".
       03 FILLER  PIC X(18) VALUE "1062West Virginia".
       03 FILLER  PIC X(18) VALUE "1393Wisconsin".
       03 FILLER  PIC X(18) VALUE "1393Wyoming".
02 FILLER REDEFINES StateNameValues.
       03 State OCCURS 50 TIMES.
          04 BaseSalary  PIC 9(4).
          04 StateName   PIC X(14).
 
01  MiscVariables.
    02 SalesCommission  PIC 9(5)V99.
    02 Percentage       PIC V99 VALUE .08.
    02 FullSalary       PIC 9(6)V99.
    02 ActualStateNum   PIC 99.
 
REPORT SECTION.
RD  SolaceSalesReport
    CONTROLS ARE FINAL
                 StateNum
                 SalesAgentNum
    PAGE LIMIT IS 66
    HEADING 1
    FIRST DETAIL 6
    LAST DETAIL 54
    FOOTING 56.
 
01  TYPE IS PAGE HEADING.
    02 LINE 1.
       03 COLUMN 20     PIC X(32)
                        VALUE "Solace Solar Solutions".
 
    02 LINE 2.
       03 COLUMN 6      PIC X(51)
          VALUE "Sales Agent - Sales and Salary Report Monthly Report".
 
    02 LINE 4.
       03 COLUMN 2      PIC X(5)  VALUE "State".
       03 COLUMN 16     PIC X(5)  VALUE "Agent".
       03 COLUMN 32     PIC X(8)  VALUE "Value".
 
    02 LINE 5.
       03 COLUMN 2      PIC X(4)  VALUE "Name".
       03 COLUMN 16     PIC X(6)  VALUE "Number".
       03 COLUMN 31     PIC X(8)  VALUE "Of Sales".
 
01  DetailLine TYPE IS DETAIL.
    02 LINE IS PLUS 1.
       03 COLUMN 1      PIC X(14)
                        SOURCE StateName(StateNum) GROUP INDICATE.
       03 COLUMN 17     PIC 999
                        SOURCE SalesAgentNum  GROUP INDICATE.
       03 COLUMN 30     PIC $$$,$$$.99 SOURCE ValueOfSale.
 
01  SalesAgentGrp
    TYPE IS CONTROL FOOTING SalesAgentNum  NEXT GROUP PLUS 2.
    02 LINE IS PLUS 1.
       03 COLUMN 15     PIC X(21) VALUE "Sales for sales agent".
       03 COLUMN 37     PIC 999 SOURCE SalesAgentNum.
       03 COLUMN 43     PIC X VALUE "=".
       03 TotalAgentSales COLUMN 45 PIC $$$$$,$$$.99 SUM ValueOfSale.
 
    02 LINE IS PLUS 1.
       03 COLUMN 15     PIC X(19) VALUE "Sales commission is".
       03 COLUMN 43     PIC X VALUE "=".
       03 COLUMN 45     PIC $$$$$,$$$.99 SOURCE SalesCommission.
 
    02 LINE IS PLUS 1.
       03 COLUMN 15     PIC X(22) VALUE "Sales agent salary is".
       03 COLUMN 43     PIC X VALUE "=".
       03 COLUMN 45     PIC $$$$$,$$$.99 SOURCE FullSalary.
 
01  StateGrp TYPE IS CONTROL FOOTING StateNum NEXT GROUP PLUS 2.
    02 LINE IS PLUS 2.
       03 COLUMN 15     PIC X(15) VALUE "Total sales for".
       03 COLUMN 31     PIC X(14) SOURCE StateName(StateNum).
       03 TotalStateSales COLUMN 45  PIC $$$$$,$$$.99 SUM TotalAgentSales.
        
    02 LINE IS PLUS 1.
       03 COLUMN 15     PIC X(15) VALUE "Base salary for".
       03 COLUMN 31     PIC X(14) SOURCE StateName(StateNum).
       03 COLUMN 48     PIC $$,$$$.99 SOURCE BaseSalary(StateNum).
        
    02 LINE IS PLUS 1.
       03 COLUMN 15     PIC X(26)
                        VALUE "Actual state number is   -".
       03 COLUMN 42     PIC Z9 SOURCE ActualStateNum.
 
    02 LINE IS PLUS 1.
       03 COLUMN 15     PIC X(26)
                        VALUE "Supplied state number is -".
       03 COLUMN 42     PIC Z9 SOURCE StateNum.
        
    02 LINE IS PLUS 1.
       03 COLUMN 1      PIC X(58) VALUE ALL "-".
 
01  TotalSalesGrp TYPE IS CONTROL FOOTING FINAL.
    02 LINE IS PLUS 4.
       03 COLUMN 15     PIC X(11)
                        VALUE "Total sales".
       03 COLUMN 46     PIC X VALUE "=".
       03 COLUMN 48     PIC $$,$$$,$$$.99 SUM TotalStateSales.
 
01  TYPE IS PAGE FOOTING.
    02 LINE IS 58.
       03 COLUMN 1      PIC X(29) VALUE "Programmer - Michael Coughlan".
       03 COLUMN 55     PIC X(6) VALUE "Page :".
       03 COLUMN 62     PIC ZZ9 SOURCE PAGE-COUNTER.
 
PROCEDURE DIVISION.
DECLARATIVES.
Calc SECTION.
    USE BEFORE REPORTING SalesAgentGrp.
Calculate-Salary.
    MULTIPLY TotalAgentSales BY Percentage
          GIVING SalesCommission ROUNDED
    ADD SalesCommission, BaseSalary(StateNum)
          GIVING FullSalary.
END DECLARATIVES.
 
Main SECTION.
Begin.
    OPEN INPUT SalesFile
    OPEN OUTPUT PrintFile
    READ SalesFile
         AT END SET EndOfFile TO TRUE
    END-READ
    INITIATE SolaceSalesReport
    PERFORM PrintSalaryReport
            UNTIL EndOfFile
    TERMINATE SolaceSalesReport
    CLOSE SalesFile, PrintFile
    STOP RUN.
 
PrintSalaryReport.
    GENERATE DetailLine
    READ SalesFile
          AT END SET EndOfFile TO TRUE
    END-READ
    MOVE StateNum  TO ActualStateNum.

Example 18-5. Report Showing Commission Earned and Total Salary

                   Solace Solar Solutions
     Sales Agent - Sales and Salary Report Monthly Report
 State         Agent           Value
 Name          Number         Of Sales
Alabama         038           $9,325.14
                             $11,839.19
                             $19,102.61
              Sales for sales agent 038   =   $40,266.94
              Sales commission is         =    $3,221.36
              Sales agent salary is       =    $4,370.36
Alabama         073           $4,503.71
                             $11,659.87
                             $19,540.19
              Sales for sales agent 073   =   $35,703.77
              Sales commission is         =    $2,856.30
              Sales agent salary is       =    $4,005.30
              Total sales for Alabama         $75,970.71
              Base salary for Alabama          $1,149.00
              Actual state number is   -  2
              Supplied state number is -  1
----------------------------------------------------------
Alaska          055          $18,981.84
                              $3,065.97
                             $10,686.92
              Sales for sales agent 055   =   $32,734.73
              Sales commission is         =    $2,618.78
              Sales agent salary is       =    $4,154.78
Alaska          089          $11,187.72
                             $14,145.82
              Sales for sales agent 089   =   $25,333.54
              Sales commission is         =    $2,026.68
              Sales agent salary is       =    $3,562.68
Alaska          104          $18,005.42
                             $17,614.20
              Sales for sales agent 104   =   $35,619.62
              Sales commission is         =    $2,849.57
              Sales agent salary is       =    $4,385.57
              Total sales for Alaska          $93,687.89
              Base salary for Alaska           $1,536.00
              Actual state number is   -  3
              Supplied state number is -  2
----------------------------------------------------------
Programmer - Michael Coughlan                         Page :   1

The major differences between Listing 18-2 and Listing 18-3 are shown in bold. To print the agent commission and total salary, I have added a number of entries to SalesAgentGrp. Note, though, that the sources of these items are data items declared outside the REPORT SECTION. The reason is that these items require calculations beyond what the Report Writer can handle automatically. To calculate these items, you must use declaratives. I discuss declaratives presently; but for now, I want to discuss another issue.

Look at the StateGrp CONTROL FOOTING and in particular at these lines:

03 COLUMN 31     PIC X(14) SOURCE StateName(StateNum).
03 COLUMN 48     PIC $$,$$$.99 SOURCE BaseSalary(StateNum).

Notice anything strange? This footer is printed when there is a control break on StateNum—in other words, when the value of StateNum changes. This means StateNum in the previous lines should refer to the next state and not the one for which the totals have just been accumulated. And yet, if you examine the report, you see that the correct state name and base salary are printed. How can this be? Remember this:

In aCONTROL FOOTINGor in theDECLARATIVES SECTION, when a control data item is referenced, the value supplied is the previous value and not the value that has just caused the control break.

To emphasize this point, I have printed the actual state number value (the one in the record buffer) and the state number supplied by the Report Writer. To get the actual state number, each time a record is read, the StateNum in the record is moved to the ActualStateNum in the WORKING-STORAGE SECTION. This data item is used as a SOURCE when the CONTROL FOOTING is printed.

Report Writer Declaratives

The Report Writer is a wonderful tool if the structure of the required report fits the way the Report Writer does things. But sometimes the structure or requirements of a report are such that the standard Report Writer alone is not sufficient. In these cases, you can use declaratives to extend the functionality of the Report Writer.

The USE BEFORE REPORTING phrase allows code specified in the declaratives to be executed just before the report group mentioned in the USE BEFORE REPORTING phrase is printed. The code in the declaratives extends the functionality of the Report Writer by performing tasks or calculations that the Report Writer cannot do automatically or by selectively stopping a report group from being printed (using the SUPPRESS PRINTING command).

In Listing 18-3, declaratives are used to calculate SalesCommission and FullSalary before SalesAgentGrp is printed.

Report Writer Syntax and Semantics

I have shown you a number of example programs that use the Report Writer. That informal introduction should have given you a good idea of the new verbs and declarations required when you write a Report Writer program. This section deals with the syntax and semantics of Report Writer elements.

ENVIRONMENT DIVISION Entries

Just like ordinary reports, the reports generated by the Report Writer are written to an external device—usually a report file. The ENVIRONMENT DIVISION entries for a report file are the same as those for an ordinary file. The same SELECT and ASSIGN clauses apply. You can either omit the ORGANIZATION phrase as in the example programs, in which case the default of ORGANIZATION IS SEQUENTIAL applies, or you can specify ORGANIZATION IS SEQUENTIAL explicitly, as in the following example:

FILE-CONTROL.
    SELECT SalesFile ASSIGN TO "Listing18-4-Sales.DAT"
           ORGANIZATION IS LINE SEQUENTIAL.

    SELECT PrintFile ASSIGN TO "Listing18-4.Rpt"
           ORGANIZATION IS SEQUENTIAL.

FILE SECTION Entries

The entries in the ENVIRONMENT DIVISION are the same as those for ordinary print files. But in the FILE SECTION, the normal file description is replaced by the REPORT IS phrase, which points to the RD in the REPORT SECTION. The metalanguage for the phrase is

9781430262534_unFig18-01.jpg

where ReportName must be the same as the ReportName used in the RD entry. You can see this in Listing 18-3, where the REPORT IS SolaceSalesReport phrase links the PrintFile with the RD in the REPORT SECTION.

Note that before the report can be used, it must be opened for output. For instance, in Listing 18-3, the PrintFile is opened for output before the SolaceSalesReport is generated.

Report Description (RD) Entries

The RD entry in the REPORT SECTION defines the report. There must be a separate RD entry for each report you want to print. The RD entry names the report, specifies the format of the printed page, and identifies the control-break items.

Each RD entry is followed by one or more 01 level-number entries. Each 01 level-number entry identifies a report group and consists of a hierarchical structure similar to a COBOL record. Each report group is a unit consisting of one or more print lines and cannot be split across pages. The metalanguage for the RD is given in Figure 18-2.

9781430262534_Fig18-02.jpg

Figure 18-2. Metalanguage for the Report Description (RD) entry

Keep the following points in mind:

  • ReportName can appear in only one RD entry.
  • When more than one report is declared in the REPORT SECTION, ReportName may be used to qualify the LINE-COUNTER and PAGE-COUNTER report registers.
  • ControlName$#i must not be a data item defined in the REPORT SECTION.
  • Each occurrence of ControlName$#i must identify a different data item.
  • ControlName$#i must not have a variable-length table subordinate to it.
  • ControlName$#i and FINAL specify the levels of the control-break hierarchy, where FINAL (if specified) is the highest, the first ControlName$#i is the next highest, and so on.
  • When the value in any ControlName$#i changes, a control break occurs. The level of the control break depends on the position of the ControlName$#i in the control-break hierarchy.
  • HeadingLine#l must be greater than or equal to 1.
  • The following must hold: HeadingLine#l <= FirstDetailLine#l <= LastDetailLine#l <= FootingLine#l <= PageSize#l
  • The line numbers used in a REPORT HEADING or PAGE HEADING group must be greater than or equal to HeadingLine#l and less than FirstDetailLine#l. But when a REPORT HEADING appears on a page by itself, any line number between HeadingLine#l and PageSize#l may be used.
  • The line numbers used in a DETAIL or CONTROL HEADING group must be in the range FirstDetailLine#l to LastDetailLine#l, inclusive.
  • The line numbers used in CONTROL FOOTING groups must be in the range FirstDetailLine#l to FootingLine#l, inclusive.
  • The line numbers used in a REPORT FOOTING or PAGE FOOTING group must be greater than FootingLine#l and less than or equal to PageSize#l. But when a REPORT FOOTING appears on a page by itself, any line number between HeadingLine#l and PageSize#l may be used.
  • All the report groups must be defined so that they can be presented on one page. The Report Writer never splits a multiline group across page boundaries.

Report Group Entries

The RD entry specifies the name of the report, identifies the control items, and lays down the basics of how the page is to be formatted. After the RD entry, you specify the report groups to be used in the report. Each report group is represented by a report-group record. As with all record descriptions in COBOL, a report-group record starts with level number 01. The subordinate items in the record describe the report lines and columns in the report group.

Each report group starts with a level 01 report group definition. The metalanguage for the report group definition is given in Figure 18-3.

9781430262534_Fig18-03.jpg

Figure 18-3. Metalanguage for the report group definition

RD Entry

When you create an RD entry, keep in mind that ReportGroupName is required only when the group

  • Is a DETAIL group referenced by a GENERATE statement or the UPON phrase of a SUM clause
  • Is referenced in a USE BEFORE REPORTING sentence in the declaratives
  • Is required to qualify the reference to a SUM counter

LINE NUMBER Clause

When you use the LINE NUMBER clause, keep the following in mind:

  • The LINE NUMBER clause is used to specify the vertical positioning of print lines. Lines can be printed on
    • A specified line (absolute)
    • A specified line on the next page (absolute)
    • The current line number plus some increment (relative)
  • The LINE NUMBER clause specifies where each line is to be printed, so no item that contains a LINE NUMBER clause may contain a subordinate item that also contains a LINE NUMBER clause (subordinate items specify the column items).
  • Where absolute LINE NUMBER clauses are specified, all absolute clauses must precede all relative clauses, and the line numbers specified in the successive absolute clauses must be in ascending order.
  • The first LINE NUMBER clause specified in a PAGE FOOTING group must be absolute.
  • The NEXT PAGE clause can appear only once in a given report group description, and it must be in the first LINE NUMBER clause in the report group.
  • The NEXT PAGE clause cannot appear in any HEADING group.

NEXT GROUP Clause

When you use the NEXT GROUP clause, keep the following things in mind:

  • The NEXT GROUP clause is used to specify the vertical positioning of the start of the next group. This clause can be used to specify that the next report group should be printed on
    • A specified line (absolute)
    • The current line number plus some increment (relative)
    • The next page
  • The NEXT PAGE option in the NEXT GROUP clause must not be specified in a page footer.
  • The NEXT GROUP clause must not be specified in a REPORT FOOTING or PAGE HEADING group.
  • When used in a DETAIL group, the NEXT GROUP clause refers to the next DETAIL group to be printed.

The TYPE Clause

The TYPE clause specifies the type of the report group. The type of the report group governs when and where it is printed in the report (for instance, a REPORT HEADING group is printed only once: at the beginning of the report).

When you use the TYPE clause, keep the following things in mind:

  • Most groups are defined once for each report, but control groups (other than CONTROL ..FINAL groups) are defined for each control-break item.
  • In REPORT FOOTING, and CONTROL FOOTING groups, SOURCE and USE clauses must not reference any data item that contains a control-break item or is subordinate to a control-break item.
  • PAGE HEADING and FOOTING groups must not reference a control-break item or any item subordinate to a control-break item.
  • DETAIL report groups are processed when they are referenced in a GENERATE statement. All other groups are processed automatically by the Report Writer. There can be more than one DETAIL group.
  • The REPORT HEADING, PAGE HEADING, CONTROL HEADING FINAL, CONTROL FOOTING FINAL, PAGE FOOTING, and REPORT FOOTING report groups can each appear only once in the description of a report.

Report Group Lines

The subordinate items in a report-group record describe the report lines and columns in the report group. There are two formats for defining items subordinate to the report-group record. The first is usually used to define the lines of the report group, and the second defines and positions the elementary print items.

Defining the Print Lines

Print lines in a report group are usually defined using the metalanguage given in Figure 18-4. This format is used to specify the vertical placement of a print line, and it is always followed by subordinate items that specify the columns where the data items are to be printed.

9781430262534_Fig18-04.jpg

Figure 18-4. Metalanguage for vertical print line positioning

As shown in the metalanguage, the level number is from 2 to 48, inclusive. If ReportLineName is used, its only purpose is to qualify a SUM counter reference.

Defining the Elementary Print Items

The elementary print items in the print line of a report group are described using the metalanguage shown in Figure 18-5. As you can see, the normal data-description clauses such as PIC, USAGE, SIGN, JUSTIFIED, BLANK WHEN ZERO, and VALUE may be applied when describing an elementary print item. The Report Writer provides a number of additional clauses that may also be used with these items.

9781430262534_Fig18-05.jpg

Figure 18-5. Metalanguage to define elementary report items

SumCounterName can only be referenced if the entry uses the SUM clause to define a sum counter.

The COLUMN NUMBER Clause

When you use the COLUMN NUMBER clause, keep the following things in mind:

  • COLUMN NUMBER specifies the position of a print item on the print line. When this clause is used, it must be subordinate to an item that contains a LINE NUMBER clause.
  • In a given print line, the ColNum#ls should be in ascending sequence.
  • ColNum#l specifies the column number of the leftmost character position of the print item.

The GROUP INDICATE Clause

The GROUP INDICATE clause can only appear in a DETAIL report group. It is used to specify that a print item should be printed only on the first occurrence of its report group after a control break or page advance. For instance, in Listing 18-3, the state name and sales agent number are suppressed after their first occurrence. As a reminder, I have repeated the DETAIL group declaration here:

01  DetailLine TYPE IS DETAIL.
    02 LINE IS PLUS 1.
       03 COLUMN 1      PIC X(14)
                        SOURCE StateName(StateNum) GROUP INDICATE.
       03 COLUMN 17     PIC 999
                        SOURCE SalesAgentNum  GROUP INDICATE.
       03 COLUMN 30     PIC $$$,$$$.99 SOURCE ValueOfSale.

The SOURCE Clause

The SOURCE clause is used to identify a data item that contains the value to be used when the print item is printed. For instance, the SOURCE ValueOfSale clause in the previous example specifies that the value of the item to be printed in column 30 is to be found in the data item ValueOfSale.

The SUM Clause

The SUM clause is used both to establish a sum counter and to name the data items to be summed. A SUM clause can appear only in the description of a CONTROL FOOTING report group. Statements in the PROCEDURE DIVISION can be used to alter the contents of the sum counters.

You can do three forms of summing in the Report Writer:

  • Subtotaling
  • Rolling forward
  • Crossfooting

Subtotaling

When the SUM clause is used with a data item declared in the FILE or WORKING-STORAGE SECTION, then each time a GENERATE is executed, the value to be summed is added to the sum counter. If there is more than one DETAIL group in the report, the SUM..UPON option allows you to select which sum counter to total. For instance, if the report contains two DETAIL groups—one called DetailLine and the other called AlternateDetailLine—you can use SUM..UPON to specify that subtotaling is to be done only each time a GENERATE AlternateDetailLine is executed.

Rolling Forward

When the SUM clause is used with a data item representing the sum counter of another CONTROL FOOTING group, then each time the other group is executed, the value of its sum counter is added to the value of the sum counter of the current group.

Listing 18-3 contains good examples of both subtotaling and rolling forward. Example 18-6 provides a reminder of the relevant code. Each time a DETAIL line is GENERATED, the ValueOf Sale is added to the TotalAgentSales sum counter. When a control break occurs on SalesAgentNum, the accumulated sum is printed and is added to the TotalStateSales sum counter. When a control break occurs on StateNum, the sum accumulated in the TotalStateSales sum counter is added to the final total sum counter.

Example 18-6. Subtotaling and Rolling Forward from Listing 18-3

01  SalesAgentGrp
    TYPE IS CONTROL FOOTING SalesAgentNum  NEXT GROUP PLUS 2.
    :   :   :   :   :   :  :   :   :   :   :   :   :   :   :
       03TotalAgentSalesCOLUMN 45 PIC $$$$$,$$$.99 SUMValueOfSale.
 
01  StateGrp TYPE IS CONTROL FOOTING StateNum NEXT GROUP PLUS 2.
    02 LINE IS PLUS 2.
    :   :   :   :   :   :  :   :   :   :   :   :   :   :   :
       03TotalStateSalesCOLUMN 45  PIC $$$$$,$$$.99 SUMTotalAgentSales.
        
01  TotalSalesGrp TYPE IS CONTROL FOOTING FINAL.
    :   :   :   :   :   :  :   :   :   :   :   :   :   :   :
       03 COLUMN 48     PIC $$,$$$,$$$.99 SUMTotalStateSales.

Crossfooting

In crossfooting, the sum counters in the same CONTROL FOOTING group can be added together to create another sum counter. In Example 18-7, each time a GENERATE statement is executed, the value of NetWeightOfGoods (in the file record) is added to the NWG sum counter, and the value of WeightOfPackingMaterials (in the file record) is added to WPM (subtotaling). When a control break occurs on OrderNumber, the values of the NWG and WPM sum counters are added together to give the combined total identified as GrossWeight and printed in column 40 (crossfooting).

Example 18-7. Crossfooting to Create the GrossWeight Sum Counter

01  ShippingGrp
    TYPE IS CONTROL FOOTING  OrderNumber  NEXT GROUP PLUS 3.
                      : other entries :
                      : other entries :
       03 NWG           COLUMN 20  PIC Z,ZZ9   SUM NetWeightOfGoods.
       03 WPM           COLUMN 30  PIC ZZ9     SUM WeightOfPackingMaterials.
       03 GrossWeight   COLUMN 40  PIC ZZ,ZZ9  SUM GNW, PMW.

The RESET ON Clause

Sum counters are normally reset to zero after a control break on the control-break item associated with the report group. For instance, in Example 18-6, if you wanted SalesAgentGrp to show a rolling total of the sales in the state, you could change SalesAgentGrp as shown in Example 18-8. In this example, TotalAgentSales prints the sales of a particular agent and is reset to zero when the footer group is printed, whereas StateSalesToDate prints a rolling total of sales for the state and is reset to zero only when there is a control break on StateNum.

Example 18-8. Using the RESET ON Clause

01  SalesAgentGrp
    TYPE IS CONTROL FOOTING SalesAgentNum  NEXT GROUP PLUS 2.
    :   :   :   :   :   :  :   :   :   :   :   :   :   :   :
       03 TotalAgentSales  COLUMN 45 PIC $$$$$,$$$.99 SUM ValueOfSale.
       03 StateSalesToDate COLUMN 60 PIC $$$$$,$$$.99 SUM ValueOfSale
                                                    RESET ON StateNum.

Special Report Writer Registers

The Report Writer maintains two special registers for each report declared in the REPORT SECTION.: LINE-COUNTER and PAGE-COUNTER.

LINE-COUNTER

LINE-COUNTER is a reserved word that can be used to access a special register that the Report Writer maintains for each report in the REPORT SECTION. The Report Writer uses the LINE-COUNTER register to keep track of where the lines are being printed on the report. It uses this information and the information specified in the PAGE LIMIT clause in the RD entry to decide when a new page is required.

Although the LINE-COUNTER register can be used as a SOURCE item in the report, no statements in the PROCEDURE DIVISION can alter the value in the register.

References to the LINE-COUNTER register can be qualified by referring to the name of the report given in the RD entry.

PAGE-COUNTER

The reserved word PAGE-COUNTERis used to access a special register that the Report Writer maintains for each report in the REPORT SECTION. It keeps track of the number of pages printed in the report. The PAGE-COUNTER register can be used as a SOURCE item in the report, but the value of the PAGE-COUNTER may also be changed by statements in the PROCEDURE DIVISION .

PROCEDURE DIVISION Report Writer Verbs

The Report Writer introduces four new verbs for processing reports:

  • INITIATE
  • GENERATE
  • TERMINATE
  • SUPPRESS PRINTING

The first three are normal PROCEDURE DIVISION verbs, but the last one can only be used in the declaratives. I will postpone discussion of that verb until I deal with declaratives.

The INITIATE Verb

An INITIATE statement starts the processing of the ReportName report or reports. The metalanguage for the INITIATE verb is given in Figure 18-6.

9781430262534_Fig18-06.jpg

Figure 18-6. Metalanguage for the INITIATE verb

Before INITIATE is executed, the file associated with the ReportName must have been opened for OUTPUT or EXTEND. This is illustrated in Listing 18-3 by these statements:

SELECTPrintFileASSIGN TO "Listing18-3.Rpt".
    :    :    :    :    :    :    :    :    :
FD  PrintFile
    REPORT ISSolaceSalesReport.
    :    :    :    :    :    :    :    :    :
RD  SolaceSalesReport
    :    :    :    :    :    :    :    :    :
OPEN OUTPUTPrintFile
    :    :    :    :    :    :    :    :    :
INITIATESolaceSalesReport

The GENERATE Verb

The GENERATE statement drives the production of the report. The metalanguage for GENERATE is given in Figure 18-7.

9781430262534_Fig18-07.jpg

Figure 18-7. Metalanguage for the GENERATE verb

The target of a GENERATE statement is either a DETAIL report group or a ReportName. When the target is a ReportName, the report description must contain the following:

  • A CONTROL clause
  • Not more than one DETAIL group
  • At least one group that is not a PAGE or REPORT group

When all the GENERATE statements for a particular report target the ReportName, the report performs summary processing only, and the report produced is called a summary report. For instance, to make a summary report using Listing 18-3, all you have to do is change

GENERATE DetailLine
to
GENERATE SolaceSalesReport.

If you specify GENERATE SolaceSalesReport, then the DETAIL group is never printed, but the other groups are printed.

The TERMINATE Verb

You use a TERMINATE statement to instruct the Report Writer to finish the processing of the specified report. The metalanguage for TERMINATE is given in Figure 18-8.

9781430262534_Fig18-08.jpg

Figure 18-8. Metalanguage for the TERMINATE verb

When TERMINATE is executed, the Report Writer prints the PAGE and REPORT FOOTING groups, and all the CONTROL FOOTING groups are printed as if there had been a control break on the most senior control group.

After the report has been terminated, the file associated with the report must be closed. For instance, in Listing 18-3, the TERMINATE SolaceSalesReport statement is followed by the CLOSE PrintFile statement.

Declaratives

The main structural elements of a COBOL program are divisions, sections, and paragraphs. This section introduces a new structural element: declaratives. When declaratives are used, they are the first element in the PROCEDURE DIVISION and start with the word DECLARATIVES and end with END DECLARATIVES. Declaratives specify USE procedures that are executed when certain conditions occur. You write the USE procedures in the declaratives in consecutive sections.

When declaratives are used, the remainder of the PROCEDURE DIVISION must consist of at least one section. Example 18-9 is a template the shows the structure of declaratives.

Example 18-9. Structure of Declaratives

PROCEDURE DIVISION.
DECLARATIVES
SectionName SECTION.
    USE statement
ParagraphName.
    COBOL Statements
END DECLARATIVES.
Main SECTION.

Declaratives are used for two main purposes:

  • To extend the functionality of the Report Writer
  • To handle file operation errors

Using Declaratives with the Report Writer

Declaratives are used to extend the functionality of the Report Writer by performing tasks or calculations that the Report Writer cannot do automatically or by selectively stopping a report group from being printed (using the SUPPRESS PRINTING command). When you use declaratives with the Report Writer, the USE BEFORE REPORTING phrase lets you specify that a particular section of code is to be executed before the identified report group is printed. The metalanguage for the USE statement used with the Report Writer is given in Figure 18-9.

9781430262534_Fig18-09.jpg

Figure 18-9. Metalanguage for the Report Writer version of USE

Note the following:

  • ReportGroupName must not appear in more than one USE statement.
  • The GENERATE, INITIATE, and TERMINATE statements must not appear in the declaratives.
  • The value of any control data items must not be altered in the declaratives.
  • Statements in the declaratives must not reference procedures outside the declaratives.

Listing 18-3 has a good example of how declaratives may be used to extend the functionality of the Report Writer. They are used to calculate the sales agent SalesCommission and FullSalary before SalesAgentGrp is printed. For convenience, the code is repeated in Example 18-10.

Example 18-10. Declaratives from Listing 18-3

PROCEDURE DIVISION.
DECLARATIVES.
Calc SECTION.
    USE BEFORE REPORTING SalesAgentGrp.
Calculate-Salary.
    MULTIPLY TotalAgentSales BY Percentage
          GIVING SalesCommission ROUNDED
    ADD SalesCommission, BaseSalary(StateNum)
          GIVING FullSalary.
END DECLARATIVES.
Main SECTION.
Begin.
    OPEN INPUT SalesFile
    OPEN OUTPUT PrintFile

The SUPPRESS PRINTING Statement

The SUPPRESS PRINTING statement is used in a DECLARATIVES section to stop a particular report group from being printed. The report group suppressed is the one mentioned in the USE statement associated with the section containing the SUPPRESS PRINTING statement. The SUPPRESS PRINTING statement must be executed each time you want to stop the report group from being printed.

In Example 18-11, the CONTROL FOOTING data for StateGrp is printed only if the state sales total is above a certain threshold.

Example 18-11. Suppressing the Printing of a Report Group

PROCEDURE DIVISION.
DECLARATIVES.
CheckStateSales SECTION.
    USE BEFORE REPORTING StateGrp.
PrintImportantStatesOnly.
    IF TotalStateSales  < 100000
       SUPPRESS PRINTING
    END-IF.
END DECLARATIVES.

Control-Break Registers

The Report Writer maintains a special control-break register for each control-break item mentioned in the CONTROLS ARE phrase in the RD entry. When a control-break item is referred to in a control footer or in the declaratives, the Report Writer supplies the value held in the control-break register and not the value in the item itself. If a control break has just occurred, the value in the control-break register is the previous value of the control-break item.

This point is demonstrated in the report produced by Listing 18-3 by printing the actual state number (the one in the record buffer) and the supplied state number (the one in the control-break register) each time StateGrp group is printed.

Using Declaratives with Files

You can also use declaratives to handle file operation errors. The metalanguage for the version of USE used with files is given in Figure 18-10.

9781430262534_Fig18-10.jpg

Figure 18-10. Metalanguage for the files version of USE

When you use this version of the declaratives, you can create code that deals with any I-O error on a particular file or more generalized code that deals with INPUT, OUTPUT, I-O, or EXTEND errors on any file. When declaratives exist for a file, the INVALID KEY clause and the AT END clause are optional.

The program fragment in Example 18-12 shows how you can use declaratives to handle errors on a particular file.

Example 18-12. Declarative Procedures to Handle Unexpected File Errors

PROCEDURE DIVISION.
DECLARATIVES.
SupFile SECTION.
   USE AFTER ERROR PROCEDURE ON SupplierFile.
DisplaySupplierFileStatus.
   DISPLAY "Unexpected error on Supplier file. Status = " SupplierStatus
   DISPLAY "The file name used was :- " SupplierFileName
   STOP RUN.
 
VidFile SECTION.
   USE AFTER ERROR PROCEDURE ON VideoFile.
DisplayVideoFileStatus.
   DISPLAY "Unexpected error on Video file. Status = " VideoStatus
   DISPLAY "The file name used was :- " VidFileName
   STOP RUN.
END DECLARATIVES.
Main SECTION.
Begin.
    OPEN INPUT SupplierFile
    OPEN INPUT VideoFile
              etc

Summary

This chapter introduced you to the COBOL Report Writer. In a series of increasingly complex programs, you learned how to use the Report Writer to create control-break-based reports. You were introduced to a number of new verbs, clauses, sections, and concepts. You saw how to use the RD entry in the REPORT SECTION to specify control-break items and define the basic layout of the report page. You were introduced to the idea of a report group and shown how to create report groups linked to control-break items. You learned how to use the SUM clause for totaling and rolling forward. The final program demonstrated how to extend the capabilities of the Report Writer by using declaratives. You then covered the verbs, clauses, and concepts of the Report Writer. And in the final section, you saw how to use declaratives for error handling in files.

The final chapter introduces OO-COBOL. This book adheres to the ANS 85 COBOL standard, so the ISO 2002 OO-COBOL is somewhat outside its remit. Nevertheless, some of the drawbacks of contained subprograms are remedied by OO-COBOL, and it is from this perspective that I examine the topic. Do not expect a course in object-oriented programming.

PROGRAMMING EXERCISE

And now for a programming exercise that tests your understanding of the last two chapters. For this, you need a really sharp 2B pencil.

Introduction

Two months before the beginning of each semester, Campus Bookshop produces a Purchase Requirements Report. This report details the books that have to be purchased for the coming semester. In the past, this was done manually; but now management has decided to computerize the operation. Accordingly, lecturers’ requirements have been captured and the results used to update a purchase requirements file. This is a permanent file that contains details of the lecturers’ book requirements for both semesters.

You are required to write a program to produce a Purchase Requirements Report from the publisher, book, and purchase requirements files. The report should be sequenced on ascending publisher name and should only detail the purchase requirements for the semester under scrutiny.

The semester number (1 or 2) should be accepted from the user at the start of the program using a simple ACCEPT and DISPLAY.

File Descriptions

Purchase Requirements File (Indexed)

There is a record for each book title required by a lecturer. Note that a book may be required by more than one lecturer.

Table18-2.jpg

Book File (Indexed)

Table18-3.jpg

Publisher File (Indexed)

Table18-4.jpg

Print Specification

The report must be printed according to the print specification given in Figure 18-11.

9781430262534_Fig18-11.jpg

Figure 18-11. Print specification for the Purchase Requirements Report

The publisher name must be suppressed after its first occurrence. The headings should be printed at the top of each page, and *** END OF REPORT *** should be printed on line 56 on the last page of the report.

Ordinarily, a new page is required after line 50.

The Qty field, which is a synonym for Copies-Required, should be zero suppressed up to but not including the last digit.

The page number field should also be zero suppressed.

PROGRAMMING EXERCISE: SOLUTION

IDENTIFICATION DIVISION.
PROGRAM-ID. Listing18-4.
AUTHOR.  MICHAEL COUGHLAN.
*The Campus Bookshop Purchase Requirements Report (DP291-91-EXAM)
*Originally written for VAX COBOL 1991
*Converted to Microfocus COBOL 2002
*Modified for COBOL book 2014

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT PurchaseReqFile  ASSIGN TO "Listing18-4-PRF.DAT"
        ORGANIZATION IS INDEXED
        FILE STATUS IS FileStatus-PRF
        ACCESS MODE IS DYNAMIC
        RECORD KEY IS PRNumber-PRF
        ALTERNATE RECORD KEY IS LecturerName-PRF
                WITH DUPLICATES
        ALTERNATE RECORD KEY IS BookNum-PRF
                WITH DUPLICATES.

    SELECT BookFile ASSIGN TO "Listing18-4-BF.DAT"
        ORGANIZATION IS INDEXED
        FILE STATUS IS FileStatus-BF
        ACCESS MODE IS DYNAMIC
        RECORD KEY IS BookNum-BF
        ALTERNATE RECORD KEY IS PublisherNum-BF
                WITH DUPLICATES.

    SELECT PublisherFile ASSIGN TO "Listing18-4-PF.DAT"
        ORGANIZATION IS INDEXED
        FILE STATUS IS FileStatus-PF
        ACCESS MODE IS DYNAMIC
        RECORD KEY IS PublisherNum-PF
        ALTERNATE RECORD KEY IS PublisherName-PF.

    SELECT ReportFile ASSIGN TO "Listing18-4.RPT".

DATA DIVISION.
FILE SECTION.
FD  PurchaseReqFile.
01  PurchaseRec-PRF.
    88 EndOfPRequirements     VALUE HIGH-VALUES.
    88 NotEndOfPRequirements  VALUE LOW-VALUES.
    02  PRNumber-PRF          PIC 9(4).
    02  LecturerName-PRF      PIC X(20).
    02  BookNum-PRF           PIC 9(4).
    02  ModuleCode-PRF        PIC X(5).
    02  CopiesRequired-PRF    PIC 9(3).
    02  Semester-PRF          PIC 9.
    
FD  BookFile.
01  BookRec-BF.
    88 EndOfBooks             VALUE HIGH-VALUES.
    88 NotEndOfBooks          VALUE LOW-VALUES.
    02  BookNum-BF            PIC 9(4).
    02  PublisherNum-BF       PIC 9(4).
    02  BookTitle-BF          PIC X(30).

FD  PublisherFile.
01  PublisherRec-PF.
    88  EndOfPublishers       VALUE HIGH-VALUES.
    02  PublisherNum-PF       PIC 9(4).
    02  PublisherName-PF      PIC X(20).
    02  PublisherAddress-PF   PIC X(40).

FD  ReportFile
    REPORT IS PurchaseRequirementsReport.

WORKING-STORAGE SECTION.
01  File-Stati.
    02  FileStatus-PRF        PIC X(2).
        88 PurchaseRec-PRF-Not-Found   VALUE "23".
    02  FileStatus-BF         PIC X(2).
        88 BookRec-Not-Found   VALUE "23".
    02  FileStatus-PF         PIC X(2).

01  Current-Semester          PIC 9.

REPORT SECTION.
RD  PurchaseRequirementsReport
    CONTROLS ARE     FINAL
                     PublisherName-PF
    PAGE LIMIT IS 66
    HEADING 2
    FIRST DETAIL 8
    LAST DETAIL 50
    FOOTING 55.

01  TYPE IS REPORT FOOTING.
    02  LINE 56.
        03  COLUMN 29         PIC X(23)
                    VALUE "*** END  OF  REPORT ***".

01  TYPE IS PAGE HEADING.
    02  LINE 2.
        03  COLUMN 27         PIC X(30)
                    VALUE "PURCHASE  REQUIREMENTS  REPORT".
        03  COLUMN 77         PIC X(6)
                    VALUE "PAGE :".
        03  COLUMN 84         PIC Z9 SOURCE PAGE-COUNTER.

    02  LINE 3.
        03  COLUMN 26         PIC X(32) VALUE ALL "-".

    02  LINE 6.
        03  COLUMN 2          PIC X(24) VALUE "PUBLISHER NAME".
        03  COLUMN 33         PIC X(11) VALUE "BOOK  TITLE".
        03  COLUMN 57         PIC X(3)  VALUE "QTY".
        03  COLUMN 65         PIC X(14) VALUE "LECTURER  NAME".

01  PReq-PrintLine TYPE IS DETAIL.
    02  LINE IS PLUS 2.
        03  COLUMN 1          PIC X(20) SOURCE PublisherName-PF
                              GROUP INDICATE.
        03  COLUMN 24         PIC X(30)  SOURCE BookTitle-BF.
        03  COLUMN 57         PIC ZZ9    SOURCE CopiesRequired-PRF.
        03  COLUMN 63         PIC X(20)  SOURCE LecturerName-PRF.

PROCEDURE DIVISION.
BEGIN.
   DISPLAY "Enter the semester number (1 or 2) - " WITH NO ADVANCING
   ACCEPT Current-Semester
   OPEN INPUT PurchaseReqFile
   OPEN INPUT BookFile
   OPEN INPUT PublisherFile
   OPEN OUTPUT ReportFile
   INITIATE PurchaseRequirementsReport

   MOVE SPACES TO PublisherName-PF
   START PublisherFile
         KEY IS GREATER THAN PublisherName-PF
         INVALID KEY DISPLAY "START Pub file status" FileStatus-PF
   END-START
   READ PublisherFile NEXT RECORD
         AT END SET EndOfPublishers TO TRUE
   END-READ
   PERFORM PrintRequirementsReport UNTIL EndOfPublishers

   TERMINATE PurchaseRequirementsReport
   CLOSE   PurchaseReqFile, BookFile,
           PublisherFile, ReportFile
   STOP RUN.

PrintRequirementsReport.
    SET NotEndOfBooks TO TRUE
    MOVE PublisherNum-PF TO PublisherNum-BF
    READ BookFile
        KEY IS PublisherNum-BF
        INVALID KEY
            DISPLAY SPACES
            DISPLAY "Book File Error.  FileStatus = "  FileStatus-BF
            DISPLAY "Publisher Number - " PublisherNum-BF
            DISPLAY "Publisher Rec = " PublisherRec-PF
            MOVE ZEROS TO PublisherNum-BF
    END-READ

    PERFORM ProcessPublisher
        UNTIL PublisherNum-PF NOT EQUAL TO PublisherNum-BF
              OR EndOfBooks
    
    READ PublisherFile NEXT RECORD
        AT END SET EndOfPublishers TO TRUE
    END-READ.

ProcessPublisher.
    SET NotEndOfPRequirements TO TRUE
    MOVE BookNum-BF TO BookNum-PRF
    READ PurchaseReqFile
        KEY IS BookNum-PRF
        INVALID KEY
           DISPLAY SPACES
           DISPLAY "PurchReqFile Error. FileStatus = " FileStatus-PRF
           DISPLAY "Book Num PRF = " BookNum-PRF
           DISPLAY "Book Rec = " BookRec-BF
           MOVE ZEROS TO BookNum-PRF
    END-READ

    PERFORM UNTIL BookNum-BF NOT EQUAL TO BookNum-PRF
            OR EndOfPRequirements
                IF Current-Semester = Semester-PRF THEN
            Generate PReq-PrintLine
        END-IF
        READ PurchaseReqFile NEXT RECORD
            AT END SET EndOfPRequirements TO TRUE
        END-READ
    END-PERFORM
    READ BookFile NEXT RECORD
        AT END SET EndOfBooks TO TRUE
    END-READ.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.192.247