IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Reading COBOL Variable length file with multiple layouts


IBM Mainframe Forums -> COBOL Programming
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
venuhunev

New User


Joined: 26 May 2007
Posts: 70
Location: chennai

PostPosted: Mon May 21, 2012 1:27 pm
Reply with quote

Hi,

I have a problem in reading a variable file in a COBOL program which uses copybook having multiple layouts.

My actual file record length is 151 (155 in JCL) and Block size is 23467. since the file is existing and cannot change attributes, I am not sure how to solve it.
No Abends or any other errors. I am splitting detail 1 and detail 2 record along with header record. So I just read it and direct the input to specific output.

Following is an example of the problem what I face.

Quote:
Copybook layouts:
Code:
01 Record
   05  gen-record   pic x(45).
01 Header.
    05  hdr-record   pic x(20).
01 Detail1
     05 dtl1-record  pic x(25).
01 Detail2
     05 dtl2-record  pic x(35).
01 Trailer.
    05  TRL-record   pic x(20).



When I read the input file in program record by record, i am getting few details from next record as well (bolded ones below are from next records)

Input file:
Code:
0ASD11 20120112 11100
11232134123 123zecv 123123123
2123124212312323 123231 asdasdsad
999999 20120112 1234569978


When I read and displayed the first record in the program,
0ASD11 20120112 1110011232134123 123ze

Second record is displayed as
11232134123 123zecv 123123123212312421

Third record is displayed as
2123124212312323 123231 asdasdsad99999

Last record is displayed correctly as there are not more records further.
999999 20120112 1234569978



My guess is because of Block size. But I am not sure.
Kindly help me to overcome this while reading.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon May 21, 2012 1:41 pm
Reply with quote

What are you DISPLAYing?

With multiple types of record, you should have something on the record to tell you which layout to use. If you use the wrong layout to DISPLAY a particular record, then you well get more/less data shown than expected (sometimes, when lucky, a S0C4).

Nothing to do with anything except defining more/less data than exists (ie using the wrong record-layout, ie coding error - at least from what you have explained so far).
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8696
Location: Dubuque, Iowa, USA

PostPosted: Mon May 21, 2012 2:40 pm
Reply with quote

As Bill says, depending upon what -- exactly -- you are doing, it does not appear there's an error or even anything to change. The system fills the buffer when it does a read; if your COBOL program attempts to reference data past the length of the currently defined record then you'll see data from the next record(s). This behavior is the way COBOL works and has worked for many, many, many years -- so there's not much chance you are going to be able to change it.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon May 21, 2012 2:55 pm
Reply with quote

Just to add, you blocksize is not very good for a 3390 track. Wasting 10k per track, or close to 1/6 of the space available.
Back to top
View user's profile Send private message
venuhunev

New User


Joined: 26 May 2007
Posts: 70
Location: chennai

PostPosted: Mon May 21, 2012 2:57 pm
Reply with quote

I am displaying all 01 variables when reading each record.

READ INFILE.
DISPLAY RECORD.
DISPLAY HEADER.
DISPLAY TRAILER.
DISPLAY DETAIL1.
DISPLAY DETAIL2.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon May 21, 2012 3:11 pm
Reply with quote

Well, there's your problem.

I don't know what RECORD represents, presumablye you've carefully hidden the real name from us, as RECORD is a reserved word, but the other record areas would seem to relate to the first byte of data.

So, 88 for the first byte

Code:
evaluate true
   when 88-says-detail-1
    display detail1
   when 88-says-detail-2
    display detail2
   when 88-says-header
    display header-record
   when 88-says-trailer
    display header-record
   when other
    whoops, theres something unusual here
end-evaluate


Your FD, in this case, is getting to look at the whole block of data, and there will be a number of buffers/blocks following. When you "read" a record, if there is data left in the block, your FD will just be pointed to it. If the block is finished but other blocks have already been read, you will be pointed to the first record in the next block. If all blocks/buffers have been "read", a new physical read will be done to get the next set of blocks/buffers for you, and you will be pointing to the first record in the first block.

If you are using a record layout longer than the current record, you will "see" the begining of the next record, possibly in the next block/buffer.

Basically, don't do it. Only use the record layout which matches the current record.
Back to top
View user's profile Send private message
venuhunev

New User


Joined: 26 May 2007
Posts: 70
Location: chennai

PostPosted: Mon May 21, 2012 3:19 pm
Reply with quote

Thanks for your replies.. sorry, I have edited my reply.

I actually dont need display in my code. I just did it to know what was wrong.

My file is Variable (151). Atleast one of the record layout should be 151. So I have a 01 varaible which is RECORD.

File Structure:
header record layout is 40
detail1 record layout is 50+10 (where last 10 bytes are not mandatory kinda comments)
detail2 record layout is 40
Trailer record is 40.

When i execute READ INFILE for the first time, it takes 40 bytes of HEADER record as the layout is for 40 bytes.
But my detail1 record layout varies as the last 10 bytes are not mandatory. so my detail1 record could be 50 bytes or 55 bytes.

