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

Convert VB file to FB plus special formatting


IBM Mainframe Forums -> SYNCSORT
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
cz016m

New User


Joined: 09 Mar 2016
Posts: 9
Location: United States

PostPosted: Fri Oct 19, 2018 7:26 pm
Reply with quote

Hello,

I have been working on converting a variable length, tab delimited file from (VB 512) to fixed block (FB 80) for a couple days now with limited success. I'm struggling with date conversion, among other things, and I haven't been able to find many examples of what I'm trying to do in the Syncsort manual or online and time is of the essence.

This is what I've written so far:
Code:

  OPTION SKIPREC=1                                             
       OMIT COND=(1,1,CH,EQ,X'05')                             
     INREC PARSE=(%01=(ENDBEFR=X'05',FIXLEN=08),
                  %02=(ENDBEFR=X'05',FIXLEN=05),
                  %03=(ENDBEFR=X'05',FIXLEN=09),
                  %04=(STARTAFT=X'7F',ENDBEFR=X'7F',FIXLEN=30),
                  %05=(ENDBEFR=X'05',FIXLEN=01),
                  %06=(ENDBEFR=C'-',FIXLEN=03),
                  %07=(ENDBEFR=C'-',FIXLEN=02),
                  %08=(ENDBEFR=X'05',FIXLEN=04),
                  %09=(ENDBEFR=X'05',FIXLEN=01),
                  %10=(ENDBEFR=X'05',FIXLEN=01)),
           BUILD=(001,004,
                  %06,
                  %07,
                  %08,
                  %04,
                  %03,
                  %02,
                  %01,
                  %09,
                  %10,
                  C'C')                                       
     SORT FIELDS=COPY                                         


I'd like to do this in one sort step. I need to skip the first record in the input file because it contains headers that I don't want. The fields are separated by hexadecimal tab (X'05'). The input file has data in some rows that I want to process, but hexadecimal tabs (X'05') for the first 31 bytes in other rows that I don't want in my output.

The date must be converted from format 16-APR-18 to 20180416.

The double quotes and comma must be removed from the name, there must be a space between the last and first names, and the last and first names combined must not exceed 30 bytes, padded on the right with spaces or truncated on the right, if the name exceeds 30 bytes.

The dashes must be removed from the 9-digit number.

The letter "C" must be appended immediately after the last significant value in the record. This should be in position 63 of the output record. The remaining 17 bytes at the end of the record (positions 64 through 80) should be padded with spaces.

Below is the input file with 10 records. The last five records appear to be contain spaces, but they actually contain hexadecimal "05" (Tab) in the first 31 bytes. After the last byte of significant data on each input record, there are 25 hexadecimal tabs (X'05') and the remainder of the 512 VB record is padded with spaces.
Code:

field_1 field_2 field_3 field_4 field_5 field_6 field_7     
CPG75145 4275 16-Apr-18 "DOE, JOHN" 123-45-6789 E A       
CPG75147 3495 20-May-18 "DOE, JANE" 234-56-7891 E A     
CPG75148 1010 21-Jun-18 "JAMES, LEBRON" 345-67-8912 E A         
CPG75150 3500 21-Jul-18 "IRVING, KYRIE" 456-78-9123 E A
CPG75152 4860 16-Aug-18 "MAYFIELD, BAKER" 567-89-1234 O R   







The records do not need to be sorted in any particular sequence. This is what the output file should look like:
Code:

123456789DOE JOHN                      2018041604275CPG75145ERC
234567891DOE JANE                      2018052003495CPG75147ERC
345678912JAMES LEBRON                  2018062101010CPG75148ERC
456789123IRVING KYRIE                  2018072103500CPG75150ERC
567891234MAYFIELD BAKER                2018081604860CPG75152ORC


Output record layout:
Positions 01 - 09: Fixed length, 9 bytes
Positions 10 - 39: Fixed length, 30 bytes, left justified and padded on the right with spaces
Positions 40 - 47: Fixed length, 8 bytes, YYYYMMDD
Positions 48 - 52: Fixed length, 5 bytes, right justified and padded with zeroes on the left
Positions 53 - 60: Fixed length, 8 bytes
Positions 61 - 61: Fixed length, 1 byte
Positions 62 - 62: Fixed length, 1 byte
Positions 63 - 80: Fixed length, 18 bytes, value "C "

