Sunday, December 16, 2018

How to extract last byte of each record in VB and FB file using DFSORT


Hello,

In this post, I'll be showing how to extract last byte of each record, from a VB and FB file (in zOS).  I prefer using IBM's DFSORT utility to complete this task.

The last byte in a record might be anywhere within the record. 

Let's switch to apply our thinking process on real world example. Let's assume that we have a word document with following sentences.

My favourite number is 7
My favourite destination is Bhutan
I love Mainframes
I love IBM DFSORT
I love COBOL
You have this task of extracting the last letter of each sentence. As you see, the last letter is occurring in different positon for each sentence. With rich set of formatting tools in Word, we can align the sentences to look something like the below.



My favourite number is 7
My favourite destination is Bhutan
I love Mainframes
I love IBM DFSORT
I love COBOL


Right! Now that all the sentence are aligned to the right side, it's pretty much easy to read out the last letters in each sentence. You can even write a code to scan the word document and read last position of each sentence in the word document.

Let's switch back to Mainframes. Let's start with FB file. I'll be using JUSTIFY option in DFSORT. JUSTIFY option will align the data to make it look more presentable.

Access Left-justifying and right-justifying data to learn more about JUSTIFY.

I have created a FB file with LRECL of 80 and with some records as shown in the Picture 5.1  below.
Picture 5.1

I have prepared a JCL with some DFSORT statements as shown in Picture 5.2. I have preferred to format the records before sorting by using INREC FIELDS. Basically, with JUSTIFY, I am aligning each record to the right side, so that, the last byte, wherever it may be in the record, will be FORCED to occupy the 80th position, as the LRECL is 80.
Picture 5.2

Now, I can use OUTREC FIELDS to write the 80th byte to output. See Picture 5.3 for output.
Picture 5.3

We can do the same stuff with VB files, but we have to take care of two things. RDW and SHORT records.
  • RDW (Record Descriptor Word) is a 4 byte field describing the record. The first 2 bytes contain the length of the logical record. 
  • SHORT records: A variable-length input record may be too short to contain all specified control fields. A short record causes DFSORT to issue message ICE218A and terminate. 
Here's a VB file with LRECL 84 and with a record as shown in Picture 5.4 below. The record is 28 byte long (4bytes RDW + 24 bytes of record).
Picture 5.4

I have prepared a JCL as shown in Picture 5.5. 
Picture 5.5

I've used INREC IFTHEN to,
  1. align the record to the right side
  2. check if the logical record length (access first 2 bytes of RDW for the length) is less than the LRECL of the file and overlay the 84th byte with a blank. This will ensure short records are being padded with blanks and will prevent DFSORT from terminating.  Note that this will change the actual length in RDW (0028) to 84.
The output after submitting the JCL is shown in Picture 5.6.
  
Picture 5.6

Hope this helps. Use the Comments section below, to share your thoughts on this article. 


Screenshot courtesy: Mainframe access obtained via Master the Mainframe contest run by IBM.


4 comments:

  1. Super , very informative Srini , keep it up.

    ReplyDelete
  2. Glad that you found it to be informative! Keep coming here.

    ReplyDelete
  3. When you specify jusify=right, what will be the position of 7 and you overlayed 84 with blank. Then how we will get 7 in output it should be blank. Can you explain i am confused here

    ReplyDelete
    Replies
    1. That was a good catch. The second WHEN condition isn't executed as the WHEN=INIT condition alters the record length (which is stored in the first 2 bytes) of the first record from 28 to 84. Therefore, the second WHEN condition is unnecessary (and confusing) in the SORT statements that I've used. I just wanted to let the readers know about the SHORT RECORD issue and a method to overcome it.

      Delete