|
View previous topic :: View next topic
|
| Author |
Message |
socker_dad
Active User

Joined: 05 Dec 2006 Posts: 177 Location: Seattle, WA
|
|
|
|
Here's something for us all to chew on.
I have a copybook that has 7 different record layouts defined, each layout with a specific, fixed length. For example, record type 1 is 28 bytes, 2 is 117 bytes, etc. Each record has its own 01 level name.
In the write program, there are 7 output FD's, as we want each record type to be written to its own file.
When the layout of a particular tecord type changes, we just want to have to recompile the program without having to change any coding. This suggests that the FD statement would not define the record length, but that the WRITE statement would pick up the length from the copybook.
Is this possible?
 |
|
| Back to top |
|
 |
CaptBill
New User
Joined: 28 May 2009 Posts: 20 Location: Oklahoma City, OK USA
|
|
|
|
The answer will depend on how you defind each FD and the WRITE statement.
I have not written COBOL is several years, but I'd suggest you define each FD with one record type by using an 01 then an 05 FILLER with the PIC defining the length.
Then as you write a record, use WRITE record FROM copybook name. |
|
| Back to top |
|
 |
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
How about "nesting" the copybooks?
Separate copybook for each 01. Copybook for input file with seven copy statements. Seven individual output files with their individual copybook. WRITE ... FROM ... for the specific 01. When one of the copybooks changes, just recompile (assuming record-type does not change/move). |
|
| Back to top |
|
 |
Robert Sample
Global Moderator

Joined: 06 Jun 2008 Posts: 8700 Location: Dubuque, Iowa, USA
|
|
|
|
COBOL must know the record length for fixed-length files at compile time. COBOL must know the maximum record length for variable-length files at compile time (although using RECORD VARYING with DEPENDING ON allows you to defer record length determination for output records until execution time, the maximum record length must still be known at compile time).
As long as your code meets these restrictions, you will not have any problems. |
|
| Back to top |
|
 |
Bill O'Boyle
CICS Moderator

Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
|
|
| Back to top |
|
 |
Gary McDowell
Active User
Joined: 15 Oct 2012 Posts: 139 Location: USA
|
|
|
|
Robert mentioned variable-length which I use very much. Example something likeā¦
| Code: |
FD OUTPUT-FILE
RECORDING MODE IS V
RECORD IS VARYING
IN SIZE FROM 1 TO 3000 CHARACTERS
DEPENDING ON WS-OUTPUT-LENGTH
BLOCK CONTAINS 0 RECORDS.
01 OUTPUT-FILE-REC PIC X(3000).
WORKING-STORAGE SECTION.
01 WS-OUTPUT-LENGTH PIC 9(08) COMP.
PROCEDURE DIVISION.
MOVE LENGTH OF WS-COPYBOOK-1 TO WS-OUTPUT-LENGTH
MOVE WS-COPYBOOK-1 TO OUTPUT-FILE-REC
WRITE OUTPUT-FILE-REC
MOVE LENGTH OF WS-COPYBOOK-2 TO WS-OUTPUT-LENGTH
MOVE WS-COPYBOOK-2 TO OUTPUT-FILE-REC
WRITE OUTPUT-FILE-REC
Etc. |
|
|
| Back to top |
|
 |
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Yes, if variable-length records of a fixed-length are required(!), use the same field as specified on the VARYING for the input file on all the seven output files.
One problem will come when a record is changed but the file is not converted yet. You'd want that to be noticed. So test the VARYING against the LENGTH OF for the record-layout, and deal with it however you like... |
|
| Back to top |
|
 |
Ed Goodman
Active Member
Joined: 08 Jun 2011 Posts: 556 Location: USA
|
|
|
|
| Is dynamic allocation a possibility? |
|
| Back to top |
|
 |
socker_dad
Active User