I don't get to use Syncsort as often as I'd like to. Any assistance with reformatting this file would be appreciated.

Thank you for your time.
Back to top
View user's profile Send private message
Arun Raj

Moderator


Joined: 17 Oct 2006
Posts: 2481
Location: @my desk

PostPosted: Fri Oct 19, 2018 7:51 pm
Reply with quote

cz016m,

Welcome to the forums. Nice job with all the details in your first post.

Quote:
Positions 62 - 62: Fixed length, 1 byte
Is that a typo in your expected output, should it be all 'A's except for the last record?
Back to top
View user's profile Send private message
cz016m

New User


Joined: 09 Mar 2016
Posts: 9
Location: United States

PostPosted: Fri Oct 19, 2018 8:47 pm
Reply with quote

Hello,

Yes, there was a typo. Position 62 should be fixed length, 1 byte and take whatever is on the input file. It could be "A" or "R".

Here is what the output should look like (corrected):
Code:

123456789DOE JOHN                      2018041604275CPG75145EAC
234567891DOE JANE                      2018052003495CPG75147EAC
345678912JAMES LEBRON                  2018062101010CPG75148EAC
456789123IRVING KYRIE                  2018072103500CPG75150EAC
567891234MAYFIELD BAKER                2018081604860CPG75152ORC


Thank you for your response.
Back to top
View user's profile Send private message
Arun Raj

Moderator


Joined: 17 Oct 2006
Posts: 2481
Location: @my desk

PostPosted: Fri Oct 19, 2018 10:44 pm
Reply with quote

cz016m,

Since the input is VB, you might want to check this at pos-5 instead of pos-1.
Code:
OMIT COND=(1,1,CH,EQ,X'05')
Back to top
View user's profile Send private message
cz016m

New User


Joined: 09 Mar 2016
Posts: 9
Location: United States

PostPosted: Fri Oct 19, 2018 10:55 pm
Reply with quote

I saw that too and applied a fix.

Thank you!
Back to top
View user's profile Send private message
Arun Raj

Moderator


Joined: 17 Oct 2006
Posts: 2481
Location: @my desk

PostPosted: Fri Oct 19, 2018 11:28 pm
Reply with quote

cz016m,

I don't have Syncsort, so cannot test this, but this should get you started. Good luck.

Also note that I have hard-coded the century as 20, you could change it to use the appropriate Syncsort date function to do the actual date conversion instead (Use CENTWIN parm to determine the century window while converting 2 digit years to 4 digit years).

Code:
//SYSIN    DD *                                                   
  OPTION SKIPREC=1                                                 
  OMIT COND=(5,1,CH,EQ,X'05')                                     
  INREC PARSE=(%01=(ENDBEFR=X'05',FIXLEN=08),                     
               %02=(ENDBEFR=X'05',FIXLEN=05),                     
               %03=(ENDBEFR=X'05',FIXLEN=09),                     
               %04=(STARTAFT=X'7F',ENDBEFR=X'7F',FIXLEN=30),       
                 %=(ENDBEFR=X'05',FIXLEN=01),                     
               %05=(ENDBEFR=X'05',FIXLEN=11),                     
               %06=(ENDBEFR=X'05',FIXLEN=01),                     
               %07=(ENDBEFR=X'05',FIXLEN=01)),                     
        BUILD=(001,004,                                           
               %05,UFF,ZD,LENGTH=9,                               
               30X,                                               
               08X,                                               
               %02,UFF,ZD,LENGTH=5,                               
               %01,                                               
               %06,                                               
               %07,                                               
               C'C',                                                   
               %03,                                                   
               %04)                                                   
  SORT FIELDS=COPY                                                     
  OUTREC IFTHEN=(WHEN=INIT,OVERLAY=(71:71,3,                           
  CHANGE=(3,C'Jan',C'01',C'Feb',C'02',C'Mar',C'03',C'Apr',C'04',       
            C'May',C'05',C'Jun',C'06',C'Jul',C'07',C'Aug',C'08',       
            C'Sep',C'09',C'Oct',C'10',C'Nov',C'11',C'Dec',C'12'),     
  NOMATCH=(71,3))),                                                   
         IFTHEN=(WHEN=INIT,FINDREP=(IN=C',',OUT=C'',STARTPOS=77)),     
         IFTHEN=(WHEN=INIT,OVERLAY=(14:77,30,44:C'20',75,2,71,2,68,2))
  OUTFIL VTOF,BUILD=(5,63,80:X)
