B1. | Pre-requisites and Game-Plan for record layout conversions. |
reform1 - load original cobmap into an Indexed file for use by reform2. | |
reform2 - generate uvcopy job to reformat data file records, based on | |
old cobmap (indexed file) & new cobmap (sequential input). | |
- new cobmap (copybook layout) has been modified as desired | |
(expand date-fields, move fields, unpack fields, etc) |
C1. | Sample copy-books to demonstrate date field expansion (old/new) |
C2. | Sample data file to test/demo the reform2 procedures (before/after) |
D1. | uvcopy skeleton job using option m0 (1 instruction per field) |
D2. | uvcopy skeleton job using option m1 (combine same type fields) |
D3. | uvcopy complete job with correct data file names (& ISAM keys if nay) |
D4. | uvcopy complete job with option m4 (combine all fields between dates) |
E1. | Conversion Sub-routines provided for alpha/numeric/packed/binary fields |
- conversions provided for all combinations | |
E2. | Options controlling century insertion, field conversions, |
& date formats (yymmdd default, options for mmddyy or ddmmyy) | |
E3. | Overriding generation time options on the bal rfm__ subrtns |
(ie - overrid global default options for selected fields) | |
E4. | Table of date-field-names to controls date expansions. |
- disabled, but could be reinstated | |
- date-fields recognized because of 2 byte length difference |
F1. | Preparation for generating reformat job (1 file at a time) |
F2. | Generating & Executing a reformat (date expansion) job |
F3. | Options for reform2 (generate reformat job from copybook) |
- options controlling field expansions |
G1. | Overview |
G2. | Preparation for generating reformat jobs (ALL Files in Directory) |
G4. | Generating reformat (date expansion) jobs |
G5. | Executing reformat (date expansion) jobs |
G6. | Alternative jobs (reform1a & reform1b) for sites that have duplicate |
fieldnames in copybooks due to qualification. |
Goto: Begin this document , End this document , UVSI Home-Page
H1. | Sample File & Copybook with redefined records for multiple record types |
H2. | Sample uvcopy job generated from Copybook with multiple record types |
H3. | Changes to uvcopy job required for files with multiple record types |
I1. | Sample COPYBOOK for files with DATES in OCCURS |
I2. | Sample uvcopy job generated from Copybook with DATES in OCCURS |
I3. | Changes to uvcopy job required for files with DATES in OCCURS |
I4. | Alternate (no obsolete) solution for files with DATES in OCCURS |
J1. | Sample copybooks (cpy1/warmat2) before & after expansion |
J2. | Sample data-files to illustrate problems |
J3. | generated uvcopy job (pfr2/warmat2) before & after corrections |
K1. | genrfm1 - script to perform multiple steps to generate uvcopy reformat |
jobs (1 at a time). Intended for regens after correcting copybooks. |
L1. | Summary of uvcopy jobs documented in this section |
- mkctlf1, cobmap1, reform1, reform2, reform2.sub, uvdata52 |
M1. | Sample of the 'reform2.sub' sub-routines called by generated jobs |
Goto: Begin this document , End this document , UVSI Home-Page
These jobs will save you a lot of time (& money) whenever you need to modify record layouts. Two significant examples are converting mainframe records prior to loading Data-Bases & expanding date fields for the Year-2000.
For loading data-bases, you must convert any packed fields to zoned numeric and separate any redefined areas. For Year-2000 conversions, you may wish to expand all 2 digit years to 4 digits.
The 'reform2' job will automatically generate the uvcopy instructions to convert your records, based on two versions of the copybook (the original and your new desired layout). To convert packed fields to zoned, you would simply create a new version of the copybook with all 'comp-3's removed.
To expand date fields you would create a new version of the copybook with the date fields expanded (2,4,or 6 digits expanded to 4,6,or 8). When reform2 sees this situation, it will automatically generate the code to right adjust the data and to insert '19' in the first 2 bytes.
For sites that have 6 digit dates where the year may already have exceeded '99', there is an option to insert 19 or 20 depending on the 1st 2 bytes of the field greater or less than a pivot point (default 50). There is also an option not to insert the 19/20 if the field is blank/zero.
Non-standard dates requiring special processing are easily accommodated by these utilities. There is a standard instruction to convert between any 2 formats of calendar, julian, or days-since-1900. The interpretive instruction set has all the power to do whatever other manipulations you may need.
Please note the flexibility provided by generating interpretive instructions, and then giving you the opportunity to modify them when required. This is far more flexible than a black box utility that is designed to perform the task internally.
For files that have 'redefined' records, you will have to add code to test the record type & process the records accordingly. This can not be done automatically because the copybook does not include the record type info.
If desired you can also rearrange fields, because reform2 will read the new copybook sequentially, but randomly read the original copybook which is loaded into an indexed file (keyed on fieldname).
If your main interest is Year 2000, you should also see DATEjobs for COBOL source program problem detection, AGEjobs to create test files,& CMPjobs to compare directories of data files after 19xx/20xx testing.
If your objective was to convert a mainframe type file into an Oracle data-base, you would follow 'reform2' (to remove packed fields), with 'oracle1' to generate the control-file for SQL*LOADER. See DATAcnvt3.doc in volume 4 of the Vancouver Utilities documentation.
Goto: Begin this document , End this document , UVSI Home-Page
The vancouver Utilities includes some other jobs that are somewhat similar to reform2, in that they automatically generate parameters from copybooks.
For example, see 'oracle1' in DATAcnvt3.doc of volume 4. This job reads a copybook & automatically generates the control file for SQL*LOADER.
If you are converting files from a mainframe, you would first use 'reform2' to unpack the packed fields which is required before loading into Oracle. (see details & illustrations in DATAcnvt3.doc of volume 4).
Goto: Begin this document , End this document , UVSI Home-Page
Year 2000 Date-Field Expansion - Example
cobmap1 start-end bytes for cobol record fields 199905081041 pg# 0001 cpy1/warmas1 RCSZ=0064 bgn-end lth typ *warmas1 - warranty master record 05 wm-cust pic x(6). 000-0005 006 05 wm-prod pic x(6). 006-0011 006 05 wm-descrip pic x(18). 012-0029 018 05 wm-purchase pic x(6). <- 6 digit date 030-0035 006 05 wm-policy pic x(8). 036-0043 008 05 wm-expiry. 10 wm-exp-year pic 9(2). <- 2 digit year 044-0045 002 n 02 10 wm-exp-month pic 9(2). 046-0047 002 n 02 10 wm-exp-day pic 9(2). 048-0049 002 n 02 05 filler001 pic x(1). 050-0050 001 05 wm-paid-amt pic 9(9). 051-0059 009 n 09 05 filler002 pic x(4). 060-0063 004 *RCSZ=0064 0064
cobmap1 start-end bytes for cobol record fields 199905081053 pg# 0001 cpy2/warmas1 RCSZ=0068 bgn-end lth typ *warmas1x - warranty master record (warmas1 expanded dates) 05 wm-cust pic x(6). 000-0005 006 05 wm-prod pic x(6). 006-0011 006 05 wm-descrip pic x(18). 012-0029 018 05 wm-purchase pic x(8). <- expanded to 8 030-0037 008 05 wm-policy pic x(8). 038-0045 008 05 wm-expiry. 10 wm-exp-year pic 9(4). <- expanded to 4 046-0049 004 n 04 10 wm-exp-month pic 9(2). 050-0051 002 n 02 10 wm-exp-day pic 9(2). 052-0053 002 n 02 05 filler001 pic x(1). 054-0054 001 05 wm-paid-amt pic 9(9). 055-0063 009 n 09 05 filler002 pic x(4). 064-0067 004 *RCSZ=0068 0068
Note1 |
|
Note2 |
|
Goto: Begin this document , End this document , UVSI Home-Page
Year 2000 Date-Field Expansion - Example
pic x(6) pic 9(2) 12345 12345 sony television 970101 1-year 980101 000002995 22222 11111 refrigerator 970101 2-year 990101 000004925 33333 22222 dish washer 961231 3-year 991231 000006750 33333 11111 refrigerator 970101 3-year 000101 000006750 44444 33333 freezer 970101 4-year 010101 000009975 55555 55555 clothes dryer 991231 5-year 021231 000055500 66666 66666 blank dates 6-year 000066600 77777 77777 zero/blank dates 000000 7-year 000000 000077700 99999 99999 nines dates 999999 7-year 999999 000099900
pic x(8) pic 9(4) 12345 12345 sony television 19970101 1-year 19980101 000002995 22222 11111 refrigerator 19970101 2-year 19990101 000004925 33333 22222 dish washer 19961231 3-year 19991231 000006750 33333 11111 refrigerator 19970101 3-year 20000101 000006750 44444 33333 freezer 19970101 4-year 20010101 000009975 55555 55555 clothes dryer 19991231 5-year 20021231 000055500 66666 66666 blank dates 6-year 000066600 77777 77777 zero/blank dates 00000000 7-year 00000000 000077700 99999 99999 nines dates 99999999 7-year 99999999 000099900
Goto: Begin this document , End this document , UVSI Home-Page
Year 2000 Date-Field Expansion
opr='JOBNAME warmas1 - generated by cobmap1,reform2,uvdata52' uop=q1m4d2t0z0g7n3p3s0w5x1y0m0 <-- NOTE option 'm0' overrides dflt 'm4' was=a9000b9000 fili1=FILEIN,rcs=0064,typ=RSF filo1=FILEOUT,rcs=0068,typ=RSF @run opn all loop get fili1,a0 skp> eof clr b0(0068),' ' init output area to all blanks # --- <-- insert R/T tests if redef records mvc b0(6),a0(6) wm-cust mvc b6(6),a6(6) wm-prod mvc b12(18),a12(18) wm-descrip bal rfmxx,'a0030b08c08d0030e06f06','wm-purchase' mvc b38(8),a36(8) wm-policy bal rfmnn,'a0046b04c04d0044e02f02','wm-exp-year' mvc b50(2),a46(2) wm-exp-month mvc b52(2),a48(2) wm-exp-day mvc b54(1),a50(1) filler001 mvc b55(9),a51(9) wm-paid-amt mvc b64(4),a60(4) filler002 # put1 put filo1,b0 skp loop eof cls all eoj @pf2=reform2.sub
Note the 'bal' instructions used to expand the date-fields. These save a lot of inline code that older versions of reform2 used. The subrtns are included at run-time via the '@pf2=reform2.sub'. This keeps our generated jobs short, but allows the subrtns to do a lot more processing than was previously possible. Let us explain the bal parameters, for example:
bal rfmxx,'a0030b08c08d0030e06f06','wm-purch-date' =====================================================
rfmxx |
|
a0030 |
|
b08 |
|
b08 |
|
d0030 |
|
e06 |
|
f06 |
|
Goto: Begin this document , End this document , UVSI Home-Page
opr='JOBNAME warmas1 - generated by cobmap1,reform2,uvdata52' uop=q1m4d2t0z0g7n3p3s0w50x1y0m1 <-- NOTE option 'm1' overrides dflt 'm4' was=a9000b9000 fili1=FILEIN,rcs=0064,typ=RSF filo1=FILEOUT,rcs=0068,typ=RSF @run opn all loop get fili1,a0 skp> eof clr b0(0068),' ' init output area to all blanks # --- <-- insert R/T tests if redef records mvc b0(30),a0(30) wm-cust : wm-descrip bal rfmxx,'a0030b08c08d0030e06f06','wm-purchase' mvc b38(8),a36(8) wm-policy bal rfmnn,'a0046b04c04d0044e02f02','wm-exp-year' mvc b50(4),a46(4) wm-exp-month : wm-exp-day mvc b54(1),a50(1) filler001 mvc b55(9),a51(9) wm-paid-amt mvc b64(4),a60(4) filler002 # put1 put filo1,b0 skp loop eof cls all eoj @pf2=reform2.sub
This is the same job (for the same 2 old/new copybooks/files) as shown on the previous page, but using option 'm1' to combine move instructions for same type fields into 1 'mvc' instruction. Note that wm-exp-month & wm-exp-day have been combined into 1 instruction (since both pic 9).
The filenames (FILEIN & FILEOUT) do not have to be coded here, since they will be specified on the command line (see op. instrns. a few pages ahead).
If we only want to convert 1 file (& if it is sequential) this is OK, but if we have many files, then it is better to add an extra generation step which completes the uvcopy skeleton jobs, adding correct data file names & indexed keys.
'reform2' generates the uvcopy skeleton job from the copy-book only & the real data file names & indexed file keys cannot be determined from the copybook alone.
'uvdata52' is the extra step which adds data filenames & indexed keys, which requires preparation of a control file to relate this info to the copybook names.
The 1st set of Op. Instrns in section 'F' is for '1 file at a time' & is intended as a demo. I recommend you use the 'ALL files in directory' Op. Instrns presented later in section 'G'.
Goto: Begin this document , End this document , UVSI Home-Page
opr='warmas1 warmas1 - generated by cobmap1,reform2,uvdata52' uop=q1m4d2t0z0g7n3p3s0w50x1y0m4 <-- NOTE option 'm4' max combine instrns was=a9000b9000 fili1=${UVDATA1}/warmas1,rcs=0064,typ=RSF filo1=${UVDATA2}/warmas1,rcs=0068,typ=RSF @run opn all loop get fili1,a0 skp> eof clr b0(0068),' ' init output area to all blanks # --- <-- insert R/T tests if redef records mvc b0(30),a0(30) wm-cust : wm-descrip bal rfmxx,'a0030b08c08d0030e06f06','wm-purchase' mvc b38(8),a36(44) wm-policy bal rfmnn,'a0046b04c04d0044e02f02','wm-exp-year' mvc b50(18),a46(18) wm-exp-month : filler002 # put1 put filo1,b0 skp loop eof cls all eoj @pf2=reform2.sub
This example uses option 'm4' for maximum instruction combining all fields between Y2K date insertions. This is now the default, but you might want to use options m0,m1,or m2 when you are reformatting records for other purposes (such as unpacking packed fields for data-base conversions).
The previous pages illustrated the uvcopy 'SKELETON' job generated from the copybook. We call it a 'skeleton' because it lacks the correct data filename & any indexed key information.
This page illustrates the 'COMPLETE' uvcopy job with correct data filenames (& indexed keys if applicable). This requires preparation of a control file to relate this info to the copybook names (see sub-section 'G').
Note that the directory pathnames are not hard-coded, which gives us flexibility. Before you run the jobs, you would export the directories for example:
export UVDATA1=/home/uvadm/tstrfm/dat1
export UVDATA2=/home/uvadm/tstrfm/dat2
Goto: Begin this document , End this document , UVSI Home-Page
opr='warmas8 warmas8 - generated by cobmap1,reform2,uvdata52' uop=q1m4d2t0z0g7n3p3s0w50x1y0m4 <-- NOTE option 'm4' max combine instrns was=a9000b9000 fili1=${UVDATA1}/warmas8,rcs=0064,typ=ISFl1,isks=(0,11) filo1=${UVDATA2}/warmas8,rcs=0070,typ=ISFl1,isks=(0,11) @run opn all loop get fili1,a0 skp> eof clr b0(0070),' ' init output area to all blanks # --- <-- insert R/T tests if redef records mvc b0(30),a0(30) wm-cust : wm-descrip bal rfmxx,'a0030b08c08d0030e06f06','wm-purch-date' mvc b38(8),a36(0) wm-policy bal rfmxn,'a0046b02c02d0044e00f00','wm-exp-cent <-19/20' mvc b48(7),a44(51) wm-exp-year : filler001 bal rfmxx,'a0055b14c14d0051e12f12','wm-date-time' mvc b69(1),a63(1) filler002 # put1 put filo1,b0 skp loop eof cls all eoj @pf2=reform2.sub
This example is for an indexed file. Note that the fili1/filo1 declarations are coded with 'typ=ISF' (vs typ=RSF for sequential files). The 'l1' option on 'typ=ISFl1' is the read-only locking option. 'isks=0(11)' indicates that there is only 1 key in the 1st 11 bytes.
The information re file types & indexed keys (& correct data filenames) must be coded in a control file, since this is not available in the copybooks. Please see page 'G3' for information on preparing of the control file.
bal rfmxn,'a0046b02c02d0044e00f00','wm-exp-cent <-19/20' ===========================================================
Note |
|
Goto: Begin this document , End this document , UVSI Home-Page
<-- generated instruction--> <---- op1 output----> <----- op1 input ----->
rfmxx,a0030b04c04d0030e02f02 a/n 4 ccyy <- a/n 2 yy rfmxx,a0030b06c06d0030e04f04 a/n 6 ccyymm <- a/n 4 yymm rfmxx,a0030b06c06d0030e04f04 a/n 6 ccyymm <- a/n 4 yymm rfmxx,a0030b08c08d0030e06f06 a/n 8 ccyymmdd <- a/n 6 yymmdd rfmxx,a0030b12c12d0030e10f10 a/n 12 ccyymmddHHMM <- a/n 10 yymmddHHMM rfmxx,a0030b14c14d0030e12f12 a/n 14 ccyymmddHHMMSS <- a/n 12 yymmddHHMMSS
rfmnn,a0030b04c04d0030e02f02 num 4 ccyy <- num 2 yy rfmnn,a0030b06c06d0030e04f04 num 6 ccyymm <- num 4 yymm rfmnn,a0030b07c07d0030e05f05 num 7 ccyyjjj <- num 5 yyjjj rfmnn,a0030b08c08d0030e06f06 num 8 ccyymmdd <- num 6 yymmdd rfmnn,a0030b12c12d0030e10f10 num 12 ccyymmddHHMM <- num 10 yymmddHHMM rfmnn,a0030b14c14d0030e12f12 num 14 ccyymmddHHMMSS <- num 12 yymmddHHMMSS
rfmpp,a0030b04c07d0030e03f05 pak 4/7 ccyyjjj <- pak 3/5 yyjjj rfmpp,a0030b05c08d0030e04f06 pak 5/8 ccyymmdd <- pak 4/6 yymmdd rfmpp,a0030b08c14d0030e07f12 pak 8/14 ccyymmddHHMMSS <- pak 7/12 yymmddHHMMSS
rfmbb,a0030b04c08d0030e04f06 bin 4/8 ccyymmdd <- bin 4/6 yymmdd rfmbb,a0030b04c07d0030e04f05 bin 4/7 ccyyjjj <- bin 4/5 yyjjj
any combination of x,n,p,b conversions possible, for example:
rfmpn,a0030b08c08d0030e04f06 num 8/8 ccyymmdd <- pak 4/6 yymmdd rfmnp,a0030b05c08d0030e06f06 pak 5/8 ccyymmdd <- num 6/6 yymmdd
rfmbn,a0030b08c08d0030e04f06 num 8/8 ccyymmdd <- bin 4/6 yymmdd rfmnb,a0030b04c08d0030e06f06 bin 4/8 ccyymmdd <- num 6/6 yymmdd
rfmpb,a0030b04c08d0030e04f06 bin 4/8 ccyymmdd <- pak 4/6 yymmdd rfmbp,a0030b05c08d0030e04f06 pak 5/8 ccyymmdd <- bin 4/6 yymmdd
bal rfm__,'a____b__c__d____e__f__','fname' =============================================
a____ |
|
b__ |
|
c__ |
|
d____ |
|
e__ |
|
f__ |
|
Goto: Begin this document , End this document , UVSI Home-Page
The default (global) options are established at reform2 generation time. These options are coded as the defaults on the generated uvcopy jobs.
The default options appear on line 2 of each generated job, for example:
uop=g7n3p3s0w50x1y0 <-- default options from reform2 generation ===================
g0 - don't insert century g1 - insert century (if op1 lth = op2+2), presume 19 g2 - insert century as 20 if yy < 50 (or optn w value) g4 - if yymm = 9999, insert century as 99 g7 - all of above (g1+g2+g4)
n0 - convert nulls/blanks in numeric fields to zeros n1 - retain nulls in numeric fields (output all nulls) n2 - retain blanks in numeric fields (output all blanks)
p0 - convert null/blank packed fields to packed zeros p1 - retain nulls in packed fields (output all nulls) p2 - retain blanks in packed fields (output all blanks)
s0 - sign in packed fields copied from input field s1 - signs in packed fields will be set to x'_C' s2 - signs in packed fields will be set to x'_F' - If option 's' is not specified on the rfmpp subrtn call signs in packed fields will be set to x'_C' or x'_F' depending on global run option rop=s0/s2 on the uvcopy job - the global default is rop=s0 (copy sign from last input field) - Micro Focus COBOL requires x'_C' for packed comp-3 signed, & x'_F' for packed comp-3 unsigned for linked executables ('.int's will compare correctly for either). - see 'mvn' doc in uvcopy3.doc in vol 2 of UVdoc
w50 - Y2K pivot value to test insert 19/20
x0 - retain nulls/blanks/zeros in alphanumeric fields x1 - convert nulls in alphanumeric fields to blanks x2 - convert blanks in alphanumeric fields to zeros x4 - convert zeros in alphanumeric fields to blanks
y0 - date format YYMMDD (default) y4 - date format MMDDYY or DDMMYY
Note |
|
Goto: Begin this document , End this document , UVSI Home-Page
The global options may be over-ridden as required on selected date fields. We will illustrate using a date field expansion from the warmas1 job previously listed on page 'D1'.
bal rfmxx,'a0030b08c08d0030e06f06','wm-purchase' <-- as generated
bal rfmxx,'a0030b08c08d0030e06f06w75y4','wm-purchase' <-- modified ^^^^^
Note that we have inserted options to change the window from the default 'w50' to 'w75' & the date format from 'y0' for yymmdd to 'y4' for mmddyy.
Goto: Begin this document , End this document , UVSI Home-Page
The 'reform2' uvcopy job includes the following table. (vi /home/uvadm/pf/reform2)
# load table of date field names for '19' insert determination lod=m6000(20) date~~~~~~~~~~~~~~~~ year~~~~~~~~~~~~~~~~ yr~~~~~~~~~~~~~~~~~~ yy~~~~~~~~~~~~~~~~~~ term~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
Fields that are <= 16 bytes long & that are being increased in length by 2 bytes are assumed to be date fields.
Previous versions of reform2 used this date field name table to determine if packed fields should have centuries inserted.
This is no longer used, since the new version now considers the digit lengths as well as the byte length.
Not using it means you don't have to worry about the names of date fields, reform2 will insert centuries wherever your new copybook has increased the length of the field by 2 bytes.
The table has been retained (but disabled) in case somebody wants to expand fields for other reasons & needs to limit century insertion.
Goto: Begin this document , End this document , UVSI Home-Page
The following files are supplied to test/demo reform1/reform2:
uvadm/dat1/warmas1 - demo data-file supplied in 'tf' directory uvadm/cpy/warmas1 - demo copy-book supplied in 'cpy' directory
We will setup a test sub-directory (within uvadm directory), change into it and setup several sub-sub-directories. This will keep our uvadm home directory uncluttered & make it easier & safer to clean up after the test/demo.
Sub-directories are made for the different types of files, so that we can keep the same name as the original copybook.
Multiple sub-directories work especially well for the ALL Files in Directory generation since we can retain the same names as we convert copybooks to record layouts, to skeletons,& to complete jobs.
1a. cd /home/uvadm - change to the Vancouver Utility home directory or use your home directory 1b. mkdir tstrfm - make a sub-directory for the test/demo 1c. cd tstrfm - change into it
- make sub-sub-directories 2a. mkdir dat1 - for original (input) test data files 2b. mkdir dat2 - for converted (output) data files 2c. mkdir cpy1 - for the original copybooks 2d. mkdir cpy2 - for new copybooks (dates expanded) 2e. mkdir map1 - for 'cobmap's of original copybooks 2f. mkdir map2 - for 'cobmap's of new copybooks 2g. mkdir map1I - for original cobmaps loaded into indexed files 2h. mkdir pfr1 - for generated uvcopy jobs (to reformat data) 2i. mkdir pfr2 - for uvcopy jobs (with filenames & indexed keys) 2i. mkdir pfr3 - for uvcopy jobs requiring manual changes (so we wont overwrite on mass regens into pfr2)
3a. cp /home/uvadm/cpy/warmas1 cpy1/warmas1 - copy demo copybook to subdir
3b. cp /home/uvadm/dat1/warmas1 dat1 - copy demo test-data file to subdir
4a. cp cpy1/warmas1 cpy2/warmas1 - copy copybook for revised layout
4b. vi cpy2/warmas1 - modify copybook for desired layout (changing 6 digit dates to 8, 2 to 4)
See demo job generation & execution on the next page --->
Goto: Begin this document , End this document , UVSI Home-Page
<-- See preparations on the previous page. (making demo sub-directories & populating with supplied test files)
#1. uvcopy cobmap1,fili1=cpy1/warmas1,filo1=map1/warmas1 ==================================================== - run cobmap1 for the original copybook
#2. uvcopy cobmap1,fili1=cpy2/warmas1,filo1=map2/warmas1 ==================================================== - run cobmap1 for the new copybook
#3. uvcopy reform1,fili1=map1/warmas1,filo1=map1I/warmas1 ===================================================== - load old map into an Indexed file
#4. uvcopy reform2,fili1=map2/warmas1,filr1=map1I/warmas1, ====================================================== filo1=pfr1/warmas1,uop=w75 ========================== - generate uvcopy job to reformat data file see options explained next page --->
#5. uvdata52 job omitted for 1 at a time generation, see All files ahead
#6. vi pfr1/warmas1 - modify generated job as required - add record-type tests for redefined fields - hard-code I/O filenames if desired
#7. uvcopy pfr1/warmas1,fili1=dat1/warmas1,filo1=dat2/warmas1 ========================================================= - execute the job to convert the data file
#8a. cat dat1/warmas1 - inspect original data with 6 digit dates
#8b. cat dat2/warmas1 - inspect new data file with 8 digit dates
Note |
|
Goto: Begin this document , End this document , UVSI Home-Page
#4. uvcopy reform2,fili1=map2/warmas1,filr1=map1I/warmas1, ====================================================== filo1=pfr1/warmas1,uop=w75 ==========================
Unless uop=q0 is specified on the command line, you will be prompted for option changes as shown below:
uop=q1m2d2t0z0g7n3p3s0w50x1y0 <-- option defaults m0 - generate separate mvc/mvn instrns for each field m1 - combine contiguous same type/lth/occurs flds into 1 mvc m2 - combine contiguous same lth flds (regardless of type) m4 - max combine to next expansion(y2K) or type change d2 - generate 'bal' to expand date field if op1=op2+2 t0 - output typ=RSF (fixed rcsz, no LF terminator) t1 - output typ=RST (insert LF in last byte of rcsz) z1 - convert nulls to blanks (if record all display) --------- following may be overridden on bal rfm__ for selected fields g0 - don't insert century g1 - insert century (if op1 lth = op2+2), presume 19 g2 - insert century as 20 if yy < 50 (or optn w value) g4 - if yymm = 9999, insert century as 99 g7 - all of above (g1+g2+g4) n0 - convert nulls/blanks in numeric fields to zeros n1 - retain nulls in numeric fields (output all nulls) n2 - retain blanks in numeric fields (output all blanks) p0 - convert null/blank packed fields to packed zeros p1 - retain nulls in packed fields (output all nulls) p2 - retain blanks in packed fields (output all blanks) s0 - sign in packed fields copied from input field s1 - sign in packed fields will be set to x"_C" s2 - sign in packed fields will be set to x"_F" w50 - Y2K pivot value to test insert 19/20 x0 - retain nulls/blanks/zeros in alphanumeric fields x1 - convert nulls in alphanumeric fields to blanks x2 - convert blanks in alphanumeric fields to zeros x4 - convert zeros in alphanumeric fields to blanks y0 - date format YYMMDD (default) y4 - date format MMDDYY or DDMMYY
User OPtion (uop) defaults = q1m2t0z0g7n0p0s0w50x1y0 null to accept or re-specify (1 or more) ---> t1 <-- enter option changes
't1' inserts a LineFeed in the last byte of the record & is used for these demos so we can examine the output files using vi,cat,lp,etc. You could only use this if the last byte happens to be unused as in this case. (otherwise use 'uvhd', which must be used when packed fields present)
Options g,h,n,p,s,w,y appended onto the 'bal' instruction options override the global defaults selected on reform2 generation, for example:
bal rfmxx,'a0030b08c08d0030e06f06w30y4','wm-purchase' ^^^^^ Note that options 'w30y4' has been appended to change for this field only.
Goto: Begin this document , End this document , UVSI Home-Page
Previously (in sub-section 'F'), we presented operating instructions to reformat 1 data file at a time. We will now present Operating Instructions for all copybooks & all data files, which is almost as easy to do as for 1 at a time. The operating instructions are actually simpler.
I recommend you use these 'ALL FILES in DIRECTORY' procedures at your site, even if you will subsequently use only a fraction.
The 'ALL FILES in Directory' procedures include 1 extra job 'uvdata52', which generates complete uvcopy jobs with actual data file names & indexed keys. The jobs will be renamed the same as the data file names, rather than the copybook names (note that there could be multiple files for 1 copybook).
You will be able to run these complete jobs simply by specifying the jobname:
uvcopy pfr2/glmasterfile - run job to reformat the 'glmaster' file ========================
uvcopy 'pfr2/gl*' - run jobs to reformat all 'gl' files =================
Note that the previous 1 file at a time procedures required you to specify the data file names on the command line, for example:
uvcopy pfr1/glmaster.cpy,fili1=dat1/glmasterfile,filo1=dat2/glmasterfile ========================================================================
If the files were indexed, you would have to specify the file type & keys:
uvcopy pfr1/glmaster.cpy,fili1=dat1/glmasterfile\ ================================================ ,filo1=dat2/glmasterfile,typ=ISF,isks=(0,6,20,25) =================================================
This added convenience does require the preparation of a control file, to relate the copy-book-names to the data-file-names, but 'mkctlf1' is provided to generate the control file from the data file directory.
Mkctlf1 assumes that the copybook name is the same as the data file name, and you will have to make corrections where this is not the case. You will also have to correct the record sizes of sequential files since this cannot be determined from the directory.
glmasterfile cpy=glmaster.cpy rcs=256 keys=(0,6,20,25) gltransactions cpy=gltrans/cpy rcs=100
Note that the record size of sequential files will be generated as 100 and you should investigate any rcs=100 for non-keyed files.
Goto: Begin this document , End this document , UVSI Home-Page
<-- See descriptive overview of these procedures on the previous page.
/home/uvadm - Vancouver Utilities home directory /home/uvadm/cpy1/... - demo copybooks provided with UV package /home/uvadm/ctl/... - demo control files (will copy to tstrfm/ctl) /home/uvadm/tf/... - test data files provided (copy to tstrfm/dat1)
You can run this test/demo by setting up a 'tstrfm' subdirectory in your home directory (or uvadm if only 1 user) & copying provided test files.
1a. cd $HOME - change to your home directory 1b. mkdir tstrfm - setup super directory for test/demo 1c. cd tstrfm - change into it
2a. mkdir dat1 - test data input files 2b. mkdir dat2 - test data output files (with expanded dates) 2c. mkdir cpy1 - make subdir for original copy-books 2d. mkdir cpy2 - make subdir for new expanded copy-books 2e. mkdir map1 - for original record layouts (created from copybooks) 2f. mkdir map2 - for new record layouts (created from new copybooks) 2g. mkdir map1I - indexed file versions of map1 record layouts 2h. mkdir ctl - control file (relates copybook names to datafile names) 2i. mkdir pfr1 - uvcopy skeleton jobs (created from record layouts) 2j. mkdir pfr2 - uvcopy completed jobs (filenames & keys from ctlfile) 2k. mkdir pfr3 - for uvcopy jobs requiring manual changes (so we wont overwrite on mass regens into pfr2)
3a. cp /home/uvadm/cpy1/warmas1 cpy1 - orig copybook - sequential file 3b. cp /home/uvadm/cpy1/warmas3 cpy1 - orig copybook - multi R/T file 3c. cp /home/uvadm/cpy1/warmas8 cpy1 - orig copybook - Indexed file
4a. cp cpy1/* cpy2 - copy all original copybooks to 2nd directory 4b. vi cpy2/* - modify copybooks to new record layouts - expanding 6 digit dates to 8 digits, etc
NOTE |
|
4a. cp /home/uvadm/cpy1/warmas1x cpy2/warmas1 - expanded, sequential file 4b. cp /home/uvadm/cpy1/warmas3x cpy2/warmas3 - expanded, multi R/T file 4c. cp /home/uvadm/cpy1/warmas8x cpy2/warmas8 - expanded, Indexed file
Goto: Begin this document , End this document , UVSI Home-Page
5a. cp /home/uvadm/dat1/warmas1 dat1 - demo datafile - sequential file 5b. cp /home/uvadm/dat1/warmas3 dat1 - demo datafile - multi R/T file 5c. cp /home/uvadm/dat1/warmas8* dat1 - demo datafile - Indexed file
6a. uvcopy mkctlf1,fild1=dat1,filo1=ctl/ctlrfm1 ===========================================
# ctl/ctlrfm1 - created by mkctlf1 1998/12/21_13:42:01 # - control file for vtocr1,uvdata52,AGEjobs,CMPjobs,REFORMjobs warmas1 cpy=warmas1 rcs=00100 warmas3 cpy=warmas3 rcs=00100 warmas8 cpy=warmas8 rcs=00064 keys=(0,12)
6b. vi ctl/ctlrfm1 - correct the control file as required ============== - correct copybook names (if not same as datafile names) - correct record-size of sequential files (coded as rcs=00100, so easy to find with editor) - change 'rcs=00100' to 'rcs=00064' for warmas1 & warmas3
NOTE |
|
6a. cp /home/uvadm/ctl/ctlrfm1 ctl - filename/copybookname control file ===============================
>>End preparations, see REFORMjobs Generation & Execution following --->
Goto: Begin this document , End this document , UVSI Home-Page
<-- See preparation on the previous 3 pages. - setup tstrfm directory in your home dir or in uvadm if single user - making demo sub-directories & populating with supplied test files - making control file to relate copy-book-names to data-file-names
#1a. uvcopyx cobmap1 cpy1 map1 uop=q0i7p0 ==================================== - create record-layouts from copybooks, for ORIGINAL data files
#1b. uvcopyx cobmap1 cpy2 map2 uop=q0i7p0 ==================================== - create record-layouts from copybooks, for EXPANDED data files
#2a. rmzf map1 - remove zero length files (for any procedure copybooks) #2b. rmzf map2
#3. uvcopyx reform1 map1 map1I uop=q0i7 =================================== - load indexed files from original copybooks - so reform2 can lookup original field defs from new field defs
#4. uvcopyxr reform2 map2 pfr1 map1I uop=q0i7 ========================================= - generate uvcopy skeleton reformat jobs from copybook layouts
#5. uvcopy uvdata52,fili1=ctl/ctlrfm1,fild2=pfr1,fild3=pfr2,uop=q0i7\ =============================================================== ,arg1=dat1,arg2=dat2 ==================== - complete the uvcopy skeleton job, by encoding the I/O data path directories (& indexed keys if any)
I recommend NOT coding arg1/arg2 on the command line (as above) Better to wait for the prompts & enter pathnames as variables:
enter input data path --> ${UVDATA1} <-- suggested for input directory enter output data path --> ${UVDATA2} <-- suggested for output directory
These are the defaults, so you can just hit enter (null reply)
>>End of REFORMjobs Generation, see EXECUTION on the next page --->
Goto: Begin this document , End this document , UVSI Home-Page
<-- See preparation & generation on the previous 4 pages.
#6. export UVDATA1=/home/uvadm/tstrfm/dat1 - setup path to input data files ======================================
export UVDATA2=/home/uvadm/tstrfm/dat2 - setup path to output data files ======================================
#7a. uvcopyxx 'pfr2/*' - execute all uvcopy jobs to convert all files ================
#7b. uvcopy 'pfr2/gl*' - execute all reformat jobs for GL data files =================
#7c. uvcopy pfr2/glmaster - execute a specific job to convert a specific file ====================
Note |
|
Goto: Begin this document , End this document , UVSI Home-Page
These procedures use 'reform1a' (vs 'reform1') & include an extra step 'reform1b'. An extra directory is required 'map2a'.
#1. uvcopyx cobmap1 cpy1 map1 uop=q0p0i7 ==================================== - convert original copybooks into cobmap1 layouts
#2. uvcopyx cobmap1 cpy2 map2 uop=q0p0i7 ==================================== - convert modified copybooks into cobmap1 layouts
#3. uvcopyx reform1a map1 map1I uop=q0i7 <-- reform1a vs reform1 ==================================== - convert original cobmap1 into ISAM files (for reform2)
#3a. uvcopyxr reform1b map2 map2a map1I uop=q0i7 <-- reform1b creates map2a ===========================================
#4. uvcopyxr reform2 map2a pfc1 map1I uop=q0i7 <-- indir map2a vs map2 ========================================== - generate uvcopy jobs to reformat data-files
#5. uvcopy uvdata52,fili1=ctl/ctlrfm1,fild2=pfr1,fild3=pfr2 ======================================================
reform1a |
|
reform1b |
|
note |
|
Goto: Begin this document , End this document , UVSI Home-Page
The example above demonstrated the generation of uvcopy jobs to reformat files (insert century), for files with only 1 record type, which is the normal situation. The process was completely automatic & we did not have to modify the generated code before execution.
If you do have files with multiple record-types, you will have to modify the generated code before execution. This is because the copybooks which drive the generation do not have the record-type information. They do have the 'redefined' field information, and some uvcopy instructions will be generated for them. It is simply a matter of inserting some code to test the record type & conditionally execute the proper set of instructions.
See the 'warmas3' test data file which includes a 2nd record type for notes or comments re the customer/product warranty details. These note records are identified by a '*' in column 12, the file is as follows:
12345 12345 sony television 970101 1-year 980101 000002500 12345 12345*warmas3 alternate warmas file, demo multi rec types 22222 11111 refrigerator 970101 2-year 990101 000004500 22222 22222 dish washer 971231 2-year 991231 000004500 22222 22222*rectype col 12, blank for detail, '*' for note recs 33333 11111 refrigerator 970101 3-year 000101 000006500 33333 11111*special 3 yr warranty to John Smith GE refrigerator 44444 33333 freezer 970101 4-year 010101 000010000 55555 55555 dryer 971231 5-year 021231 000010000 66666 66666 blank/zero dates 6-year 000000 000060000
cobmap1 start-end bytes for cobol record fields 199905081041 pg# 0001 cpy1/warmas3 wm-rec RCSZ=0064 bgn-end lth typ 01 wm-rec. 05 wm-cust pic x(6). 000-0005 006 05 wm-prod pic x(5). 006-0010 005 05 wm-type pic x(1). 011-0011 001 05 wm-dtl. 10 wm-descrip pic x(18). 012-0029 018 10 wm-purchase pic x(6). <- 6 digits yymmdd 030-0035 006 10 wm-policy pic x(8). 036-0043 008 10 wm-expiry pic x(6). <- 6 digits yymmdd 044-0049 006 10 filler001 pic x(1). 050-0050 001 10 wm-paid-amt pic 9(9). 051-0059 009 n 09 10 filler002 pic x(4). 060-0063 004 05 wm-note redefines wm-dtl. 10 wm-comment pic x(52). 012-0063 052 *RCSZ=0064 0064
Goto: Begin this document , End this document , UVSI Home-Page
The previous page illustrated a file with multiple record-types, and also the corresponding copy-book.
We could follow the same procedure (as in the preceding sub-section 'G') to generate the uvcopy job to expand the dates (insert centuries). This would involve duplicating the copy-book, lengthening the date-fields & running the various jobs (cobmap1, reform1, reform2). The result would be as follows:
opr='warmas3 warmas3 - generated by cobmap1,reform2,uvdata52' uop=q1m4d2t0z0g7n3p3s0w50x1y0 <-- options from reform2 generation was=a9000b9000 fili1=${UVDATA1}/warmas3,rcs=0064,typ=RSF filo1=${UVDATA2}/warmas3,rcs=0068,typ=RSF @run opn all loop get fili1,a0 skp> eof clr b0(0068),' ' init output area to all blanks # --- <-- insert R/T tests if redef records mvc b0(30),a0(30) wm-cust : wm-descrip bal rfmxx,'a0030b08c08d0030e06f06','wm-purchase' mvc b38(8),a36(44) wm-policy bal rfmxx,'a0046b08c08d0044e06f06','wm-expiry' mvc b54(14),a50(14) filler001 : filler002 # --- *redef ?, R/T test ?, or remove skp ? skp put1 # mvf b12(56),a12(52) wm-comment # put1 put filo1,b0 skp loop eof cls all eoj @pf2=reform2.sub
Please compare this code to the previous job on page 'D1' for a single record-type & to the multi record-type copy-book on the previous page.
Note the additional code generated (prior to the 'put1' tag) for the second record-type. We must now add some code to test the record type --->
Goto: Begin this document , End this document , UVSI Home-Page
opr='warmas3 warmas3 - generated by cobmap1,reform2,uvdata52' uop=q1m4d2t0z0g7n3p3s0w50x1y0 <-- options from reform2 generation was=a9000b9000 fili1=${UVDATA1}/warmas3,rcs=0064,typ=RSF filo1=${UVDATA2}/warmas3,rcs=0068,typ=RSF @run opn all loop get fili1,a0 skp> eof clr b0(0068),' ' init output area to all blanks mvc b0(30),a0(30) wm-cust : wm-descrip <-COMMON #------------------------------------------------------------------------- cmc a11(1),' ' detail record ? <-INSERT skp= dtl <-INSERT cmc a11(1),'*' note record ? <-INSERT skp= note <-INSERT msgw 'Invalid record type - enter to copy unchanged ?' <-INSERT skp put1 <-INSERT #------------------------------------------------------------------------- dtl bal rfmxx,'a0030b08c08d0030e06f06','wm-purchase' <-ADD TAG bal rfmxx,'a0030b08c08d0030e06f06','wm-purchase' mvc b38(8),a36(44) wm-policy bal rfmxx,'a0046b08c08d0044e06f06','wm-expiry' mvc b54(14),a50(14) filler001 : filler002 skp put1 #------------------------------------------------------------------------- note mvf b12(56),a12(52) wm-comment <-ADD TAG # put1 put filo1,b0 skp loop eof cls all eoj @pf2=reform2.sub
We inserted 6 instructions & added 2 tags to already generated instructions. We did not have to change the addresses on the generated 'mvf' because we inserted our record type test after moving the first 30 bytes. The note record only needed 12 bytes moved here, but the extra does no harm,& is needed for the detail record.
In more complex files, there might be 3 or more record types, and there might be date-fields in the 2nd & 3rd record types. However it is still a matter of inserting the record type tests - all the code to reformat the fields would already be generated.
Goto: Begin this document , End this document , UVSI Home-Page
Reform2 is not designed to handle dates in occurs, but this sub-section will show you how to modify the generated jobs.
cobmap1 start-end bytes for cobol record fields 199905130550 pg# 0001 cpy1/warmat1 RCSZ=0100 bgn-end lth typ *warmas1 - warranty master record 05 wm-cust pic x(6). 000-0005 006 05 wm-prod pic x(6). 006-0011 006 05 wm-descrip pic x(18). 012-0029 018 05 wm-policy occurs 4. 07 wm-policy-date pic x(6). 030-0035 006 07 wm-policy-type pic x(8). 036-0043 008 05 wm-expiry. 07 wm-exp-year pic 9(2). 086-0087 002 n 02 07 wm-exp-month pic 9(2). 088-0089 002 n 02 07 wm-exp-day pic 9(2). 090-0091 002 n 02 05 wm-paid-amt pic 9(7). 092-0098 007 n 07 05 filler001 pic x(1). 099-0099 001 *RCSZ=0100 0100
Check occurs: (6+8) * 4 = 56 + 30 = 86 OK
cobmap1 start-end bytes for cobol record fields 199905130551 pg# 0001 cpy2/warmat1 RCSZ=0110 bgn-end lth typ *warmas1 - warranty master record 05 wm-cust pic x(6). 000-0005 006 05 wm-prod pic x(6). 006-0011 006 05 wm-descrip pic x(18). 012-0029 018 05 wm-policy occurs 4. 07 wm-policy-date pic x(8). 030-0037 008 07 wm-policy-type pic x(8). 038-0045 008 05 wm-expiry. 07 wm-exp-year pic 9(4). 094-0097 004 n 04 07 wm-exp-month pic 9(2). 098-0099 002 n 02 07 wm-exp-day pic 9(2). 100-0101 002 n 02 05 wm-paid-amt pic 9(7). 102-0108 007 n 07 05 filler001 pic x(1). 109-0109 001 *RCSZ=0110 0110
Check occurs: (8+8) * 4 = 64 + 30 = 94 OK
Goto: Begin this document , End this document , UVSI Home-Page
opr='warmat1 warmat1 - generated by cobmap1,reform2,uvdata52' uop=q1m4d2t0z0g7n3p3s0w50x1y0 <-- options from reform2 generation was=a9000b9000 fili1=${UVDATA1}/warmat1,rcs=0100,typ=RSF filo1=${UVDATA2}/warmat1,rcs=0110,typ=RSF @run opn all loop get fili1,a0 skp> eof clr b0(0110),' ' init output area to all blanks # --- <-- insert R/T tests if redef records mvc b0(30),a0(30) wm-cust : wm-descrip bal rfmxx,'a0030b08c08d0030e06f06','wm-policy-date occurs 04' # --- *date expansion in occurs (may need loop) # mvc b38(56),a36(50) wm-policy-type occur 04 bal rfmnn,'a0094b04c04d0086e02f02','wm-exp-year' mvc b98(12),a88(12) wm-exp-month : filler001 # put1 put filo1,b0 skp loop eof cls all eoj @pf2=reform2.sub
WARNING |
|
Setup 'pfr3' for all jobs that require manual modifications.
pfr1 |
|
pfr2 |
|
pfr3 |
|
Goto: Begin this document , End this document , UVSI Home-Page
opr='warmat1 warmat1 - generated by cobmap1,reform2,uvdata52' uop=q1m4d2t0z0g7n3p3s0w50x1y0 <-- options from reform2 generation was=a9000b9000 fili1=${UVDATA1}/warmat1,rcs=0100,typ=RSF filo1=${UVDATA2}/warmat1,rcs=0110,typ=RSF @run opn all loop get fili1,a0 skp> eof clr b0(0110),' ' init output area to all blanks # mvc b0(30),a0(30) wm-cust : wm-descrip #--------------------------------------------------------------------- ## bal rfmxx,'a0030b08c08d0030e06f06','wm-policy-date occurs 04' ## mvc b38(56),a36(50) wm-policy-type occur 04 ## dates in occurs require code loop, original above ##cmtd out # # occurs input 4 * (6 date + 8 type) = 56 + 30 start = 86 end # occurs output 4 * (8 date + 8 type) = 64 + 30 start = 94 end # must use rgstr j output & k input, see below: 'aj___b__c__dk___e__f__' mvn $rj,0 clear rgstr for output area mvn $rk,0 clear rgstr for input area lup1 bal rfmxx,'aj30b08c08dk30e06f06' <--NOTE rgstrs j & k inserted mvc bj38(8),ak36(8) wm-policy-type occur 04 <-- rg j k inserted add $rk,14 up input rgstr to next occurs add $rj,16 up output rgstr to next occurs cmn $rj,64 end of occurs 4 * 16 = 64 ? skp< lup1 #--------------------------------------------------------------------- bal rfmnn,'a0094b04c04d0086e02f02','wm-exp-year' mvc b98(12),a88(12) wm-exp-month : filler001 # put1 put filo1,b0 skp loop eof cls all eoj @pf2=reform2.sub
I recommend you insert #comment lines as shown above to check your math.
# occurs input 4 * (6 date + 8 type) = 56 + 30 start = 86 end # occurs output 4 * (8 date + 8 type) = 64 + 30 start = 94 end
Please relate these calcs to the old & new copybooks shown on page 'I1'.
These #comments are a big help to you or other people who may later need to verify that the job was done correctly.
Goto: Begin this document , End this document , UVSI Home-Page
Here is an alternate solution to the 'dates in occurs' problem that was used before the register j/k solution was provided (see previous page).
This is now of academic interest, but some important points are noted below.
#-------------------------------------------------------------------------- mvn $rj,0 clear rgstr for output area mvn $rk,0 clear rgstr for input area lup1 mvc a200(6),ak30(6) store date for bal in high input area bal rfmxx,'a0200b08c08d0200e06f06' <--NOTE 'a0200' & 'd0200' mvc bj30(8),b200(8) store date from bal in outarea date mvc bj38(8),ak36(8) wm-policy-type occur 04 add $rk,14 up input rgstr to next occurs add $rj,16 up output rgstr to next occurs cmn $rj,64 end of occurs 4 * 16 = 64 ? skp< lup1 #--------------------------------------------------------------------------
bal option 'a' - displacement to the output date in area 'b' bal option 'b' - length (in bytes) of the output date in area 'b' bal option 'c' - length (in digits) of the output date in area 'b' bal option 'd' - displacement to the input date in area 'a' bal option 'e' - length (in bytes) of the input date in area 'a' bal option 'f' - length (in digits) of the input date in area 'a'
Goto: Begin this document , End this document , UVSI Home-Page
cobmap1 start-end bytes for cobol record fields 199905221203 pg# 0001 cpy1/warmat2 RCSZ=0064 bgn-end lth typ *warmat2 - to test reform2 on mmddyy date formats 05 wm-cust pic x(6). 000-0005 006 05 wm-prod pic x(6). 006-0011 006 05 wm-descrip pic x(18). 012-0029 018 05 wm-purch-date pic x(6). <- mmddyy 030-0035 006 05 wm-policy pic x(8). 036-0043 008 05 wm-expiry. 10 wm-exp-month pic 9(2). 044-0045 002 n 02 10 wm-exp-day pic 9(2). 046-0047 002 n 02 10 wm-exp-year pic 9(2). <- yy for prior mmdd 048-0049 002 n 02 05 filler001 pic x(1). 050-0050 001 05 wm-paid-amt pic 9(9). 051-0059 009 n 09 05 filler002 pic x(4). 060-0063 004 *RCSZ=0064 0064
cobmap1 start-end bytes for cobol record fields 199905221203 pg# 0001 cpy2/warmat2 RCSZ=0068 bgn-end lth typ *warmat2x - test mmddyy formats expanded to mmddccyy 05 wm-cust pic x(6). 000-0005 006 05 wm-prod pic x(6). 006-0011 006 05 wm-descrip pic x(18). 012-0029 018 05 wm-purch-date pic x(8). <- mmddccyy 030-0037 008 05 wm-policy pic x(8). 038-0045 008 05 wm-expiry. 10 wm-exp-month pic 9(2). 046-0047 002 n 02 10 wm-exp-day pic 9(2). 048-0049 002 n 02 10 wm-exp-year pic 9(4). <- ccyy of prior ddmm 050-0053 004 n 04 05 filler001 pic x(1). 054-0054 001 05 wm-paid-amt pic 9(9). 055-0063 009 n 09 05 filler002 pic x(4). 064-0067 004 *RCSZ=0068 0068
Tests for blank/zero/nines presume date formats YYMMDD & these work OK, when the 2 digit YY is defined separately, but MMDD follows in the data.
These tests (for 2 digit years) do not work for MMDDYY/DDMMYY formats.
For 6 digit mmddyy/ddmmyy, we simply need to code the 'y4' option, but for 2 digit years, we also need to redefine the field as 6 digits, so we can include the mmdd portion in the zero/blank/nines test.
The problem & the solution is illustrated on the following pages --->
Goto: Begin this document , End this document , UVSI Home-Page
MMDDYY mmddYY <- YY separate in copybook 12345 12345 sony television 010197 1-year 010198 000002995 22222 11111 refrigerator 010197 2-year 010199 000004925 33333 22222 dish washer 123196 3-year 123199 000006750 33333 11111 refrigerator 010197 3-year 010100 000006750 44444 33333 freezer 010197 4-year 010101 000009975 55555 55555 clothes dryer 123199 5-year 123102 000055500 66666 66666 blank dates 6-year 000066600 77777 77777 zero/blank dates 000000 7-year 000000 000077700 99999 99999 nines dates 999999 7-year 999999 000099900
incorrect almost OK 12345 12345 sony television 20010197 1-year 01011998 000002995 22222 11111 refrigerator 20010197 2-year 01011999 000004925 33333 22222 dish washer 20123196 3-year 12311999 000006750 33333 11111 refrigerator 20010197 3-year 01012000 000006750 44444 33333 freezer 20010197 4-year 01012001 000009975 55555 55555 clothes dryer 20123199 5-year 12312002 000055500 66666 66666 blank dates 6-year 000066600 77777 77777 zero/blank dates 00000000 7-year 00002000 000077700 <- incorrect 99999 99999 nines dates 99999999 7-year 99991999 000099900 <- incorrect
MMDDCCYY mmddCCYY 12345 12345 sony television 01011997 1-year 01011998 000002995 22222 11111 refrigerator 01011997 2-year 01011999 000004925 33333 22222 dish washer 12311996 3-year 12311999 000006750 33333 11111 refrigerator 01011997 3-year 01012000 000006750 44444 33333 freezer 01011997 4-year 01012001 000009975 55555 55555 clothes dryer 12311999 5-year 12312002 000055500 66666 66666 blank dates 6-year 000066600 77777 77777 zero/blank dates 00000000 7-year 00000000 000077700 <- OK 99999 99999 nines dates 99999999 7-year 99999999 000099900 <- OK
Please relate these data file results to the copybooks on the previous page & the uvcopy jobs on the next page --->
Goto: Begin this document , End this document , UVSI Home-Page
** pfr2/warmat2 as generated ** opr='warmat2 warmat2 - generated by cobmap1,reform2,uvdata52' uop=q1m4d2t0z0g7n3p3s0w50x1y0q0i7 <-- options from reform2 gen was=a9000b9000 fili1=${UVDATA1}/warmat2,rcs=0064,typ=RSF filo1=${UVDATA2}/warmat2,rcs=0068,typ=RSF @run opn all loop get fili1,a0 skp> eof clr b0(0068),' ' init output area to all blanks # --- <-- insert R/T tests if redef records mvc b0(30),a0(30) wm-cust : wm-descrip bal rfmxx,'a0030b08c08d0030e06f06','wm-purch-date' mvc b38(12),a36(12) wm-policy : wm-exp-day bal rfmnn,'a0050b04c04d0048e02f02','wm-exp-year' mvc b54(14),a50(14) filler001 : filler002 # put1 put filo1,b0 skp loop eof cls all eoj @pf2=reform2.sub
** pfr2/warmat2 - AFTER corrections ** opr='warmat2 warmat2 - generated by cobmap1,reform2,uvdata52' uop=q1m4d2t0z0g7n3p3s0w50x1y0q0i7 <-- options from reform2 gen was=a9000b9000 fili1=${UVDATA1}/warmat2,rcs=0064,typ=RSF filo1=${UVDATA2}/warmat2,rcs=0068,typ=RSF @run opn all loop get fili1,a0 skp> eof clr b0(0068),' ' init output area to all blanks #------------------------------------------------------------------------ mvc b0(30),a0(30) wm-cust : wm-descrip bal rfmxx,'a0030b08c08d0030e06f06y4','wm-purch-date' <--NOTE y4 mvc b38(12),a36(12) wm-policy : wm-exp-day ## bal rfmnn,'a0050b04c04d0048e02f02','wm-exp-year' <--original bal rfmnn,'a0046b08c08d0044e06f06y4','wm-exp-year' <--Modified mvc b54(14),a50(14) filler001 : filler002 #------------------------------------------------------------------------ put1 put filo1,b0 skp loop eof cls all eoj @pf2=reform2.sub
For 6 digit dates mmddyy, you only need to add the 'y4' option.
For 2 digit years (of mmddyy), you should also redefine as a 6 digit date by modifying the displacements & lengths as illustrated above.
Goto: Begin this document , End this document , UVSI Home-Page
'genrfm1' is a script that performs the multiple steps required to generate uvcopy reformat jobs (1 at a time). It is intended for regenerations required after correcting copybooks,etc.
genrfm1 data-file-name copy-book-name =====================================
genrfm1 warmas1 warmas1 =======================
See the 'genrfm1' script listed on the next page --->
Goto: Begin this document , End this document , UVSI Home-Page
#!/bin/ksh # genrfm1 - Generate uvcopy job to convert 1 data file # based on old & new versions of the copy-books # - expand dates for Y2K, or reformat records for any reason # - see REFORMjobs.doc of UVdoc # # This script executes the multi-steps to generate the uvcopy job # - For use when you only have 1 or 2 files to do # or for re-gens of specific jobs after copybook updates # - also see genrfm1a for sites with # - For mass conversions you should the 'ALL FILES IN DIRECTORY' # operating instructions documented in section 'G' of REFORMjobs.doc # # Must run from the conversion super-directory which contains # subdirectories: cpy1,cpy2,map1,map2,map1I,pfr1,pfr2 # # backup output dir 'pfr2' before regenerating jobs with modified code # backup: cp pfr2/* pfr3 # ============== # usage: genrfm1 dataFileName copyBookName # ================================= # Example: genrfm1 perm.audfile audfile # echo "genrfm1 using: cpy1,cpy2,map1,map2,map1I,pfr1,pfr2" if [[ -f "cpy1/$2" ]]; then : else echo "usage: genrfm1 DataFileName CopyBookName"; exit 9; fi echo "If regen job with modified code(R/T tests), did you backup pfr2->pfr3 ?' read reply # # select line from ctl/ctlrfm1 with matching filename & write to tmp/filename exec 3< ctl/ctlrfm1 # open ctlrfm1 ctl file for reading exec 4> tmp/ctl1 # open output file while read -u3 file line do if [[ $file = *${1}* ]] then print -u4 "$file $line"; break fi done exec 3<&- # close ctlrfm1 ctl file exec 4>&- # close output file # uvcopy cobmap1,fili1=cpy1/$2,filo1=map1/$2,uop=q0i7p0 # uvcopy cobmap1,fili1=cpy2/$2,filo1=map2/$2,uop=q0i7p0 # uvcopy reform1,fili1=map1/$2,filo1=map1I/$2,uop=q0i7 # uvcopy reform2,fili1=map2/$2,filo1=pfr1/$2,filr1=map1I/$2,uop=q0i7 # uvcopy uvdata52,fili1=tmp/ctl1,fild2=pfr1,fild3=pfr2,uop=q0i7 # echo "output in pfr2, recover R/T test code from pfr3 ?' exit 0
Goto: Begin this document , End this document , UVSI Home-Page
These jobs are not listed here, but all jobs are available for inspection or printing in /home/uvadm/pf.
Note |
|
mkctlf1 |
|
cobmap1 |
|
reform1 |
|
reform2 |
|
Note |
|
reform2.sub - field expansion/conversion sub-routines for the uvcopy jobs generated by reform2. These are stored in the /home/uvadm/pf uvcopy parameter files directory. They are loaded by the '@pf2=reform2.sub' instruction at the end of each generated job.
uvdata52 - convert uvcopy skeleton jobs into complete jobs - with data-file-names supplied by the control file - with correct file types & Indexed keys supplied by control file - see DATAcnvt2.doc
genrfm1 |
|
Goto: Begin this document , End this document , UVSI Home-Page
# reform2.sub - subrtns for uvcopy jobs generated by reform2 # - see REFORMjobs.doc in vol 3 of UVdoc # # This collection of subrtns is loaded by the '@pf2=reform2.sub' instruction # which appears at the end of the uvcopy jobs generated by reform2. # This enables the generated jobs to be as short as possible, yet have # access to the extended logic required for date expansion (including tests # for century insert, windowing, suppression for zero/blank/nines fields). # # Subrtns are named depending on op1/op2 data formats # rfmxx - alphanum to alphanum, # rfmnn - numeric to numeric # rfmpp - packed to packed # rfmbb - binary to binary # # Subrtns are provided for all possible combinations. # A few that make sense are: rfmxn, rfmpn, rfmbn, etc. # #990513 - allow registers 'j' & 'k' for dates in occurs # - option 'y4' for date formats mmddyy/ddmmyy (vs default yymmdd) #990515 - option 'n' to retain nulls &/or blanks in numeric fields # - option 'p' to retain nulls &/or blanks in numeric fields # - option 's' to specify signs in packed fields x'_C' or x'_F' # - option 'x' to convert nulls/blanks/zeros in alphanum fields # - see complete documentation in REFORMjobs.doc (volume 3 of UVdoc) # #------------------------------------------------------------------------ # rfmxx - reformat alpha/numeric flds, allowing century insert or lth chg # - this is 1 of reform2.sub collection of subrtns that may be # called by the jobs generated by reform2 via @pf2=reform2.sub # - sample call as follows: # # bal rfmxx,'a____b__c__d____e__f__','fname' # bal rfmxx,'a0030b08c08d0030e06f06','fname' # bal rfmxx,'a0030b08c08d0030e06f06g7w75y4','fname' <- option override # rfmxx bal pop common subrtn to process options, load rgstrs, etc # # get input data to d0(20)max test/insert century (comx for a/n data) bal comx get a/n data, insert century # # move input to output staging area, don't really need for rfmxx, # but do need for rfmnn,rfmpp,etc so follow standard procedures rfmxx4 mvc d40(16),d0 move in to out stage area # # now move to output field in record (via rgstr dsplcmnt & lth) mvc ba0($rb16),d40 store field in outrec # # subrtn to test option 'x' to convert nulls/blanks/zeros in numeric fields bal topx ret=
Goto: Begin this document , End this document , UVSI Home-Page
There are 4 common subrtns called by the 4 main 'rfm__' subrtns. These are named for the input data type being handled (comx, comn, comp, comb).
# comx - get input data & test/insert century - for alpha/num data # - common subrtn called by various rfm__ subrtns # - test option g1+ & lth diff 2, if not return condition '!' # - ifso insert century (test 19/20,blanks,zeros,nines) & return cc '=' # comx mvc d0($re16),ad0 retrieve input a/n data mvc d90(2),'19' presume century insert '19' mvc d80(6),d0 store 1st 2 wintest + 4 blank/zero/nines test cmn $popby,4 format mmddyy/ddmmyy (vs yymmdd) ? skp< 2 mvc d80(2),d4 store win test for mmddyy format mvc d82(4),d0 store blank/zero/nine test for mmddyy format # # test option g1+ & lth diff 2, if not return condition '!' to inhibit tsb g0(1),x'01' optn g1 for century insert ? skp! comx90 no - go exit with cc ! (to inhibit) cmn $ca3,2 op1 - op2 = 2 ? skp! comx90 no - go exit cc ! to inhibit # # test optn g2 for windows test & compare yy to optn w window value tsb g0(1),x'02' optn g2 for windows test ? skp! comx30 no - bypass test for 19/20 cmn d80(2),$popbw 2 digit year > window option ? skp=> 1 mvc d90(2),'20' no - change '19' to '20' # # test for blank field, ifso insert blank century comx30 cmc d0(2),' ' 1st 2 bytes (yy) blank ? skp! 1 mvc d90(2),' ' yes # # test for zeros field, ifso insert zeros for century # optn to test 5 bytes, since 00 may be valid for 2 digit year # - test 5 bytes to allow julian format yyddd comx40 cmc d80(5),'00000' 1st 5 00000 ? skp! 1 mvc d90(2),'00' yes, set century insert '00' # # test for nines field, ifso store century insert as '99' comx50 tsb g0(1),x'04' option to test for nines ? skp! comx80 comx54 cmc d80(4),'9999' yes, 1st 4 9999 ? skp! 1 mvc d90(2),'99' yes, set century insert '99' # # insert century & exit with condition = (indicates century inserted) comx80 ins dy0(20),d90(2) insert century (rg y=4 if mmddyy) add $rf,2 lth rgstr +2 for cc insert ret= comx90 ret<
Goto: Begin this document , End this document , UVSI Home-Page