Report Writer
This chapter describes how to use COBOL report writer and its Declaratives.
1. Report Files and RD Entries
This section covers all COBOL report writer entries that can be included in the program’s ENVIRONMENT DIVISION and FILE SECTION, and describes the clauses that can be used in the RD entry in alphabetical order.
1.1. Report Files
The COBOL report writer generates output records and automatically writes them to the report file when a program calls GENERATE and TERMINATE. The report file is very similar to other output sequential files. The ENVIRONMENT DIVISION must have an FD clause in the SELECT… ASSIGN clause and FILE SECTION. An FD clause is processed by the OPEN and CLOSE statements of the PROCEDURE DIVISION.
There are additional clauses, but only the 'SELECT file-name ASSIGN TO assignment-name' clause is used in general. OpenFrame does not support additional clauses.
FD entry is similar to a sequential file (refer to FILE-CONTROL Paragraph). You can use the FILE STATUS clause to change back the status of the report file. The order of the clauses is not important.
The report-name can be up to 30 characters long and is constructed following the COBOL naming convention. Each report-name must be the same as the name in the RD of the REPORT SECTION. The REPORTS ARE ALL option that assigns all reports to the same file is not supported in the current version. If multiple report-names are coded in the REPORTS ARE clause, data can be created consecutively or concurrently in the same file.
In general, you should not code record-description-entry after an FD entry because the report writer eliminates the need to code all WRITE statements of the report file. If there is no MODE clause in the SELECT clause and no CODE clause in the RD clause, the program can write to the report file independently of the report writer. In this case, you must specify one or more 01 level record descriptions in the FD entry.
If you want to code the record-description after the FD entry and get a fixed-length record, you must code the RECORD CONTAINS clause even if you specify RECORDING MODE IS F. The integer in the RECORD CONTAINS clause must match the record size.
1.2. REPORT SECTION and RD
Each report description is shown in the REPORT SECTION, the last section of the DATA DIVISION. Just as the FILE SECTION consists of a series of FD entries, the REPORT SECTION consists of RD entries and each RD entry is followed by 01 level entry with the report group description.
Each report description entry consists of one or more report group descriptions.
The report-name must be unique and same as the report-name specified in the REPORT clause of one or more FD entries. If report-name is declared in more than one FD, a UPON clause is required in the INITIATE clause. Each RD entry must have at least one report-group-description.
The record-description-entry supports additional clauses, but OpenFrame only supports CONTROL, LINE LIMIT, and PAGE LIMIT clauses.
1.3. CONTROL Clause
The CONTROL clause codes an additional line, such as a total line or subtitle, that is generated when the value changes in one or more key (control) fields.
A CONTROL clause can code REPORT/FINAL or control-id (identifier list), or both. More than one operand must be coded, and at least one space or line break must be coded between the operands. If there is more than one control-id, a hierarchy exists. If a control break (value change) occurs on the parent control, all the controls on the lower levels break regardless of whether or not the child control breaks. If a control break occurs, CONTROL HEADING is output from the higher level to the lower level. CONTROL FOOTING is output from the lower level to the higher level. However, the control break is not detected unless the GENERATE statement is executed.
If there is a CONTROL HEADING and a CONTROL FOOTING for the control-id, a CONTROL HEADING group is generated each time a new control-id is started, and a CONTROL FOOTING group is generated at the end of the control-id. A CONTROL FOOTING group is created using the control-id value before the control break occurs. You can selectively code CONTROL HEADING and CONTROL FOOTING groups for each control-id, but you can only code one each per control-id. You can code only one of the groups, both groups, or none.
-
REPORT/FINAL
-
REPORT and FINAL are equivalent. REPORT/FINAL must be coded first in the control-id list, but it can be omitted.
-
REPORT/FINAL represents the highest control. Use REPORT/FINAL if you need special action to be taken once only at the beginning and end of the report.
-
-
control-id
-
The control-id must be the name of the data item in the DATA DIVISION. You can include qualifiers or subscripts if necessary, but you can not use special registers, such as PAGE-COUNTER.
-
The PICTURE of a control-id can not contain a 'V' symbol. You can not use the same control-id more than once in the same CONTROL clause, but you can duplicate it in other RDs.
-
1.4. LINE LIMIT Clause
The LINE LIMIT clause represents the maximum number of rows needed for the longest row of the report. This allows you to check if a field can fit within the limits of a row and if any data is lost. If the report field exceeds the value specified in the LINE LIMIT clause, an error occurs at compile time or runtime.
If the LINE LIMIT clause is omitted, it is set to the default value. However, if there is a 'BLOCK or RECORD CONTAINS integer CHARACTERS' clause in the FD entry, the corresponding value becomes the maximum value.
-
integer
-
The coded value represents the maximum number of columns. Make sure that the report does not exceed this value.
-
-
identifier
-
When the width of a line in a report assumes different values at different times, you can use the identifier defined as a numeric field.
-
Report writer evaluates its contents dynamically at INITIATE time. Since this form is used only for REPEATED or WRAP clause, it is recommended not to use it in general.
-
1.5. PAGE LIMIT Clause
The PAGE LIMIT clause divides the report across multiple pages. You can further divide a page into heading, main data, and footing sections. Each subclause is optional, but a subclause can not exist without a PAGE LIMIT clause. Subclauses can be coded in any order, but coding from the top to the bottom of the page is recommended.
-
PAGE LIMIT
-
If the PAGE LIMIT clause is omitted, the report consists of one continuous output stream without page breaks. In this case, report-group-description can not contain any clauses that include absolute lines, NEXT GROUP and PAGE HEADING groups, FOOTING groups, and PAGE keyword.
-
-
HEADING
-
HEADING is not required, but if you have a PAGE HEADING that begins with a relative line, you can use the HEADING as the reference point.
-
If HEADING is omitted, the value of 1 at the top of the page becomes the reference point.
-
-
FIRST DE
-
If you have a PAGE HEADING group, it is a good idea to code FIRST DETAIL so that the body of the page is at a fixed position below it. If the PAGE HEADING group overlaps the FIRST DETAIL position, the first body group is printed immediately after the PAGE HEADING group. If FIRST DE is omitted, the following are the default values:
-
If there is no PAGE HEADING, the HEADING value becomes the default value.
-
If there is PAGE HEADING, the body begins immediately after the PAGE HEADING group.
-
-
-
LAST DE/CH
-
If LAST DETAIL is used, the identifier must be a numeric field and its value must be between the FIRST DETAIL and LAST CONTROL FOOTING positions. CONTROL HEADING and DETAIL groups can not come after LAST DETAIL. If LAST DETAIL is before the LAST CONTROL FOOTING, additional space is created in the CONTROL FOOTING group.
-
If LAST DE/CH is omitted, the following are the default values:
-
If there is LAST CONTROL FOOTING, LAST DETAIL has the same value. In this case, all body groups can go down to the LAST CONTROL FOOTING position.
-
If there is LAST CONTROL FOOTING with the form '+ integer-5', the value of the 'first line of the page footing - 1 - integer-5' is used. Otherwise the default value of LAST CONTROL FOOTING is used.
-
-
-
LAST CF (FOOTING)
-
If you want to have some space before the PAGE FOOTING starts, code LAST CF or FOOTING.
-
If LAST CONTROL FOOTING is omitted, the following are the default values:
-
If there is no PAGE FOOTING, the PAGE LIMIT value is used. In this case, all CONTROL FOOTING groups can go down to the bottom of the page.
-
If there is PAGE FOOTING, it becomes the last row before PAGE FOOTING.
-
-
2. Report Descriptions
This section describes the report description that follows the RD section of the REPORT SECTION.
A report group is a block of any number of contiguous lines in the report. The lines in a report group are always on the same page and are created in a single operation. All of the seven TYPEs except the DETAIL group are created automatically. The program executes one or more GENERATE statements for each DETAIL group (or for the entire report), and any other defined group is automatically created at the correct location according to DETAIL.
You can enter the report group description according to the RD entry, but the allowed number of each TYPE, except DETAIL, is limited. Each report group description begins with a 01 level entry in A-margin.
2.1. Coding Report Group Descriptions
The report group description is a REPORT SECTION data structure that includes descendants starting at level 01. It can only consist of level 01 report group items. You can create any number of report group descriptions after the RD entry.
Description of each clause is provided in the following list in alphabetical order. The list only includes clauses that are supported by OpenFrame. |
-
level-number
-
As in DATA DIVISION, the level-number is used to set a hierarchy of group level higher than the elementary level. The level-number at the beginning of each report group must be 01 level.
-
-
data-name
-
You do not need to put the data-name in a report group item, except in the following cases:
-
Another group that can be referenced in the 01-level entry in the DETAIL group or in the USE BEFORE REPORTING header in a Declarative SECTION.
A report-group-name or group-name represents the entire report group when using data-name at level 01. The group-name must be unique within the RD.
-
A numeric item that is referenced from a SUM clause or term.
-
An item at any level referenced from a COUNT clause or a term.
-
-
-
general-purpose DATA DIVISION clauses
-
The following DATA DIVISION clauses can be used in report groups for general purposes.
The first four are available at both group and elementary levels. PICTURE and VALUE are only allowed at elementary levels.
-
BLANK WHEN ZERO
-
JUST/JUSTIFIED
-
OCCURS
-
SIGN
-
PIC/PICTURE
-
VALUE/VALUES
-
-
The following are not available for report groups:
-
All USAGE clauses other than USAGE DISPLAY
-
REDEFINES
-
SYNC/SYNCHRONIZED
-
RENAMES
-
Level 88 items
-
-
-
special-purpose clauses
-
The following are special-purpose clauses that define the position and contents of each field.
TYPE, NEXT GROUP, GROUP LIMIT, and REPEATED clause can only be used in 01 level. PICTURE, COLUMN, SOURCE, VALUE, SUM, COUNT, and FUNCTION clauses can only be used at the elementary level.
Clause Description TYPE
Defines group type.
NEXT GROUP
Inserts lines of space between groups.
GROUP LIMIT
Sets a lower limit to the group.
REPEATED
Places groups side-by-side.
LINE
Sets the vertical position on the page.
MULTIPLE PAGE
Divides a report group across multiple pages.
COLUMN
Sets the horizontal position on the page.
SOURCE
Identifies the sending data item.
SUM
Sums totals.
COUNT
Counts occurrences.
FUNCTION
Calls specially formatted routine.
WRAP
Wraps data to the next line.
VARYING
Provides a counter for repeated items.
STYLE
Creates special printer effects.
PRESENT/ABSENT
WHEN/AFTER
PRESENT/ABSENT controls the output of items, lines, and groups.
GROUP INDICATE
Same as PRESENT AFTER.
-
-
LINE, COLUMN clause
-
For every item with a COLUMN clause, there must be a LINE clause at the same or higher level.
-
You can combine the LINE and COLUMN clauses into the same item if a particular report line contains only one elementary field (provided that the item is not a multiple-choice item).
03 LINE 5 COL 60 VALUE "REPORT".
-
The number of elementary fields that can be included in a report line is not limited. If the report line contains multiple elementary fields, then all COLUMN items in the line must be coded at a level lower than the LINE item.
03 LINE 5. 05 COL 60 VALUE "REPORT". 05 COL 90 VALUE "TEST".
-
Not all COLUMN clauses in a LINE need to be at the same level, because some or all of the elementary entries may be included in a non-LINE group entry.
03 LINE 5. 05 COL 60 VALUE "REPORT". 05 PRESENT WHEN DATA01 NOT = SPACES. 07 COL 90 VALUE "TEST".
-
-
A LINE clause can not be dependent on another LINE clause.
-
If a report group contains multiple lines, you must specify a level-number other than 01 for all LINE items in that group. You can create a LINE clause on a 01 level entry only if the group contains only one report line.
-
-
SOURCE, VALUE, SUM, COUNT clause
-
You can select one of the clauses (SOURCE, VALUE, SUM, or COUNT) to automatically provide the contents of the elementary entry. For more details, refer to the description in the relevant section.
-
If there is no SOURCE, VALUE, SUM, and COUNT clauses in an entry, the following conditions must be met:
-
The entry must have a data-name.
-
The entry must have a COLUMN clause.
-
If the COLUMN clause is relative, the item must have a fixed vertical position.
-
-
The LINE clause can not be dependent on another LINE clause.
-
If a report group contains multiple lines, you must specify a level-number other than 01 for all LINE items in that group. You can create a LINE clause on a 01 level entry only if the group contains only one report line.
-
You can create report group clauses in any order, except for multiple-choice items where each SOURCE and VALUE operands immediately follow the WHEN condition.
-
2.2. BLANK WHEN ZERO Clause
The BLANK WHEN ZERO clause replaces a numeric field whose value is zero with blanks.
-
BLANK WHEN ZERO
-
If you create BLANK WHEN ZERO in an elementary entry, the entry must have a numeric PICTURE.
-
When applied to a group level entry, it applies to all numeric elementary entries in the group.
-
2.3. COLUMN Clause
The COLUMN clause specifies the horizontal position of the field on the report line.
Coding Rules
The following describes the coding rules for the COLUMN clause.
-
COLUMN without an operand is a shorthand for COLUMN + 1.
-
For each item with a COLUMN clause, there must be a LINE clause at the same or higher level.
-
If there are no other items in LINE 5, specify as follows:
03 LINE 5 COL 60 VALUE "REPORT".
-
If there are more than one field on a line, you must create a new level as follows:
03 LINE 5. 05 COL 60 VALUE "REPORT". 05 COL 90 VALUE "TEST".
-
-
COLUMN can be the only clause in an item. In this case, the blank field is only used to move the current horizontal position to the right. The blank field occupies one column width in addition to the normal spacing for COLUMN. Hence, this creates a VALUE composed of a single space with a COLUMN clause. For example, COL +4 moves the current horizontal position four columns to the right.
-
The size of the item is calculated from the size of the PICTURE clause or VALUE "Literal". If both items are used with the COLUMN clause, check that they do not exceed or overlap the line width.
Operation
The following describes the operation method of the COLUMN clause.
-
The COLUMN clause places the elementary field horizontally.
The options are as follows:
-
COLUMN + integer-1
Relative form. Indicates that the horizontal position within the line is to be moved integer column positions from the last character of the preceding field to the first character of this field. Note that the spacing before the field is one less than the value of the integer. For example:
COLUMN + 1 = No change is applied COLUMN + 2 = A space is inserted before the field
If COLUMN + integer-1 is specified in the first field of the line, it is interpreted as COLUMN integer-1 because the initial horizontal position is 0.
-
COLUMN integer-2
Absolute form. Indicates that the left column of the field must be at the fixed position on the line. The first column of the line is COLUMN 1.
-
-
If there is no COLUMN clause in the elementary entry, then the data-name does not print in the report. This is called an unprintable item.
2.4. COUNT Clause
The COUNT clause counts the number of occurrences of a specified report field or group item.
Coding Rules
The following describes the coding rules for the COUNT clause.
-
Each data-name can be named with any REPORT SECTION entry name except RD. It may be the data-name of a group item containing the COUNT clause.
-
The COUNT clause can be placed in the report group that contains the item being counted or another report group.
-
Unlike the SUM clause, the counted item does not need to be a numeric field.
-
You can use COUNT like the SUM clause as in the following example. You can use a COUNT clause on its own instead of a SOURCE or VALUE clause.
03 LINE 5 COL 60 PIC ZZZ9 COUNT OF R-DATA-NAME.
Operation
The following describes the operation method of the COUNT clause.
-
The COUNT clause counts the number of times the referenced item occurs. That is, count is incremented every time the item is printed on the report. It does not count items that are outside the REPORT SECTION.
The referenced item can be at the following levels:
Level Description 01 level entry
Occurrences of a particular group.
LINE entry
Occurrences of a particular line.
COLUMN entry
Occurrences of a particular elementary entry.
-
If you don’t use the RESET statement, COUNT is reset to 0 when the COUNT field is output. Therefore, you always get the number of occurrences of the item since the last time the count was output. You can use the RESET statement to delay the resetting of COUNT until a higher level of control break occurs. However, the current version does not support the RESET statement of the COUNT clause.
2.5. LINE Clause
The LINE clause positions a line vertically on the page.
Coding Rules
The following describes the coding rules for the LINE clause.
-
The following are available forms of the clause.
-
LINE + integer-1.
Relative form. PLUS may be written in place of +. This advances the line integer-1 lines from the previous position. LINE + 0 or LINE + ZERO is allowed, which suppresses line advance. This results in the line being overprinted on the previous line.
-
LINE integer-2.
Absolute form. This outputs the line at the fixed position on the page. The highest line number allowed is set by the PAGE LIMIT operand. This absolute form is allowed only if there is a PAGE LIMIT clause in the RD.
-
LINE integer-2 ON NEXT PAGE.
This is similar to LINE integer-2 format, but the ON NEXT PAGE statement forces a page advance to occur before the line is output, regardless of whether or not the group containing it fits on the current page.
-
LINE ON NEXT PAGE.
This forces the line to be output in the FIRST DETAIL position on the next page or the HEADING position.
-
LINES ARE integer-1 integer-2 … or LINES + integer-1, + integer-2 …
This enables you to describe several lines in the same clause to save coding effort. For more information, refer to Multiple LINES Clause. You may also use ON NEXT PAGE after the last operand, in which case this phrase applies only to the first line in the set.
-
-
The first LINE clause of each group determines whether the entire group is relative or absolute.
If the first LINE clause is relative, the group is a relative group and all the other LINE clauses must be relative. If the first LINE clause is absolute, the group is an absolute group, and the remaining LINE clauses can be absolute or relative.
For example, the following two LINE clauses within a group are equivalent:
01 TYPE PH. 03 LINE 1. ... 03 LINE 2. ... 03 LINE 4. ...
01 TYPE PH. 03 LINE 1. ... 03 LINE +1. ... 03 LINE +2. ...
Using relative lines has the advantage of changing the position of the entire group by changing only the first line number.
-
Unless the group uses ON NEXT PAGE, the integer value must increment sequentially if there is an absolute LINE clause.
-
A LINE does not need to contain any COLUMN entries. The result is an empty line that contains no data. In the following example, the data is output only on line 2, but PAGE HEADING occupies lines 2 to 4.
01 TYPE PH. 03 LINE 2 VALUE "--PAGE HEADING--" 03 LINE 4.
--PAGE HEADING--
-
One LINE clause must not be dependent on another LINE clause.
Operation
The following describes the operation method of the LINE clause.
If a group is absolute, its first LINE clause indicates the starting position of the group.
-
Positioning of relative body groups (CH, DE, and CF)
-
If the group is the first body group on the page, the first line of the group is positioned at the FIRST DETAIL position, irrespective of the integer of the LINE clause. If you did not specify a FIRST DETAIL subclause in your RD, the first line is output one line after the PAGE HEADING group, if there is one, or at the HEADING position if not. Subsequent lines in the group are positioned relative to each other.
-
If the group is not the first body group on the page, then the first line of the group is positioned relative to LINE-COUNTER, which normally contains the last line position of the preceding body group.
-
-
Page-fit test for body groups (CH, DE, and CF)
When a report has a PAGE LIMIT clause, report writer performs a page-fit test before outputting any body groups. This is to ensure that none of the lines of the group is output unless all the lines of the group fit in the region of the page reserved for its type of body group.
The type of page-fit test performed depends on whether the group is absolute or relative. In all cases, LINE-COUNTER contains the current vertical position, normally the position of the line last output before this group was generated.
-
Absolute page-fit test for body groups
If the first LINE is absolute, the first LINE number is used as the starting position of the group. If LINE-COUNTER is positioned at a line above the starting line position of the group, report writer does not skip to a new page. In all other cases, a page advance takes place and the group is printed at the specified line on a new page.
-
Relative page-fit test for body groups
When all the LINE clauses in the group are relative, report writer totals all the integers of the LINE + clauses. This gives the total size of the group. The value LINE-COUNTER + total-size-of-group is the last line on which the group would be if it were output on the current page. If this last line position is beyond the lower limit of the group, the group can not fit on the page and a page advance occurs.
The lower limit of the group is as follows:
-
LAST DETAIL of RD, if group is DETAIL or CONTROL HEADING
-
LAST CONTROL FOOTING of RD, if group is CONTROL FOOTING
The LAST DETAIL and LAST CONTROL FOOTING subclauses do not need to be explicitly specified in the RD, because the report writer assumes the default values of the subclauses as described under the PAGE LIMIT clause.
-
-
-
Positioning of relative non-body groups (RH, PH, PF, and RF)
Group Description RH, PH
Relative to HEADING - 1.
PF
Relative to LAST CONTROL FOOTING.
RF
Relative to HEADING - 1.
-
Page advance processing
Report writer executes a page advance as follows:
-
PAGE FOOTING is output if it is defined.
-
PAGE-COUNTER is incremented by 1.
-
Advances to the top of the next page. LINE-COUNTER is set to 0.
-
PAGE HEADING is output if it is defined.
-
2.5.1. Multiple LINES Clause
By coding several integer or + integer terms in a LINE clause, you can save time in defining a group of lines with a similar layout.
Note the following:
-
Each time a line occurs, a simple VALUE or SOURCE is repeated. You can use multiple VALUE or SOURCE clauses to place a different value in a report field whenever multiple LINES occur.
-
The following is an example of a multiple LINES clause. The output results are the same for the two groups.
01 TYPE PH. 03 LINES 1 2. 05 COL 1 VALUES "REPORT" "YEAR". 05 COL 11 VALUES "TEST" "MONTH". 05 COL 21 VALUES " " "DAY".
01 TYPE PH. 03 LINES 1. 05 COL 1 VALUES "REPORT". 05 COL 11 VALUES "TEST". 05 COL 21 VALUES " ". 03 LINES 2. 05 COL 1 VALUES "YEAR". 05 COL 11 VALUES "MONTH". 05 COL 21 VALUES "DAY".
Even if a value of VALUES is not specified, specify as many empty literal VALUES as there are the number of LINES.
2.6. LINE-COUNTER
The LINE-COUNTER is an internal special register that stores the most recent report line number on which data was created.
-
LINE-COUNTER stores the current vertical position on the page. It is set to 0 by INITIATE statement and page advance.
-
You can change the value of LINE-COUNTER in the PROCEDURE DIVISION, but make sure that you do not decrease the value of LINE-COUNTER.
03 COL 100 PIC ZZZ9 SOURCE IS LINE-COUNTER.
-
If there are multiple report descriptions in the REPORT SECTION, each report has a unique LINE-COUNTER. Therefore, you must use report-name as a qualifier to specify which report the LINE-COUNTER belongs to.
03 COL 100 PIC ZZZ9 SOURCE IS LINE-COUNTER OF REPORT-01.
2.7. NEXT GROUP Clause
The NEXT GROUP clause creates additional vertical space after a group so that page overflow does not occur when there is not enough space on the page for additional blank lines.
Coding Rules
The following describes the coding rules for the NEXT GROUP clause.
-
NEXT GROUP clause must be coded only at the 01-level.
-
You can use this clause in all body groups (CH, DE, CF), in REPORT HEADING if you have PAGE HEADING, or in PAGE FOOTING if you have REPORT FOOTING.
-
If there is no PAGE LIMIT clause, you can only use the + integer-1 format.
-
You can use NEXT BODY GROUP only in the DETAIL or CONTROL HEADING group, and NEXT DE OR CH GROUP only in the CONTROL FOOTING group.
-
You can also use DE OR CH as DETAIL OR CONTROL HEADING, CH OR DE, or CONTROL HEADING OR DETAIL.
2.7.1. Effect of NEXT GROUP on Body Groups
-
Under certain constraints, the NEXT GROUP clause increases the report writer’s LINE-COUNTER value after all lines in the body group have been created, causing the next body group to be on a new page or after additional vertical spacing.
-
When you code NEXT GROUP + integer-1, the report writer adds integer-1 to LINE-COUNTER, but uses the LAST CONTROL FOOTING value as the maximum limit.
-
NEXT GROUP integer-2 forces the next body group to be created for the specified line number. The report writer first checks the LINE-COUNTER. If this value is less than integer-2 (if the position has not yet been reached), LINE-COUNTER is set to integer-2.
Otherwise, the report writer sets LINE-COUNTER equal to LAST CONTROL FOOTING so that the body group is no longer on the page and stores the value of integer-2 in the integer location of the next saved group. Before the next body group is created, the report writer sets the LINE-COUNTER to the saved integer. It is not recommended to use this form unless the following body group is always a relative group.
-
When you code a NEXT GROUP NEXT PAGE, the report writer sets LINE-COUNTER to the LAST-CONTROL FOOTING value. In this case, the report writer leaves the rest of the page blank and starts the next body group on the next page.
-
If the NEXT GROUP clause is created in the CONTROL FOOTING group, the report writer checks the level of the control break that is being processed before applying the clause being processed. If the level of the break is higher than the level of this group, the NEXT GROUP clause is ignored. That is, the NEXT GROUP clause of CONTROL FOOTING can not affect the position of the next CONTROL FOOTING.
For example, CONTROL FOOTING FOR REPORT does not force a page advance if you have NEXT DE OR CH GROUP NEXT PAGE in the previous CF level.
01 CF FOR STATE NEXT DE OR CH GROUP NEXT PAGE. .... 01 CF FOR REPORT. 03 LINES + 2. ....
In this case, to display CONTROL FOOTING FOR REPORT on a new page, code ON NEXT PAGE in the first LINE clause.
-
You can code a dummy report group that contains only the NEXT GROUP clause. No output occurs when the group is processed, but LINE-COUNTER is set equal to LAST CONTROL FOOTING because of the NEXT GROUP NEXT PAGE clause.
01 CF FOR STATE NEXT GROUP NEXT PAGE.
Instead of directly changing the LINE-COUNTER, you can code as in the following example to obtain a certain spacing at any time. Then, you can code GENERATE LINE-GAP in the PROCEDURE DIVISION.
01 LINE-GAP DE NEXT GROUP + 3.
2.7.2. Effect of NEXT GROUP on Non-Body Groups
-
You can create a NEXT GROUP in the REPORT HEADING group.
In this case, the affected group is the first PAGE HEADING group immediately after REPORT HEADING. NEXT GROUP NEXT PAGE indicates that the REPORT HEADING is a separate page, not the first page above PAGE HEADING. However, the same is true if REPORT HEADING does not fit above the first PAGE HEADING.
-
You can also code NEXT GROUP in a PAGE FOOTING group.
In this case, the affected group is REPORT FOOTING. This format is not necessary because the first LINE clause used in REPORT FOOTING is a better way to handle such case.
2.8. OCCURS Clause
The OCCURS clause displays regular iterations over a field or group of fields in a horizontal dimension, or a line or group of lines in a vertical dimension. However, report writer only supports displaying iterations of lines.
Coding Rules
The following describes the coding rules for the OCCURS clause.
-
OCCURS clause must not be used at the 01-level. It can be used at four levels, but report writer only supports the following level:
-
At the LINE level. The line is repeated vertically as many times as specified by the operand.
03 LINES OCCURS 3. 05 COL + 2 "HELLO".
The result is:
HELLO HELLO HELLO
-
-
If the number of iterations is variable, the DEPENDING ON syntax can be used but is not supported by report writer. You can use integer-1 TO only with the DEPENDING ON clause.
-
You can use the STEP/WIDTH/DEPTH syntax to specify the distance between iterations, but it is not supported.
Operation
The following describes the operation method of the OCCURS clause.
-
To obtain a vertical automatic repetition within a report group, you can use the OCCURS clause to achieve the same effect as coding each entry individually.
-
If the PRESENT WHEN clause is coded in the same entry as the OCCURS clause, the PRESENT WHEN is applied separately for each occurrence.
01 TYPE DE. 03 LINE OCCURS 12 VARYING R-MONTH PRESENT WHEN PROFIT (R-MONTH) > 0. 05 COL 1 PIC X(9) SOURCE NAME-MONTH (R-MONTH). 05 COL 12 PIC $(6)9 SOURCE PROFIT-MONTH (R-MONTH).
The result is:
JANUARY $1000 FEBRUARY $2000 MARCH $3000 ...
2.9. PAGE-COUNTER
The PAGE-COUNTER is a special register that stores the current page number.
-
PAGE-COUNTER is set to 1 by the INITIATE statement, and if the report has a PAGE LIMIT clause, each page advance after the initial page is incremented by 1. The increase occurs between the generation of PAGE FOOTING and PAGE HEADING. The TERMINATE statement leaves PAGE-COUNTER unchanged.
-
PAGE-COUNTER can be treated as a number in the SOURCE clause.
For example, use the following code to print a page number.
03 COL 100 PIC ZZZ9 SOURCE IS PAGE-COUNTER.
-
If your program has more than one report, you must use the report-name as a qualifier to specify which report the PAGE-COUNTER is for.
03 COL 100 PIC ZZZ9 SOURCE IS PAGE-COUNTER OF REPORT-01.
2.10. PICTURE Clause
As in basic COBOL, the PICTURE clause indicates the size and format of each report field.
Coding Rules
The following describes the coding rules for the PICTURE clause.
-
All available PICTURE symbols including a currency symbol defined by a CURRENCY SIGN phrase may be used if they match a DISPLAY field and the rules for combining the symbols are same as for basic COBOL. For information about the PICTURE symbol, refer to the COBOL PICTURE.
-
You can omit the PICTURE clause from an entry with a VALUE clause. ALL PICTURE is required if you use ALL "literal" or a figurative constant, such as QUOTE.
-
If you use a SOURCE or SUM/COUNT clause, you need to use PICTURE even if you want to display the field in the format that it is stored.
2.11. PRESENT/ABSENT AFTER Clause
The PRESENT/ABSENT AFTER clause is similar to PRESENT WHEN, except that it tests the conditions that occur internally in the report writer’s automatic control-break and page advance processing, rather than evaluating a general COBOL condition.
Coding Rules
The following describes the coding rules for the PRESENT/ABSENT AFTER clause.
-
If you specify the PAGE keyword, you must have a PAGE LIMIT clause in the RD. If you specify control-id, it must be one of the controls listed in the CONTROL clause of RD, except that REPORT or FINAL is always assumed to be in the CONTROL clause.
-
This clause can be coded at the group or elementary entry level, and clauses can be nested.
-
You can use the format in all body groups (DE, CH, CF), but if you use the control-id option in a CONTROL HEADING or CONTROL FOOTING group, the referenced control level must be higher than the control level in the PRESENT AFTER clause.
-
You can use the A format in a PAGE HEADING or PAGE FOOTING group, but only when you have the control-id option.
-
Format b can be used only in a body group.
-
Format C is equivalent to the following:
PRESENT AFTER NEW PAGE OR lowest-control-id
In this case, PAGE is present if the report has a PAGE LIMIT clause, and the control-id is present if the report has a CONTROLS clause.
-
It is not recommended to refer to an item of a PRESENT/ABSENT AFTER or GROUP INDICATE in a SUM clause.
Operation
The following describes the operation method of the PRESENT/ABSENT AFTER clause.
-
If you use ABSENT instead of PRESENT, you have exactly the opposite effect.
-
The PRESENT AFTER clause works similar to the PRESENT WHEN clause, except that the conditions are set within the report.
-
PRESENT AFTER NEW control-id
PRESENT WHEN this group has not been output yet, or control break occurs at the level or above since the last output.
-
PRESENT AFTER NEW PAGE
PRESENT WHEN this group has not been output yet or page advance has occurred since the last output.
-
-
PRESENT AFTER NEW control-id
The report writer outputs the field if this is the first time that the report group has been output since the start of the report or after the last control break at the level of control-id or above. For example, if you code PRESENT AFTER NEW YEAR-NO, the report field is generated at the start of the report and at the first GENERATE whenever a higher control level than YEAR-NO or YEAR-NO changes. Otherwise, the field is ignored along with any subordinate entries in the same way as the PRESENT WHEN clause.
In the following example, the field YEAR-NO is printed for the first time and whenever it is changed. SEASON-NO is output for the first time, and then whenever SEASON-NO or YEAR-NO is changed.
RD ... CONTROLS ARE YEAR-NO, SEASON-NO. ... 01 NEW-MEM TYPE DE LINE + 1. 05 COL 2 PIC 9(4) SOURCE YEAR-NO PRESENT AFTER NEW YEAR-NO. 05 COL 7 PIC X(6) SOURCE SEASON-NO PRESENT AFTER NEW SEASON-NO. 05 COL 15 PIC X(20) SOURCE MEM-NAME.
YEAR SEASON NAME 2017 SPRING JOHN ANDREW SUMMER JANE 2018 SUMMER PETER ...
-
PRESENT AFTER NEW PAGE
The report writer outputs the field if this is the first time that this group has been output since the start of the report or since the last page advance. Otherwise, the field is not printed.
-
PRESENT AFTER PAGE OR control-id
If either or both conditions are met, the field is printed. For example, in the previous example, you can print out the YEAR-NO and SEASON-NO fields every time you start a new page, even if there are no changes.
01 NEW-MEM TYPE DE LINE + 1. 05 COL 2 PIC 9(4) SOURCE YEAR-NO PRESENT AFTER NEW YEAR-NO OR PAGE. 05 COL 7 PIC X(6) SOURCE SEASON-NO PRESENT AFTER NEW SEASON-NO OR PAGE. 05 COL 15 PIC X(20) SOURCE MEM-NAME.
-
PRESENT AFTER NEW REPORT
Use PRESENT AFTER NEW REPORT when there is a field, line, etc. that you want to output only once (assuming REPORT or FINAL is the highest control level, and not always in the CONTROL clause).
-
GROUP INDICATE
The GROUP INDICATE clause allows only one item to be output.
2.12. PRESENT/ABSENT WHEN Clause
The PRESENT/ABSENT WHEN clause applies a general COBOL condition to all report entries. By evaluating the condition, the report writer determines whether the item is normally printed or skipped.
Coding Rules
The following describes the coding rules for the PRESENT/ABSENT WHEN clause.
-
If you use ABSENT instead of PRESENT, you have exactly the opposite effect. That is, ABSENT is the same as PRESENT WHEN NOT.
-
A condition can be a valid COBOL conditional expression. For more information, refer to the COBOL conditional expression.
-
You can use the CONTROL IS control-id format only if the current group is a multiple CONTROL FOOTING. That is, it can be used if it is a CONTROL FOOTING clause with multiple control-id operands, or CONTROL FOOTING FOR ALL.
-
PRESENT can be omitted and used in the following case:
... 05 COL 10 PIC X(10) VALUE "OVER LIMIT" PRESENT WHEN AMT > 100. 05 COL 20 VALUE "BLACK" WHEN AMT = 1 VALUE "WHITE" WHEN AMT = 2 VALUE "RED" WHEN OHTER.
-
PRESENT UNLESS is equivalent to ABSENT WHEN.
2.12.1. Multiple-Choice Form
-
If you need to specify a series of substitutions for a specific elementary field, you can specify it as a single entry instead of multiple individual entries containing the PRESENT WHEN clause. You can code an entry with multiple SOURCE or VALUE clauses, each followed immediately by a PRESENT WHEN clause. The PRESENT WHEN OTHER form can be coded only once, if necessary, and placed at the end.
-
The report writer searches for the condition starting from the first condition in the code order until it finds a true condition. It then uses the SOURCE or VALUE clause preceding the PRESENT WHEN clause, and ignores all remaining PRESENT WHEN and SOURCE or VALUE clauses.
-
If you specify only VALUE literal clauses without a PICTURE clause, they may be of different sizes. The size of the field actually produced is the size of the selected value.
-
You can not place multiple-choice items at the same level as a LINE clause.
01 NEW-MEM TYPE DE. 03 LINE 1 COL 1 VALUE "BLACK" WHEN SHADE = 1 "WHITE" WHEN SHADE = 0.
Instead, code as follows:
01 NEW-MEM TYPE DE. 03 LINE 1. 05 COL 1 VALUE "BLACK" WHEN SHADE = 1 "WHITE" WHEN SHADE = 0.
2.13. SOURCE Clause
The SOURCE clause specifies the source field that provides the field contents of the report. The source field is usually outside the REPORT SECTION, but may be defined within the REPORT SECTION.
Coding Rules
The following describes the coding rules for the SOURCE clause.
-
You can use valid COBOL identifiers or arithmetic expressions.
-
If necessary, you can attach qualifier or subscript to each operand as follows:
05 COL 10 PIC 999V99 SOURCE IS DATA01 IN DATA-RECORD (A-NO, B-NO)
Operands can have qualifier, subscript, and index, which are generally allowed in a MOVE statement. You can use relative subscripting and reference modification.
-
You must also code the PICTURE clause in the same entry (unlike VALUE that does not need a PICTURE). The PICTURE must be compatible with the PICTURE of the operands. The length of the two pictures may be different, in which case there may be truncation or space-filling. The rules for the SOURCE clause are the same as those for the MOVE or COMPUTE statement.
-
The SOURCE IS and SOURCES ARE keywords can be omitted except immediately following the VARYING clause. For clarity, it is recommended to code the SOURCE keyword.
-
An expression can be any arithmetic expression as follows:
05 COL 10 PIC 999V99 SOURCE IS DATA01 * DATA02 / 100
The rules for constructing expressions are described in the arithmetic expression of the COBOL PROCEDURE DIVISION. However, it is not recommended to use expressions.
-
If you use a number PICTURE with fewer digits to the right of the decimal point than the SOURCE identifier, you can use the ROUNDED clause for the same entry. This way, instead of always truncating unwanted digits, the resulting value is closer of the two possible values.
05 COL 10 PIC 999V99 SOURCE DATA01 ROUNDED
For example, if DATA01 contains a value of 100.50 or 100.99, the generated value is 101 instead of 100. For more information on the ROUNDED keyword, refer to the COMPUTE statement.
-
You can add a WHEN or UNLESS condition to the SOURCE clause and then add multiple SOURCE and WHEN/UNLESS clauses in the same entry to represent multiple-choice items.
Operation
The following describes the operation method of the SOURCE clause.
-
Rules for Generating Report Field
Since the effect of the SOURCE clause is comparable to the COBOL MOVE or COMPUTE statement, refer to these statement for more information.
SOURCE Clause Format Equivalent Statement identifier
MOVE identifier TO report-filed
identifier ROUNDED
ADD ZERO, identifier GIVING report-field ROUNDED
arithmetic-expression
COMPUTE report-filed = arithmetic-expression
arithmetic-expression ROUNDED
COMPUTE report-filed ROUNDED = arithmetic-expression
CURRENT-DATE and TIME-OF-DAY use the conceptual data items DATE and TIME.
-
Reference to Controls
If the SOURCE clause directly or indirectly references the CONTROL operand and fetches SOURCE at CONTROL FOOTING time, report writer uses the contents of the control identifier before the control break. That is, you can get the contents of the control fields before the break in the following report groups:
-
Every CONTROL FOOTING
-
PAGE FOOTING and PAGE HEADING when a page advance occurs
-
2.13.1. Multiple SOURCES
If you create more than one identifier or expression after the keyword to use multiple formats of the SOURCE clause, you do not have to code multiple line items. However, you must note the following:
-
You can include NONE as a keyword to indicate that there is no content stored in a specific field.
-
You can use an input with multiple LINES clauses. Multiple COLUMNS clauses are not supported.
-
The number of items in multiple SOURCES must be equal to the number of items defined in multiple LINES.
Consider the following example where multiple SOURCES are used with multiple LINES:
... 03 LINE 1 2. 05 COLUMN 1 PIC X(04) SOURCE YEAR MONTH. ...
The previous code is equivalent to:
... 03 LINE 1. 05 COLUMN 1 PIC X(04) SOURCE YEAR. 03 LINE 2. 05 COLUMN 1 PIC X(04) SOURCE MONTH. ...
2.14. SUM Clause
The SUM clause automatically forms the sum of other numeric fields.
Coding Rules
The following describes the coding rules for the SUM clause.
-
You can code a SUM clause as a clause on its own instead of a SOURCE or VALUE clause as follows:
05 COL 10 PIC 999V99 SUM OF SALE.
It can be coded with an expression or as a part of an expression, but it is not supported in the current version.
-
The item summed can be either of the following two items:
-
The name of the numeric data item in the REPORT SECTION. To use this, you must specify the name of the data in the REPORT SECTION column to aggregate.
05 R-SALES COL 10 PIC 99999 SOURCE SALE.
You can construct a sum by creating SUM OF R-SALES on other items in the report. This is called the SUM clause of the REPORT SECTION. The SUM operator can not have subscripts and arithmetic symbols. You can only use the SUM OF data-name.
05 COL 10 PIC 999999 SUM OF R-SALES.
The data items mentioned in the SUM clause can be created with report-name, such as SUM R-SALES IN SUMMARY-SALES.
-
An identifier or expression of a numeric type outside of the REPORT SECTION. This format is similar to the operand of the SOURCE clause. This is called the non-REPORT SECTION SUM clause. Expressions are currently not supported.
-
-
The report can contain as many entries with SUM clauses in any group TYPE. Only elementary entries can use the a SUM clause.
-
When coding the UPON statement, each group-name must be the name of the DETAIL group and different from the group currently being defined.
-
If the SUM clause is in the DETAIL group and the operand in the SUM clause is not in the REPORT SECTION, the report must contain multiple DETAIL groups and the UPON statement must be logically coded to specify the GENERATE for the adding to take place.
-
When coding RESET statements, the control-id operand must be one of the ones defined in the CONTROL clause of the report. If you are currently defining a CONTROL FOOTING group, the control level of RESET ON must be higher than the level of this group.
-
The RESET statement can not be defined anywhere in a multiple CONTROL FOOTING group.
Operation
The following describes the operation method of the SUM clause.
The report writer automatically performs summation, display, and reset (setting the sum to zero).
-
Totaling
The method used for the totals depends on whether or not the item referenced by SUM is the data-name of the REPORT SECTION item.
-
REPORT SECTION SUM
Each time the original data item in the SUM clause is output, the referenced item is added to the total field. If the summed REPORT SECTION data item contains a SOURCE or VALUE clause, the amount added to the sum is the SOURCE or VALUE operand that is outside the REPORT SECTION, not the intermediate REPORT SECTION field.
For example, the fields (S-FLD1, S-FLD2) added to the total are 10 and SALES, not R-FLD1 and R-FLD2.
05 R-FLD1 COL 1 PIC 999 VALUE 10. 05 R-FLD2 COL 10 PIC 9999 SOURCE SALES. ... 05 S-FLD1 ... SUM OF R-FLD1. 05 S-FLD2 ... SUM OF R-FLD2.
There are two names that are used to distinguish between two cases of totaling.
-
Cross-Footing
The following items are in the same report group as the SUM clause. For the SUM item, it is better to code the items that calculate the sum in physical order.
01 SALES-TOTLAS CF FOR CITY. 03 LINE + 2. 05 R-T-SALES COL 31 PIC $(6)9 SOURCE VAL-THIS-YR. 05 COL 31 PIC $(7)9 SUM OF R-T-SALES. 03 LINE + 1 COL 31 VALUE "----------------------".
You must avoid the following cyclic dependencies.
05 R-A ... SUM OF R-A ... or 05 R-A ... SUM OF R-B ... 05 R-B ... SUM OF R-A ...
-
Rolling Forward
In the following example, the item to be summed is in a SUM group of a different report group.
01 SALES-DETAIL DETAIL. 03 LINE + 1. 05 COL 1 PIC X(20) SOURCE SALES-DESC. 05 R-T-SALES COL 31 PIC $(6)9 SOURCE VAL-THIS-YR. 05 R-L-SALES COL 41 PIC $(6)9 SOURCE VAL-LAST-YR. 01 SALES-TOTLAS CF FOR CITY. 03 LINE + 2. 05 COL 1 PIC X(20) VALUE "TOTLAS". 05 COL 31 PIC $(7)9 SUM OF R-T-SALES. 05 COL 41 PIC $(7)9 SUM OF R-L-SALES. 03 LINE + 1 COL 31 VALUE "----------------------".
The value to be added is displayed in DETAIL, and the sum is displayed in CONTROL FOOTING.
You can also use this SUM method in one of the following ways:
-
Lower level CONTROL FOOTING to higher level CONTROL FOOTING
-
DETAIL to DETAIL
-
Any group to a REPORT FOOTING
-
Any body group to a PAGE FOOTING
-
PAGE FOOTING to a CONTROL FOOTING
-
-
-
Non-REPORT SECTION SUM
This sum is accumulated from values outside the REPORT SECTION. This is usually called subtotalling. Since the identifier or expression is outside the REPORT SECTION, the following rules are important because it is not as clear as with the REPORT SECTION SUM clause when the values are added to the total.
-
When SOURCE SUM correlation is applied, addition occurs when DETAIL is generated in which the identifier in the SUM clause contains the same identifier as a SOURCE item.
-
If you use the UPON statement, addition occurs when DETAIL specified in the statement is generated.
-
If SOURCE SUM correlation is not applied and there is no UPON statement, addition occurs for each GENERATE referencing the report.
Almost all totalling can also be done through the REPORT SECTION SUM clause.
-
-
-
Showing the total
When an item containing SUM is output, the most up-to-date unchanged sum is used as an internal "source" of the field contents. If the code is:
05 COL 5 PIC $$,$$$,$$9.99 SUM R-SALES.
The internal total field is moved to this report field and edited according to the PICTURE specified following the same rules as the SOURCE clause.
-
Resetting the total
The sum is reset (initialized to zero) at the end of processing for the defined report group, unless you override this value using the RESET statement. Therefore, the total field remains available in the same group until the contents are deleted.
Note the following:
-
When adding a value to a sum, the report writer follows the ADD statement rules. If there is a size error, a runtime error is displayed.
-
If the program has more than one report, rolling forward is not restricted within a report. A SUM clause in one report can represent a numeric data item named in another report. Like a single report sum, the referenced field value is added every time the field is output.
All the total fields in the report are initialized via the INITIATE statement. Therefore, if you need to perform a SUM from one report to another, you must make sure that both reports are initialized when you start processing.
-
The PRESENT WHEN clause can test any fields referenced in the conditional operator. However, an entry with a SUM clause or summed by a SUM clause must not be included in the range.
2.14.1. Using Total Fields
If a data-name is specified in an entry that contains a SUM clause, the report writer associates the data-name with its own internal total field, not the external field in the report line, as in the SOURCE or VALUE clause.
Compare the following two cases:
-
With SOURCE etc.
05 R-PAYMENT COL 11 PIC $(7)9.99 SOURCE IS WS-PAYMENT.
The R-PAYMENT field is an actual report line field except when referenced in a SUM clause, and WS-PAYMENT is the added item.
-
With SUM
05 TOT-PAYMENT COL 11 PIC $(7)9.99 SUM OF WS-PAYMENT.
The TOT-PAYMENT field is the internal total field of the REPORT SECTION. Anything that is in the report line field has no name.
The following describes how to use the internal total field and the total field.
-
Internal total field
The internal total field is a pure numeric, signed computational field with as many integer and decimal places as the SUM entry. This prevents losing precision when the total field is stored in the report field.
If the SUM clause refers to a REPORT SECTION item, the precision of the sum field increases, if necessary, and has at least the same integer and scale as the entry being totalled. So the total has at least the precision of the field being totalled, and rounding or truncation occurs when the field is output rather than during accumulation.
PICTURE in SUM Entry PICTURE of SUM Operand if in REPORT SECTION PICTURE of Internal Total 99999
(not in REPORT SECTION)
S9(5) COMP
ZZZ9.99
ZZ9.99
S9(4)V99 COMP
$(6)9-
$(5)9.99-
S9(6)V99 COMP
Note that the sum field always has a sign even if the report line field is unsigned.
-
Accessing the Total Fields
You may access the internal total field directly in the following ways:
-
SOURCE clause
You can get an internal total field that contains a SOURCE clause as a single operand item.
The value depends on the category of the accessed total field as follows:
-
SOURCE that refers to a total field defined in the same report group
In this case, you always get the exact value of the specified sum. This is useful when you want to create a non-printable total in a non-REPORT SECTION without losing precision.
Compare the following two cases:
... 05 TOT-PAYMENT COL 11 PIC S9(6).99 SUM OF WS-PAYMENT. 05 COL 21 PIC -(6)9 SOURCE TOT-PAYMENT. ...
... 05 COL 21 PIC -(6)9 SUM OF WS-PAYMENT.
In the first case, the sum is not truncated if the SUM operand is a REPORT SECTION data-name. However, in the second case, since the internal total field implicitly becomes PICTURE S9 (6), the fractional value is not guaranteed. Therefore, you can not obtain an accurate value.
-
SOURCE that refers to a total field not defined in the same report group
This is useful when you want to get the cumulative value at that moment if the total SUM field references a non-REPORT SECTION item or an item in another report group. SUM items accumulate gradually in certain parts of the report, so you can get versions of all states up to the final sum.
-
-
PRESENT WHEN clause
By checking the value of the sum field in the PRESENT WHEN condition, you can control what is generated in the report group.
... 05 TOT-PAYMENT PIC S9(6).99 SUM OF WS-PAYMENT. 05 LINE + 2 PRESENT WHEN TOT-PAYMENT NOT = ZERO. 07 COL 1 VALUE "TOTAL :". 07 COL 11 PIC -(6)9 SOURCE TOT-PAYMENT. ...
In this example, the value of TOT-PAYMENT may or may not be printed depending on the PRESENT WHEN condition.
-
2.14.2. RESET Phrase
As mentioned earlier, the total field is reset to zero at the end of the group’s processing. You can control what is reset using the RESET statement.
-
If RESET ON control-id is specified, the total field is not initialized until the corresponding control-id occurs.
Consider the following example. The definition of REPORT is as follows:
RD SALES-REPORT ... CONTROLS YEAR MONTH. ... 01 SALES-DETAIL DETAIL. 03 LINE + 1. 05 COL 20 PIC ZZZ9.99 SOURCE AMOUNT. 01 CONTROL HEADING FOR YEAR. 03 LINE + 1. 05 COL 1 PIC X(5) VALUE 'YEAR:'. 05 COL 10 PIC X(4) SOURCE YEAR. 01 CONTROL FOOTING FOR MONTH. 03 LINE + 1. 05 COL 1 VALUE 'TOTALS '. 05 COL 10 PIC X(3) SOURCE MONTH. 05 M-SUM COL 20 PIC ZZZ9.99 SUM OF AMOUNT. 05 Y-SUM COL 30 PIC ZZZ9.99 SUM OF AMOUNT RESET ON YEAR.
The RESET statement is not specified for M-SUM, but not for Y-SUM.
... YEAR: 2018 100.00 200.00 TOTALS JAN 300.00 300.00 50.00 TOTALS FEB 50.00 350.00 300.00 100.00 TOTALS MAR 400.00 750.00 ... YEAR: 2019 100.00 150.00 TOTALS JAN 350.00 350.00 ...
The value of M-SUM is output every time a MONTH control break occurs, and the value is accumulated after it is reset to 0. If the RESET statement is specified for Y-SUM, it will continue to accumulate without being reset until a YEAR control break occurs.
2.15. TYPE Clause
The TYPE clause is used at level 01 to indicate which of the seven report groups is being defined.
Here control-id is the identifier of the CONTROL(S) clause or the word REPORT or FINAL. |
Coding Rules
The following describes the coding rules for the TYPE clause.
-
TYPE clause can be coded only for level 01 entries. The TYPE IS keyword can be omitted. If the TYPE clause for the group is not coded, it is considered TYPE DETAIL.
-
All TYPEs in a report group are optional regardless of the situation, but all reports must have at least one body group (DE, CH, CF).
-
You can only use the OR PAGE, PAGE HEADING, and PAGE FOOTING phrase in a CONTROL HEADING group if the RD has a PAGE LIMIT clause.
-
In CONTROL HEADING and CONTROL FOOTING, each control-id operand is selected from the control list in the CONTROL clause, including REPORT or FINAL, which is always assumed to be present.
-
If you code CONTROL HEADING without the control-id operand, you must not have more than one control-id in the CONTROL clause. The clause means CONTROL HEADING FOR control-id if there is only one control-id in the CONTROL clause; CONTROL HEADING FOR REPORT if there is no CONTROL clause.
-
If more than one control-id is created in CONTROL FOOTING, the result is a set of multiple CONTROL FOOTING report groups. However, the current version does not support multiple CONTROL FOOTINGs.
-
If CONTROL FOOTING is coded without a control-id operand, it means CONTROL FOOTING FOR ALL or CONTROL FOOTING FOR control-id if there is one control-id in the CONTROL clause, and CONTROL FOOTING FOR REPORT if there is no CONTROL clause.
-
All reports can have multiple DETAIL report groups, but only one PAGE HEADING, PAGE FOOTING, REPORT HEADING, and REPORT FOOTING, and only one CONTROL HEADING and CONTROL FOOTING for each control-id. If CONTROL FOOTING FOR ALL is coded, it must be the only CONTROL FOOTING in the report.
Operation
You can use the TYPE clause to indicate where and how to create the group implicitly in the report. The following describes how to process each TYPE.
TYPE | Description |
---|---|
REPORT HEADING |
This group is output only once at the beginning of the report. |
PAGE HEADING |
This group is created as the first group on each page. |
CONTROL HEADING |
This group is automatically output at the beginning of each control’s actual value. |
DETAIL |
All report groups that are not one of the other six report groups are TYPE DETAIL. The DETAIL group is the only group of reports that can be explicitly GENERATED in the program. The other six TYPEs of the report group are created automatically whenever the DETAIL group is needed before processing. |
CONTROL FOOTING |
This group is automatically output at the end of each control’s actual value. |
PAGE FOOTING |
This group is created as the last group of each page. |
REPORT FOOTING |
This group is output only once at the end of the report. |
OR PAGE Clause of the CONTROL HEADING
You can add an OR PAGE clause after the control-id operand for TYPE CONTROL HEADING. This creates a CONTROL HEADING at the top of each page, and allows you to repeat essential information after each general PAGE HEADING. The exact operation rules are as follows:
-
If a report contains a TYPE CH group with an OR PAGE clause, the CONTROL HEADING group is printed after the control break at that level, as when there is no PAGE option. In addition, the processing at the time of page advance is further modified as follows:
-
If a DETAIL group triggers a page advance, the CONTROL HEADING group is output after a normal page advance. If more than one CH group has the OR PAGE option, the CH groups are output in a hierarchical order from highest to lowest. Each CH is also printed on a new page whether or not it fits on the previous page.
-
If the CONTROL HEADING group is the cause of the page advance, it behaves as previously described. Except when the CONTROL HEADING group that triggered the page advance is output to the new page only once regardless of whether or not the OR PAGE statement is present.
-
If the CONTROL FOOTING group triggers a page advance, it behaves the same as DETAIL except when the CONTROL HEADING below the CONTROL FOOTING level is not output.
-
-
If there is a CH FOR PAGE with no control-id in the group, it is assumed to be CH FOR PAGE OR REPORT.
2.16. VALUE Clause
You can use the VALUE clause when the output report field includes a fixed literal value.
Coding Rules
The following describes the coding rules for the VALUE clause.
-
You can specify a literal including a figurative constant.
-
The PICTURE clause is not required unless you specify ALL or a figurative constant. For example:
05 COL 10 VALUE "*** REPORT START ***".
-
You can use an ALL literal, a numeric literal, or a figurative constant, but in all these cases you must use a PICTURE clause.
2.16.1. Multiple VALUES
If you use a multiple VALUES clause, you can specify multiple literals after the keyword instead of coding individual entries separately.
Note the following:
-
If you do not want to specify a value for a particular occurrence, you can code it with a space character (" ").
-
The input can be used with multiple LINES clauses.
-
The rule for the number of literals allowed in multiple VALUES must match the number of iterations in the multiple SOURCES clause.
2.17. VARYING Clause
The VARYING clause varies the value of a numeric counter that creates a repeating field.
Coding Rules
The following describes the coding rules for the VARYING clause.
-
The VARYING clause allows you to use any number of data-name operands with a FROM and BY clause, but the current version supports data-name operands that do not include a single FROM and BY clause. If the FROM and BY clause is omitted, it is treated as FROM 1 and BY1.
-
The clause can be used only with an OCCURS clause or multiple LINES clauses.
-
The data-name must not already be defined elsewhere in the program, and must not be defined separately. Report writer generates description for it internally, as COBOL does with index-names.
Operation
The following describes the operation method of the VARYING clause.
-
When VARYING clause is used with an OCCURS clause to produce the first occurrence, it places the FROM value of 1 in an internal named data item set up implicitly by the VARYING clause.
-
The following is an example of creating a repeated field using a VARYING clause.
03 LINE. 05 COL + 2 PIC Z9 OCCURS 10 VARYING C-INDEX SOURCE C-INDEX.
The result is:
1 2 3 4 5 6 7 8 9 10
3. Report Statements
This section describes the statements used in the report writer.
The COBOL report writer does not run until you execute a statement used in the report writer. There are three main statements: INITIATE, GENERATE, and TERMINATE.
INITIATE and TERMINATE are performed at the beginning and end of report processing, respectively, and GENERATE while executing repeatedly can generate one DETAIL. These three main statements can be used in any place in the program, except for the USE BEFORE REPORTING Declarative SECTION, in the same way as other COBOL statements.
-
Operation Sequence
For a single report that uses a simple file as input, a typical sequence of report writer operations is as follows:
-
OPEN file once at start
OPEN INPUT input-file OPEN OUTPUT report-file
-
INITIATE report writer once at start
INITIATE report
-
Perform for each record in input file
GENERATE detail-group or report
-
TERMINATE report once at end
TERMINATE report
-
CLOSE file once at end
CLOSE input-file CLOSE report-file
-
3.1. GENERATE
The GENERATE statement is the basic syntax for the COBOL report writer to generate output. It passes control to the report writer to perform all necessary tasks, including control-break and page-break processing needed before generating all the lines and fields described in the DETAIL group.
You can not code GENERATE in the Declarative USE BEFORE REPORTING directive. |
-
detail-group-name
-
If GENERATE detail-group-name is coded, it must be the name of the DETAIL group coded in the current program or the name in the GLOBAL report defined in the containing program. The group name is printed immediately after the 01 level.
-
-
report-name
-
GENERATE report-name has a special meaning and is known as summary report format. Do not use this format unless you only need the CONTROL HEADING or CONTROL FOOTING groups in the body of the report at the time of GENERATE because it suppresses DETAIL groups. If you use this format, report must have at least one CONTROL HEADING or CONTROL FOOTING.
-
Operation
The following describes the operation method of the GENERATE statement.
The GENERATE statement causes the report writer to perform three main operations in a typical report.
-
Checks for control breaks and creates CONTROL FOOTING and CONTROL HEADING if necessary.
-
Checks for page-fit, advances pages, and creates PAGE FOOTING and PAGE HEADING if necessary. It can also be caused by CONTROL HEADING or CONTROL FOOTING.
-
Creates each line for the DETAIL group if you do not execute a GENERATE report-name.
Once the report is INITIATEd, the program can execute a GENERATE statement for each DETAIL group in the report. If the Report Description contains multiple DETAIL groups, you can code a series of different GENERATE statements in any part of the program. This allows you to create the desired report layout. You can also create a GENERATE for the same DETAIL group in more than one place in the program.
A summary report that encodes report-name instead of detail-group-name after GENERATE has the following effects:
-
No DETAIL group is output.
-
All rolling forward of the SUM operand is performed as usual except that it is rolling forward in a DETAIL group.
-
All cross-footings of the SUM operand are performed as usual except when cross-footing in a DETAIL group.
-
Subtotalling of a SUM operand not in a REPORT SECTION is executed as follows:
-
When correlation between SOURCE operands and SUM operands is applied, all SUM operands corresponding to SOURCE operands in the DETAIL group are added to the sum as if each DETAIL group is GENERATEd in turn. SUM operands that do not match the SOURCE operand and are not in the REPORT SECTION are added to the sum only once.
-
If the SOURCE SUM correlation is not applied, the SUM operand is added to the sum only once.
-
-
Control breaks are performed as usual. When a control break is detected, all CONTROL FOOTING and CONTROL HEADING groups are printed as usual together with any required PAGE FOOTING and PAGE HEADING groups when a page advance occurs.
The GENERATE report-name statement can only generate output after a control break and after an INITIATE on the first GENERATE. Between an INITIATE and TERMINATE, the program can execute both GENERATE report-name and GENERATE group-name statements.
Processing Cycle
You must execute INITIATE before processing the report.
-
On the first GENERATE after INITIATE, the following operations are performed.
-
If there is a REPORT HEADING group, REPORT HEADING is created.
-
If there is a CONTROL HEADING group, it is created from the highest to the lowest level, and the initial value of each control is saved.
-
If a THROUGH clause is used, literal-4 and literal-5 must be an alphanumeric item of length 1.
-
-
If not the first GENERATE after INITIATE, report writer compares each control identifier with the previous stored value starting from the highest level. If control is not changed, no special action is taken. When a control break occurs, the following control break behavior occurs:
-
Each control-id value is temporarily changed to the value just before the control break.
-
If CONTROL FOOTING group exists, it is generated from the lowest level CONTROL FOOTING to CONTROL FOOTING at the level where the control break occurred.
-
The control-id value is restored to the value after the control break.
-
If there is a CONTROL HEADING group, it is generated from CONTROL HEADING at the level where the control break occurred to the lowest level CONTROL HEADING.
Since the CONTROL HEADING and CONTROL FOOTING groups are independent report groups created with their own permissions, some same operations apply to them as for a DETAIL group.
-
If there is a USE BEFORE REPORTING section for the group in the DECLARATIVES, then that section is executed.
If a line is being created and there is a PAGE clause in the report, check LINE-COUNTER to see if the page needs to be advanced before the group is printed. When a page advance is required, the following operations are performed:
-
If there is a PAGE FOOTING group, a PAGE FOOTING is generated.
-
PAGE-COUNTER increases by one.
-
If PAGE HEADING group exists, PAGE HEADING is generated.
-
If there is a CONTROL HEADING group specifying OR PAGE, it is created from the highest to the lowest level.
3.2. INITIATE
The INITIATE statement must be the first report writer statement that is executed for a report.
INITIATE can not be coded in the USE BEFORE REPORTING directive of a Declarative. |
-
report-name
-
Each report-name must be the name of the current program’s report or the GLOBAL report defined in the embedded program.
-
-
UPON
-
If there is a UPON statement, each report-name must be defined in a REPORT(S) clause in the FD of the specified file-name. If the report-name is defined in multiple FD entries, the UPON statement must be used.
-
If the UPON statement is present, the report is written only to the specified file. However, the current version does not support the UPON syntax.
-
Operation
You must perform INITIATE on the report before you run GENERATE or TERMINATE on the same report (or DETAIL of the report).
A report file must be OPENed before it is INITIATEd. INITIATE does not OPEN the file. However, you can execute INITIATE again for a report that has been TERMINATEd without closing and reopening the file.
Do not execute CLOSE on the file to which the report is sent once the report is INITIATED, unless you execute TERMINATE first.
Processing Cycle
The following describes each step of executing the INITIATE statement.
-
If the identifier form of the LINE LIMIT clause is coded, the identifier is validated and stored in the report control area if valid.
-
LINE-COUNTER is reset to zero.
-
PAGE-COUNTER is set to 1.
3.3. SUPPRESS PRINTING
The SUPPRESS PRINTING statement can prevent a specific report group from being printed under certain conditions.
-
SUPPRESS PRINTING
-
A SUPPRESS PRINTING statement can only be coded in the USE BEFORE REPORTING directive of a Declarative.
-
-
MOVE integer TO PRINT-SWITCH
-
MOVE 1 TO PRINT-SWITCH is comparable to SUPPRESS PRINTING.
-
MOVE 0 TO PRINT-SWITCH can be used to undo the effect of SUPPRESS PRINTING.
-
Operation
SUPPRESS PRINTING or MOVE 1 TO PRINT-SWITCH prevents the group specified in USE BEFORE REPORTING from generating output. That is, there is no data set in any lines of the group, and no line is generated. LINE -COUNTER remains unchanged, so page advance is suppressed. This statement suppresses only the storing of the report data and the output of the lines.
Each execution of SUPPRESS PRINTING or MOVE 1 TO PRINT-SWITCH prevents output only on that particular occasion. The report writer resets PRINT-SWITCH to 0 whenever it moves to the USE BEFORE REPORTING section.
3.4. TERMINATE
TERMINATE must be the last report writer statement that executes for each report.
TERMINATE can not be coded in the USE BEFORE REPORTING directive of a Declarative. |
-
report-name
-
The report-name must be the name of the report in the current program or the GLOBAL report name defined in the containing program.
-
Operation
You must execute TERMINATE for all reports that are INITIATEd before the program is finally terminated. Print the last CONTROL FOOTING, PAGE FOOTING, and REPORT FOOTING groups that may be needed at the end of the report. PAGE-COUNTER and LINE-COUNTER contain the final values from the end of the report, but the total field is zero. You must separately CLOSE the related report file. TERMINATE does not CLOSE the file.
If you run TERMINATE without executing the GENERATE statement for the report after INITIATE, no output is generated. If you want at least REPORT HEADING and REPORT FOOTING groups to be printed, you must GENERATE an empty DETAIL group before TERMINATE.
The report can be INITIATEd and TERMINATEd again at any time without closing the report file. The new INITIATE returns PAGE-COUNTER back to 1, and if there is a PAGE LIMIT clause, it restarts the report again on a new page.
Processing Cycle
The following describes each step of executing the TERMINATE statement.
-
When at least one GENERATE is performed, the value of each control-id temporarily changes to the value at the time of the last GENERATE execution, and each CONTROL FOOTING group is generated from the lowest level to the highest level.
-
If there is a PAGE FOOTING group, a PAGE FOOTING is generated.
-
If there is a REPORT FOOTING group, a REPORT FOOTING is generated.