Joined: 05 Dec 2006 Posts: 177 Location: Seattle, WA
|
|
|
|
More information: the 7 records are concatenated in fixed lengths within a fixed length copybook:
| Code: |
01 ACT10ETL-RECORD.
03 some header stuff, also fixed length
03 RECORD-TYPE-1.
03 RECORD-TYPE-2.
etc.
|
A record type could be absent, but its positions in the full record as maintained by spaces.
Until the copybook (record layout) changes, the individual lengths will remain constant (as will the overall length of the complete ACT10ETL record.
I understand that COBOL has to know the length of the record at compile time - I was just wondering if there was a way to pick up a length from the copybook....maybe something like
| Code: |
FD SNAPSHOT-FILE
LABEL RECORDS ARE STANDARD
BLOCK CONTAINS 0 RECORDS
RECORDING MODE IS F
RECORD CONTAINS LENGTH(RECORD-TYPE-1).
|
That looks like I'm mixing JAVA & COBOL....Well, this is probably just wishful thinking on my part.
I've considered dynamic file allocation, but it looks like a maintenance nightmare. |
|
| Back to top |
|
 |
Robert Sample
Global Moderator

Joined: 06 Jun 2008 Posts: 8700 Location: Dubuque, Iowa, USA
|
|
|
|
| RECORD CONTAINS requires an unsigned integer so using LENGTH or a variable name will generate a compile error. You may use RECORD CONTAINS 0 to defer final determination of record length until execution time. However, if the length of your 01 under the FD does not match the actual file LRECL in the JCL, you will have problems (such as data truncation) that could be difficult to find. |
|
| Back to top |
|
 |
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
OK, an unexpected development :-)
I'd suggest using SORT (you still using SyncSort?).
Make up a "stub" COBOL program that has the copybook in. Compile, putting the output listing in a dataset.
Process the output listing (SORT, REXX, whatever you like) to generate symbols for your group items representing the records you want to extract. Put these symbols in a member.
| Code: |
ACT10ETL-RECORD,1,whateverlength
some header stuff, also fixed length,=,length,CH
RECORD-TYPE-1,*,length,CH
RECORD-TYPE-2.,*,length,CH
....
OPTION COPY
OUTFIL FILES=1,BUILD=(RECORD-TYPE-1)
OUTFIL FILES=2,BUILD=(RECORD-TYPE-2)
...
|
Don't put any DCB info in the JCL for the output datasets.
When the COBOL copybook changes, regenerate the symbols.
If it is not Production and you want to stick to COBOL,you can consider this. |
|
| Back to top |
|
 |
Dale Robertson
New User

Joined: 21 Jun 2013 Posts: 44 Location: U.S.A.
|
|
|
|
dad,
| socker_dad wrote: |
Here's something for us all to chew on.
I have a copybook that has 7 different record layouts defined, each layout with a specific, fixed length. For example, record type 1 is 28 bytes, 2 is 117 bytes, etc. Each record has its own 01 level name.
In the write program, there are 7 output FD's, as we want each record type to be written to its own file.
When the layout of a particular record type changes, we just want to have to recompile the program without having to change any coding. This suggests that the FD statement would not define the record length, but that the WRITE statement would pick up the length from the copybook.
Is this possible?
 |
