MainframeSupports
tip week 44/2011:

In some situations I need to re-read a file from a certain point. This typically happens when consecutive data are spread across more than one record. Until recently I used an internal buffer to store the data already read. If I then needed to access these data I processed them using the buffer. The problem with this solution is that the buffer typically has an upper limit for its maximum size. If you reach this limit you have to do something else.

One of my colleagues suggested that I could open two files against the same dataset. One of the files acts as the primary source for data while the other acts as the buffer. I think this is a brilliant solution which I hereby pass on to you using an example. Input to the following program may look like this:

INIT A
DATA BELONGING TO A
INIT B
DATA BELONGING TO B
X IN POSITION ONE TRIGGERS DISPLAY OF ALL DATA BELONGING TO PREVIOUS INIT
MORE DATA BELONGING TO B
INIT C
DATA BELONGING TO C
AND SO ON

And here is the program written in COBOL. I have only included the most important stuff. You must add missing divisions and sections and apply indentations, if you want to copy and try it. If you prefer PL/I the trick is to use TITLE on OPEN FILE:

input-output section.
file-control.
    select somefile assign to somefile
      file status is someStatus.
    select othrfile assign to othrfile
      file status is othrStatus.
data division.
file section.
fd  somefile
    recording mode is F.
01  somedata pic x(80).
fd  othrfile
    recording mode is F.
01  othrdata pic x(80).
working-storage section.
01  someStatus pic 9(2).
01  someCount  pic s9(9) binary.
01  othrStatus pic 9(2).
01  othrCount  pic s9(9) binary.
...
open input somefile
move 0 to someCount
open input othrfile
move 0 to othrCount
read somefile
read othrfile
perform until someStatus not = 0
  if someData(1:1) = 'I' and someCount not = othrCount
    perform until othrCount = someCount or othrStatus not = 0
      add 1 to othrCount
      read othrFile
    end-perform
  end-if
  if someData(1:1) = 'X'
    display othrData
    add 1 to othrCount
    read othrFile
    perform until othrData(1:1) = 'I' or othrStatus not = 0
      display othrData
      add 1 to othrCount
      read othrFile
    end-perform
    perform until someData(1:1) = 'I' or someStatus not = 0
      add 1 to someCount
      read someFile
    end-perform
  else
    add 1 to someCount
    read somefile
  end-if
end-perform
close somefile
close othrfile
goback
.

The first thing you might wonder about is the assign of two different files. In COBOL you need to have two different DD names in the corresponding JCL in order to acheive the functionality I wish for. Please note that I only test the first character in input. The most important part of the program is to wind the buffer file up to the next consecutive chunck of data. I control the winding process using the variables someCount and otherCount. I believe it can be coded more elegant, but I could not dream up anything smarter. Other adjustments may apply depending on the task you have to solve.

The result of executing the above program using the above input is the folowing output on SYSOUT:

INIT B
DATA BELONGING TO B
X IN POSITION ONE TRIGGERS DISPLAY OF ALL DATA BELONGING TO PREVIOUS INIT
MORE DATA BELONGING TO B

The job step to execute the program may look like this:

//MYSTEP   EXEC PGM=MYBUFPG
//STEPLIB  DD DISP=SHR,DSN=MY.LOAD.DATASET
//SYSOUT   DD SYSOUT=*
//SOMEFILE DD DISP=SHR,DSN=MY.INPUT.DATA
//OTHRFILE DD DISP=SHR,DSN=*.SOMEFILE

I have not found any method to provide input using a //SOMEFILE DD * and a reference to OTHRFILE. If you know how to do this I will be happy to hear about it. When using DSN=*.SOMEFILE on DD card OTHRFILE you avoid the specification of the same dataset name twice.

Previous tip in english        Forrige danske tip        Tip list