MODULE 8 · SEQUENTIAL FILES · 3/8

Writing files, filtering and reformatting

15 min30 XPExercise

A huge share of batch programs follow one shape: read a file, pick out the records you want, rearrange them, and write a new file for the next job step. Once you can read a file, writing one is a small step.

Two files at once

Each file gets its own SELECT and FD. You can open several files in one OPEN statement, and close them in one CLOSE:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. COPYDEMO.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT CUST-IN  ASSIGN TO CUSTIN
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT CUST-OUT ASSIGN TO CUSTOUT
               ORGANIZATION IS LINE SEQUENTIAL.
       DATA DIVISION.
       FILE SECTION.
       FD  CUST-IN.
       01  IN-REC.
           05  IN-ID          PIC X(6).
           05  IN-NAME        PIC X(20).
           05  IN-COUNTRY     PIC X(2).
       FD  CUST-OUT.
       01  OUT-REC            PIC X(40).
       WORKING-STORAGE SECTION.
       01  WS-EOF             PIC X VALUE "N".
           88  END-OF-FILE    VALUE "Y".
       01  WS-LINE.
           05  WS-NAME        PIC X(20).
           05  FILLER         PIC X(3) VALUE " / ".
           05  WS-ID          PIC X(6).
       PROCEDURE DIVISION.
       0000-MAIN.
           OPEN INPUT CUST-IN
                OUTPUT CUST-OUT
           PERFORM 8000-READ
           PERFORM UNTIL END-OF-FILE
               IF IN-COUNTRY = "IE"
                   MOVE IN-NAME TO WS-NAME
                   MOVE IN-ID   TO WS-ID
                   WRITE OUT-REC FROM WS-LINE
               END-IF
               PERFORM 8000-READ
           END-PERFORM
           CLOSE CUST-IN CUST-OUT
           STOP RUN.

       8000-READ.
           READ CUST-IN
               AT END SET END-OF-FILE TO TRUE
           END-READ.

Given a CUSTIN dataset of

C00042GRACE HOPPER        US
C00107MAEVE BINCHY        IE
C00200JOHN BOOLE          IE

it writes to CUSTOUT:

MAEVE BINCHY         / C00107
JOHN BOOLE           / C00200

WRITE and WRITE ... FROM

WRITE record-name writes the FD's record area. WRITE OUT-REC FROM WS-LINE first moves WS-LINE into OUT-REC, then writes it. Building the output in WORKING-STORAGE has a practical advantage: FILLER items there can carry VALUE clauses (like the " / " separator above), which are not allowed on records in the FILE SECTION (only 88-level condition names may have VALUE there).

If you build the record directly in the FD record area instead, start with MOVE SPACES TO the record. Otherwise its FILLER bytes contain whatever was there before.

Signed numbers in text files

A text dataset needs a visible sign. The clause SIGN IS LEADING SEPARATE puts it in its own byte in front of the digits:

       05  ACCT-BALANCE   PIC S9(7)V99
                          SIGN IS LEADING SEPARATE.

The field is then 10 bytes: -000004550 is minus 45.50, and +000123456 is 1,234.56. There is no decimal point in the data; V only marks where it is, as always.

Filtering and reformatting

  • Filtering: only WRITE when a condition holds. Count what you read and what you wrote, and display both at the end.
  • Reformatting: the output layout can differ completely from the input: fields reordered, dropped, edited for humans (-(7)9.99), or padded with separators.

OPEN OUTPUT always creates a new, empty file, even if nothing is written. An empty output file is a valid result ("no overdrawn accounts today"), and later job steps rely on it existing.

On the job

Extract programs like these are the glue between systems: a nightly job pulls yesterday's overdrawn accounts for the collections team, new customers for the marketing system, closed accounts for archiving. The reformatting is usually specified in an interface spec: a table of fields, positions and pictures, just like the one in this exercise.

Your task

The collections team wants a daily file of overdrawn accounts.

Input, DD name ACCTIN (line sequential), the account file:

Field Picture Positions
ACCT-NO X(8) 1–8
ACCT-NAME X(20) 9–28
ACCT-BRANCH X(4) 29–32
ACCT-BALANCE S9(7)V99 SIGN IS LEADING SEPARATE 33–42

Output, DD name ODOUT (line sequential): one record for each account with a balance below zero, in this layout (already declared in the starter as OD-REC):

Field Picture
OD-BRANCH X(4)
FILLER X (space)
OD-ACCT-NO X(8)
FILLER X (space)
OD-NAME X(20)
FILLER X (space)
OD-BALANCE -(7)9.99

For example:

COR1 10000002 ALAN TURING               -45.50

At the end, display the control totals:

READ:    00005
WRITTEN: 00002
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.