MODULE 6 · TABLES · 8/8

Module challenge: sales by region and quarter

35 min60 XPExercise

Every sales organisation runs a report like this at the end of each quarter: raw transactions go in, a grid of totals comes out, with a total for each row and each column and a grand total in the corner. Finance reconciles the grand total against the ledger, so it must be exact.

This challenge brings together everything in the module:

  • Hard-coded tables with REDEFINES: the region list, and a month-to- quarter lookup.
  • SEARCH ALL to turn a region code into a table position.
  • SET to convert the index into an ordinary subscript.
  • A two-dimensional table (region × quarter) to accumulate the totals.
  • Row and column totals from nested loops.
  • An OCCURS in the report line, so four columns are filled by one loop instead of four copies of the same code.

Direct lookup by subscript

Not every lookup needs a search. When the key already is a position, such as a month number from 1 to 12, subscript directly:

       01  WS-QTR-VALUES      PIC X(12) VALUE "111222333444".
       01  WS-QTR-TABLE REDEFINES WS-QTR-VALUES.
           05  WS-QTR-OF-MONTH    PIC 9 OCCURS 12 TIMES.
      *    ...
           MOVE WS-QTR-OF-MONTH(SR-MONTH) TO WS-Q

This is only safe after you have checked that the month is 1–12.

Using one table's index on another table

SEARCH ALL WS-REGION leaves REG-IX pointing at the matching region. You then want to add to row n of the sales table. Do not write WS-SALES(REG-IX, WS-Q): REG-IX belongs to a table with 9-byte elements, and on IBM compilers it holds a byte offset calculated for that element size. Convert it to a plain number first:

               WHEN WS-REG-CODE(REG-IX) = SR-REGION
                   SET WS-R TO REG-IX

Now WS-R is 1–4 and works as a subscript for any table.

Rejecting bad input

A batch job should not stop at the first bad record, and it must not silently drop it either. Display each rejected record, count them, and report the count at the end, so operations can see what was left out and why the totals may not match expectations.

On the job

Totals must balance. Here the ALL line's total must equal the sum of the region totals and the sum of the quarter totals. When you write a report program, check both ways as part of your testing. Auditors will.

Your task

Produce the quarterly sales report. Read sales records until END:

Columns Field Picture
1–3 Region code X(3)
4–5 Month 9(2)
6–12 Amount, 2 implied decimals 9(5)V99

NTH030007550 is region NTH, March, 75.50.

Rules

  • Regions are EST (EAST), NTH (NORTH), STH (SOUTH), WST (WEST). They are already in the starter's region table, in code order.
  • Months 1–3 are Q1, 4–6 Q2, 7–9 Q3, 10–12 Q4.
  • A record with a month outside 1–12 or an unknown region code is rejected: display REJECTED: followed by the whole record, as soon as you read it, and count it.

Report (after all input is read):

REGION         Q1         Q2         Q3         Q4       TOTAL
EAST       500.00       0.00       0.00       0.00      500.00
NORTH      200.50       0.00       0.00     300.00      500.50
SOUTH        0.00     200.00       0.00       0.00      200.00
WEST         0.00       0.00       0.00     999.99      999.99
ALL        700.50     200.00       0.00    1299.99     2200.49
REJECTED RECORDS: 02

Every region appears even if it had no sales. The ALL line has each quarter's total across regions and the grand total. The starter provides the heading and a report line (WS-REPORT-LINE) with RL-NAME, RL-QTR(1..4) and RL-TOTAL. MOVE SPACES to it before filling it.

Requirements: look the region up with SEARCH ALL, and accumulate into a two-dimensional table.

fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.