Back to top
View user's profile Send private message
cz016m

New User


Joined: 09 Mar 2016
Posts: 9
Location: United States

PostPosted: Sat Oct 20, 2018 12:52 am
Reply with quote

It's throwing a syntax error on the INREC statement, but I will work it out.

It doesn't like something about the "30X," line.

Thank you!
Back to top
View user's profile Send private message
Arun Raj

Moderator


Joined: 17 Oct 2006
Posts: 2481
Location: @my desk

PostPosted: Sat Oct 20, 2018 2:33 am
Reply with quote

Could you post the complete error message from SYSOUT?
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2010
Location: USA

PostPosted: Sun Oct 21, 2018 1:12 am
Reply with quote

Important fix needs to be added to make the code more robust: handling person name field more flexible, and do not change final field size, neither with, nor without comma in input data.

ABSPOS=5 is needed to ignore possible X'05' as part of RDW.

Code:
* OPTION SKIPREC=1                                                       
   OMIT COND=(5,1,CH,EQ,X'05')                                           
   INREC PARSE=(%01=(ABSPOS=5,ENDBEFR=X'05',FIXLEN=08),                           
                %02=(ENDBEFR=X'05',FIXLEN=05),                           
                %03=(ENDBEFR=X'05',FIXLEN=09),                           
                %04=(STARTAFT=C'"',ENDBEFR=C'"',FIXLEN=30),           
                  %=(ENDBEFR=X'05'),  (length not needed to skip field)                           
                %05=(ENDBEFR=X'05',FIXLEN=11),                           
                %06=(ENDBEFR=X'05',FIXLEN=01),                           
                %07=(ENDBEFR=X'05',FIXLEN=01)),                         
         BUILD=(1,4,                 RDW                                                   
                %05,UFF,ZD,LENGTH=9, compressed phone number             
                %04,SQZ=(SHIFT=LEFT,LENGTH=30,PREBLANK=C',',MID=C' '),   
*                   <-to provide optional comma with stable length->     
                C'20',               fixed century (unflexible...)       
                %03,                 date as C'dd-mon-yy'               
                %02,UFF,ZD,LENGTH=5, five digits code                   
                %01,                 long code                           
                %06,%07,             two code characters                 
                C'C',                final constant 'C'                 
                20X)                 filler, to satisfy OUTFIL           
   SORT FIELDS=COPY                                                     
   OUTREC FINDREP=(INOUT=(C'-Jan-',C'01',                               
                          C'-Feb-',C'02',                               
                          C'-Mar-',C'03',                               
                          C'-Apr-',C'04',                 
                          C'-May-',C'05',                 
                          C'-Jun-',C'06',                 
                          C'-Jul-',C'07',                 
                          C'-Aug-',C'08',                 
                          C'-Sep-',C'09',                 
                          C'-Oct-',C'10',                 
                          C'-Nov-',C'11',                 
                          C'-Dec-',C'12'))               
  OUTFIL VTOF,                                           
         BUILD=(5,41,             initial part           
               50,2,48,2,46,2,    exchange DD <-> YY     
               52,33)             final part             
 END                                                     


Code:
********************************* TOP OF DATA *********************************
123456789DOE JOHN                      2018041604275CPG75145EAC               
234567891DOE JANE                      2018052003495CPG75147EAC               
345678912JAMES LEBRON                  2018062101010CPG75148EAC               
456789123IRVING KYRIE                  2018072103500CPG75150EAC               
567891234MAYFIELD BAKER                2018081604860CPG75152ORC               
******************************** BOTTOM OF DATA *******************************
Back to top
View user's profile Send private message
Arun Raj

Moderator


Joined: 17 Oct 2006
Posts: 2481
Location: @my desk

