MainframeMaster

REFORMAT Deep Dive

The REFORMAT statement defines exactly how the joined output record is built from the two JOINKEYS files. You can specify multiple segments from each file, in any order: F1:position,length and F2:position,length. The output record is the concatenation of all segments in the order you list them, so the total length is the sum of every length. You can omit the join key, include it once, or include it from both files; you can pick non-contiguous ranges from either file. This page is a deep dive on REFORMAT: segment order, length calculation, how unpaired records are filled, and how to design the layout for downstream use.

JOINKEYS / REFORMAT
Progress0 of 0 lessons

Segment Syntax: F1:position,length and F2:position,length

Each item in REFORMAT FIELDS= is either F1:position,length or F2:position,length. Position is the starting byte in that file’s record (1-based). Length is how many bytes to copy. So F1:5,10 means bytes 5–14 from the first file; F2:1,20 means bytes 1–20 from the second file. The two files can have different record lengths; you are only specifying which ranges to pull and in what order. The output record has no "gaps"—each segment is placed immediately after the previous one.

Multiple Segments and Order

You can list as many F1: and F2: items as you need, in any order. For example:

text
1
REFORMAT FIELDS=(F1:1,10,F2:11,60,F1:11,30)

Output: first 10 bytes of F1 (e.g. key), then 60 bytes from F2 starting at position 11 (bytes 11–70 of F2), then 30 bytes from F1 starting at position 11 (bytes 11–40 of F1). Total length = 10 + 60 + 30 = 100 bytes. So you can reorder fields: put the key first, then part of F2, then more of F1. The order in the list is the order in the output.

Examples of REFORMAT items and meaning
ItemMeaning
F1:1,80Bytes 1–80 from the first file (full record if length 80).
F2:11,70Bytes 11–80 from the second file (70 bytes); skips bytes 1–10 of F2.
F1:1,10,F2:1,10Key from F1 then key from F2 (key duplicated in output).
F2:1,20,F1:1,80First 20 bytes of F2, then full 80 bytes of F1 (order is your choice).

Output Length = Sum of All Lengths

The joined record length is always the sum of the length value in every F1: and F2: item. Position only says where to read from in each file; it does not change the output length. So plan your downstream record length (e.g. SORTOUT LRECL, copybook, or program) to match this sum. If you add or remove a segment, recalculate the total.

Including or Omitting the Join Key

The join key is used by JOINKEYS for matching; it does not have to appear in REFORMAT at all, or it can appear once (from F1 or F2) or twice (from both). If the key is at 1–10 in both files and you want it once at the start of the output, use F1:1,10 (or F2:1,10). If you want key plus other F1 fields then F2 fields, you might use F1:1,80 (key plus rest of F1) and F2:11,70 (skip the key in F2 to avoid duplicate). It is up to you; REFORMAT does not enforce uniqueness of the key in the output.

Non-Contiguous Ranges

You can skip bytes in either file by choosing position and length. For example F1:1,20 and F1:41,40 takes bytes 1–20 and 41–80 from F1 and omits bytes 21–40. So you can drop fields (e.g. a large filler) or reorder by listing non-contiguous segments. There is no requirement that segments be contiguous within one file.

Unpaired Records: How the Other Side Is Filled

When you use JOIN UNPAIRED, unpaired F1 records are written with the F1 segments containing real data and the F2 segments filled with blanks (character) or low values (e.g. zeros for numeric). Unpaired F2 records have F2 segments with real data and F1 segments blank/low. So every output record has the same length and layout; the "missing" side is blank/low so downstream can detect unpaired rows by testing those bytes.

REFORMAT and Downstream Processing

Design REFORMAT so that the output layout matches what the next step expects: record length, field positions, and (if applicable) which bytes indicate unpaired (blank/low). If a program or another SORT step expects the key in a specific position, put the key segment there. If you need to flag unpaired rows, ensure the F1 or F2 "fill" area is at a fixed position and length so you can INCLUDE/OMIT or test it easily.

Full Example: Key Once, Then F1 Data, Then F2 Data

text
1
2
3
4
5
JOINKEYS F1=MASTER,FIELDS=(1,8,CH,A) JOINKEYS F2=DETAIL,FIELDS=(1,8,CH,A) REFORMAT FIELDS=(F1:1,80,F2:9,72) JOIN UNPAIRED,F1 SORT FIELDS=COPY

Join key is bytes 1–8 in both files. Output: full 80 bytes of F1 (including key at 1–8), then bytes 9–80 of F2 (72 bytes—F2 data after the key, so the key is not duplicated). Total 80 + 72 = 152 bytes. Unpaired F1 rows have bytes 81–152 blank/low.

REFORMAT vs INREC/OUTREC

REFORMAT is only for JOINKEYS: it builds the joined record from two files. INREC and OUTREC reformat a single record stream (one input). So in a join step you do not use INREC/OUTREC to define the join layout; you use REFORMAT. After the join, if you needed to further reformat the joined stream, you could use OUTREC in a subsequent SORT step that reads the join output.

Explain It Like I'm Five

You have two lists (F1 and F2). When two lines match, you make one new line. REFORMAT is the rule for that new line: "Take this chunk from the first list and that chunk from the second list, and stick them together in this order." You can take several chunks from the first list and several from the second, in any order you want. The new line is exactly as long as all those chunks added up. If one list has no match, we still write a line but fill the "other list’s" part with blanks so you can see it’s missing.

Exercises

  1. Write REFORMAT to produce: 20 bytes from F1 starting at 1, then 30 bytes from F2 starting at 5, then 15 bytes from F1 starting at 21. What is the output length?
  2. You want the join key (10 bytes at 1–10 in both files) only once at the start, then 70 bytes of F1 (11–80) and 60 bytes of F2 (11–70). Write the REFORMAT FIELDS= and give the output length.
  3. How would a downstream step identify rows where F2 had no match (F1 portion blank)?
  4. Can you put F2 segments before F1 segments in REFORMAT? Give an example.

Quiz

Test Your Knowledge

1. REFORMAT FIELDS=(F1:1,20,F2:5,10,F1:21,30). What is the output record length?

  • 60 bytes
  • 20 + 10 + 30 = 60 bytes; you can have multiple F1 and F2 segments, and the total length is the sum of all segment lengths
  • 50 bytes
  • 80 bytes

2. In REFORMAT, do the positions in F1: and F2: refer to the same output buffer?

  • Yes, they are output positions
  • No—F1:position,length means position and length in the first join file; F2: means position and length in the second file; output is built by concatenating the specified segments in the order listed
  • Only F1 uses positions
  • Positions are in bytes from the start of the join key

3. For an unpaired F1 record, what goes into the F2 segments in the REFORMAT output?

  • The last matched F2 record
  • Blanks for character areas and low values (e.g. zeros) for numeric areas; the output record length stays the same
  • Nothing; F2 segments are omitted
  • Spaces only

4. Can you include the join key in the output more than once?

  • No, the key appears only once
  • Yes—you can list F1:1,10 and F2:1,10 (if the key is at 1–10 in both); the key would then appear twice in the output, or you can include it from only one file
  • Only from F1
  • The key is never in REFORMAT

5. What is the main difference between REFORMAT and OUTREC in a join step?

  • They are the same
  • REFORMAT defines the joined record from two files (F1 and F2) and is used with JOINKEYS; OUTREC reformats a single record stream and is not used to build the join layout—that is REFORMAT’s role
  • OUTREC is used for joins
  • REFORMAT is only for inner join