Consider my first detail1 record which is 50 bytes, but my read statement populates 50 bytes from first detail1 record and 10 bytes of next record.
Back to top
View user's profile Send private message
dbzTHEdinosauer

Global Moderator


Joined: 20 Oct 2006
Posts: 6966
Location: porcelain throne

PostPosted: Mon May 21, 2012 3:30 pm
Reply with quote

all you have provided us is the info that you have no idea what is going on.

you need to provide, FD, i/o statements (at a minumum)
before anyone can provide you with the info that you need.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon May 21, 2012 3:37 pm
Reply with quote

We didn't really expect that you were only interested in DISPLAY. The comments apply to the records, not to any Cobol verbs.

You started off by telling us you had multiple layouts in a copybook. What you showed were different sizes, so you'd have a variable-length-record file.

Now, possibly, you are telling us that the records themselves can also be different lengths but the same type.

If that is what you mean, then there must be something on the record which distinguishes between the "fixed" part of the record for a particular type and the "variable" part, and within the fixed part there should be something which, usually indirectly, indicates the length (as in presence) of the variable part.

If you have 10 bytes which are there sometimes and not there at others, there must be something to indicate that. Only access the extra 10 bytes when the "something" is true.
Back to top
View user's profile Send private message
venuhunev

New User


Joined: 26 May 2007
Posts: 70
Location: chennai

PostPosted: Mon May 21, 2012 3:37 pm
Reply with quote

FD INFILE
LABEL RECORDS ARE STANDARD
RECORDING MODE IS V
BLOCK CONTAINS 0 RECORDS
RECORD 151 CHARACTERS.
COPY COPY1.


I gave 151 characters like FB. I think I should give RECORD VARYING 40 to 151.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon May 21, 2012 3:44 pm
Reply with quote

The shortest record you showed previously was 20 bytes.

If that is the FD you ran with, and managed to display all your records to the end, you'll not get much different if you do 20/40 to 151.

You have to use, in your program, every time, only the data which belongs to the current record.

To do that, you have to know the record type.

And if the record, by type, can be variable you have to know what tells you it is variable, and use that. Normally this would be an indicator or a count.

Only access the variable part if you know there is data there belonging to the current record.

Otherwise you will be copying data from the subsequent record(s) and even, on occasion, accessing storage you are not allowed to (possible when final record in final current block/buffer) and getting an S0C4.

Before looking at anything else, know which record it is, and use the correct layout.

Before looking at anything variable, know if/how many are present.

No problem, just normal stuff.
Back to top
View user's profile Send private message
dick scherrer

Moderator Emeritus


Joined: 23 Nov 2006
Posts: 19244
Location: Inside the Matrix

PostPosted: Mon May 21, 2012 7:23 pm
Reply with quote

Hello,

READing INTO a working-storage variable that has redefines for each record type may help you reduce confusion(personally, i believe this is a better way to code also).
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Mon May 21, 2012 8:43 pm
Reply with quote

Click here - www.ibmmainframes.com/viewtopic.php?p=191731&highlight=#191731

In the FD, you only need a single 01 area defined to the largest-length record.

As Dick has suggested, issue your READ into the largest WORKING-STORAGE area, defined to the largest maximum-length.

Then, check the value in WS-INPUT-LGTH and you'll know which type of record you have, because it will be set to the length of the record just read.

Once you've determined the record-length, you can them move it to the correct area.
Back to top
View user's profile Send private message
venuhunev

New User


Joined: 26 May 2007
Posts: 70
Location: chennai

PostPosted: Tue May 22, 2012 5:16 am
Reply with quote

thanks everyone for the suggestion... infact.. solution.... it worked icon_smile.gif
Back to top
View user's profile Send private message
dick scherrer

Moderator Emeritus


Joined: 23 Nov 2006
Posts: 19244
Location: Inside the Matrix

PostPosted: Tue May 22, 2012 9:05 am
Reply with quote

Good to hear it is working - thank you for letting us know icon_smile.gif

d
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Tue May 22, 2012 11:23 am
Reply with quote

Mmmm.... I was afraid of that.

You have a max record-length (data) of 147 bytes. For more than 100 bytes, with the definitions you have shown, you are effectively going to "guess" whether theres is something there or not.

For that extension, you have more than one field. If more than one field of those more than one fields is not there, then you are lost.

Good luck.
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> COBOL Programming

 


Similar Topics
Topic Forum Replies
No new posts How to split large record length file... DFSORT/ICETOOL 10
No new posts Replace each space in cobol string wi... COBOL Programming 3
No new posts PARSE Syntax for not fix length word ... JCL & VSAM 7
No new posts INCLUDE OMIT COND for Multiple values... DFSORT/ICETOOL 5
No new posts Extracting Variable decimal numbers f... DFSORT/ICETOOL 17
Search our Forums:

Back to Top