It's more than possible. in fact you might consider merely coding only the FD parameters that are necessary and let the operating system do the rest for you. i.e.
FD filename1 BLOCK 0.
COPY A1.
FD filename2 BLOCK 0.
COPY A2.
FD filename3 BLOCK 0.
COPY A3.
FD filename4 BLOCK 0.
COPY A4.
FD filename5 BLOCK 0.
COPY A5.
FD filename6 BLOCK 0.
COPY A6.
FD filename7 BLOCK 0.
COPY A7.
That's all you need for each file. then when the record length changes you not only don't have to rewrite the FD statement you don't even have to worry about the JCL as the operating system takes the DCB from COBOL. Therefore with COBOL don't waste your time coding any DCB parameter in JCL so you won't have anything else to change. i.e.
//filename1 DD DSN=OUT.FILE,DISP=(,C,D),SPACE=whatever
//filename2 DD DSN=OUT.FILE,DISP=(,C,D),SPACE=whatever
//filename3 DD DSN=OUT.FILE,DISP=(,C,D),SPACE=whatever
//filename4 DD DSN=OUT.FILE,DISP=(,C,D),SPACE=whatever
//filename5 DD DSN=OUT.FILE,DISP=(,C,D),SPACE=whatever
//filename6 DD DSN=OUT.FILE,DISP=(,C,D),SPACE=whatever
//filename7 DD DSN=OUT.FILE,DISP=(,C,D),SPACE=whatever
notice that you don't need to code UNIT because at most shops the default is DASD and you don't need to code anything in the DCB because the operating system does your work for you therefore if your LRECL changes you're home free and only need to change your copybook and recompile as you've desired. Of course you DO need to run a test because your file now is different!!!
notice that you do need to code BLOCK in order to invoke SDB [system determined blocksize] so you don't lapse into buffoonery.
Also if you wish to make all of those fixed length files into a variable length file use IEBGENER as it is one of the best and easiest ways to do that. if you like i'll write that for you if you really need it. it's a snap.
Also if your shop allows compressed extended sequential data sets then by compression or compaction using DATACLAS= you will not even have to use variable length files to get the same result - that of better utilizing space at your shop.
r
"Trust me Marion."
--Indiana Jones. |
|
| Back to top |
|
 |
Dale Robertson
New User

Joined: 21 Jun 2013 Posts: 44 Location: U.S.A.
|
|
|
|
dad,
so if you want to allocate a RECFM=VB out of these items that you allocated FB:
| Code: |
//filename1 DD DSN=OUT.FILE1,DISP=(,C,D),SPACE=whatever
//filename2 DD DSN=OUT.FILE2,DISP=(,C,D),SPACE=whatever
//filename3 DD DSN=OUT.FILE3,DISP=(,C,D),SPACE=whatever
//filename4 DD DSN=OUT.FILE4,DISP=(,C,D),SPACE=whatever
//filename5 DD DSN=OUT.FILE5,DISP=(,C,D),SPACE=whatever
//filename6 DD DSN=OUT.FILE6,DISP=(,C,D),SPACE=whatever
//filename7 DD DSN=OUT.FILE7,DISP=(,C,D),SPACE=whatever |
merely duplicate this 6 times:
...IEFBR14... to delete the old cataloged files...then
| Code: |
//JS2 EXEC PGM=IEBGENER
//SYSUT1 DD DSN=OUT.FILE1,DISP=SHR,NCP=10
//SYSUT2 DD DSN=&T1,SPACE=(CYL,1,,MXIG),UNIT=VIO,NCP=10,
// LRECL=32,RECFM=VB,DISP=(,PASS)
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
GENERATE MAXFLDS=1
RECORD FIELDS=(28,1,,1)
/*
... you get the idea...then finally...
//JSFINAL EXEC PGM=IDCAMS
//SYSUT1 DD DSN=&T1,DISP=(OLD,DELETE)
// DD DSN=&T2 etcetera for all 7.
//SYSUT2 DD DSN=FINAL.FILE,DISP=(,C,D),SPACE=whatever,
// LRECL=highest lrecl +4,RECFM=VB
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
REPRO INFILE(SYSUT1) OUTFILE(SYSUT2)
/*
// |
Code'd
good luck |
|
| Back to top |
|
 |
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
Dale, please use the Code tags.
It is not good to just leave compiler diagnostics lying around in a program. I've not worked anywhere that allows it.
soccer_dad changed the requirement part-way through the topic. Did you see that?
The topic has been inactive for over a month. Usually means the TS is not taking part, so suggested solutions are not much use, as they will never be tested by the TS.
Please try to go for questions which are currently active. |
|
| Back to top |
|
 |
|
|
 |
All times are GMT + 6 Hours |
|