PostPosted: Sun Oct 21, 2018 7:52 am
Reply with quote

sergeyken - you might want to modify your approach to handle embedded blanks in the firstname or lastname (though not shown in the OPs sample data).
Back to top
View user's profile Send private message
cz016m

New User


Joined: 09 Mar 2016
Posts: 9
Location: United States

PostPosted: Sun Oct 21, 2018 4:10 pm
Reply with quote

Yes, there could be middle initials or multiple values in the name field, even though I didn't show them in the sample input data.

Updated input:
Code:

field_1 field_2 field_3 field_4 field_5 field_6 field_7     
CPG75145 4275 16-Apr-18 "DOE, JOHN" 123-45-6789 E A       
CPG75147 3495 20-May-18 "DOE, JANE" 234-56-7891 E A     
CPG75148 1010 21-Jun-18 "JAMES JR, LEBRON R" 345-67-8912 E A         
CPG75150 3500 21-Jul-18 "IRVING, KYRIE" 456-78-9123 E A
CPG75152 4860 16-Aug-18 "MAYFIELD, BAKER" 567-89-1234 O R   


Updated output:
Code:

123456789DOE JOHN                      2018041604275CPG75145ERC
234567891DOE JANE                      2018052003495CPG75147ERC
345678912JAMES JR LEBRON R             2018062101010CPG75148ERC
456789123IRVING KYRIE                  2018072103500CPG75150ERC
567891234MAYFIELD BAKER                2018081604860CPG75152ORC


Thank you very much for your help!
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2010
Location: USA

PostPosted: Sun Oct 21, 2018 5:33 pm
Reply with quote

Arun Raj wrote:
sergeyken - you might want to modify your approach to handle embedded blanks in the firstname or lastname (though not shown in the OPs sample data).

I always do such modifications when creating code for my own job
Here I just wanted to give the idea how to handle this in appropriate way. Anybody may feel free to add his own modifications, to fulfil requirements of his own job.
This forum is not supposed to fully complete a task assigned to someone else.
Back to top
View user's profile Send private message
Arun Raj

Moderator


Joined: 17 Oct 2006
Posts: 2481
Location: @my desk

PostPosted: Mon Oct 22, 2018 10:30 am
Reply with quote

cz016m wrote:
Yes, there could be middle initials or multiple values in the name field, even though I didn't show them in the sample input data.
cz016m,

The solution I had posted earlier would handle this scenario.
If you're running into syntax issues, post the complete error message. Someone would be able to help with that.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2010
Location: USA

PostPosted: Mon Oct 22, 2018 5:50 pm
Reply with quote

Arun Raj wrote:
sergeyken - you might want to modify your approach to handle embedded blanks in the firstname or lastname (though not shown in the OPs sample data).

There is no need for any modification; this situation is handled in my approach in normal way.
Back to top
View user's profile Send private message
cz016m

New User


Joined: 09 Mar 2016
Posts: 9
Location: United States

PostPosted: Mon Oct 22, 2018 6:20 pm
Reply with quote

Hello,

I wanted to say thank you, Arun Raj & sergeyken, for the help. There will always be a comma in the name, so sergeyken's solution works perfectly, even when there are middle initials.

Thank you very much!
Back to top
View user's profile Send private message
Arun Raj

Moderator


Joined: 17 Oct 2006
Posts: 2481
Location: @my desk

PostPosted: Mon Oct 22, 2018 6:52 pm
Reply with quote

Quote:
There is no need for any modification; this situation is handled in my approach in normal way.
My bad. I missed you have MID in your control statements. Thanks!

cz016m - Good to hear it is working for you. I don't have Syncsort, but DFSORT and the DFSORT solution gave me the expected output for both the sample inputs.
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 -> SYNCSORT

 


Similar Topics
Topic Forum Replies
No new posts Extracting Variable decimal numbers f... DFSORT/ICETOOL 17
No new posts SFTP Issue - destination file record ... All Other Mainframe Topics 2
No new posts Access to non cataloged VSAM file JCL & VSAM 18
No new posts Need help for File Aid JCL to extract... Compuware & Other Tools 23
No new posts Need to convert date format DFSORT/ICETOOL 20
Search our Forums:

Back to Top