MVSFORUMS.com Forum Index MVSFORUMS.com
A Community of and for MVS Professionals
 
 FAQFAQ   SearchSearch   Quick Manuals   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

DFSORT INREC PARSE - convert CSV to fixed.

 
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Utilities
View previous topic :: View next topic  
Author Message
Magesh_J
Intermediate


Joined: 21 Jun 2014
Posts: 259
Topics: 54

PostPosted: Sun May 08, 2016 5:33 pm    Post subject: DFSORT INREC PARSE - convert CSV to fixed. Reply with quote

Hi,

I am trying to convert CSV to Fixed.

Code:

05/06/2016,eeeeeeeeeee vvvvvvvvv ddd aasssssss,aa,2016,999.88,0.00,0.00,0.00,-0.60,09,009900099,xxxttttttttt,zzzzz aaaaaa,ddddddddddddddddd,999.99
05/06/2016,vvvvvvvvvvv ddddddddd fff fffffffff,kk,2016,887.77,0.00,0.00,0.00,0.889,09,008898888,tttttttttttt,ttttt tttttt,ttttttttttttttttt,888.88


In the above screen it is showing two lines of record but it is a single line.

Sort code i tried
Code:

OPTION COPY                                                 
INREC IFTHEN=(WHEN=INIT,                                   
      PARSE=(%00=(ENDBEFR=C',',FIXLEN=10,PAIR=QUOTE),       
            %01=(ENDBEFR=C',',FIXLEN=50,PAIR=QUOTE),       
            %02=(ENDBEFR=C',',FIXLEN=02,PAIR=QUOTE),       
            %03=(ENDBEFR=C',',FIXLEN=04,PAIR=QUOTE),       
            %04=(ENDBEFR=C',',FIXLEN=10,PAIR=QUOTE),       
            %05=(ENDBEFR=C',',FIXLEN=10,PAIR=QUOTE),       
            %06=(ENDBEFR=C',',FIXLEN=10,PAIR=QUOTE),       
            %07=(ENDBEFR=C',',FIXLEN=10,PAIR=QUOTE),       
            %08=(ENDBEFR=C',',FIXLEN=10,PAIR=QUOTE),       
            %09=(ENDBEFR=C',',FIXLEN=2,PAIR=QUOTE),         
            %10=(ENDBEFR=C',',FIXLEN=9,PAIR=QUOTE)),       
     BUILD=(%00,%04,SFF,TO=ZD,LENGTH=9,                     
                %05,SFF,TO=ZD,LENGTH=9,                     
                %06,SFF,TO=ZD,LENGTH=9,                     
                %07,SFF,TO=ZD,LENGTH=9,                     
                %08,SFF,TO=ZD,LENGTH=9,                     
                %10))                                       


The challenge i have is 3 digit decimal 0.889, i need the output in following format.


Code:

01  DETAIL-RECORD.                 
   05 C1             PIC X(10).     
   05 N1             PIC S9(7)V99. 
   05 N2             PIC S9(7)V99. 
   05 N3             PIC S9(7)V99. 
   05 N4             PIC S9(7)V99. 
   05 N5             PIC S9(7)V99. 
   05 C2             PIC X(4).     
   05 C3             PIC X(5).     


Please advise

Thanks
Magesh
Back to top
View user's profile Send private message
William Collins
Supermod


Joined: 03 Jun 2012
Posts: 437
Topics: 0

PostPosted: Mon May 09, 2016 12:02 am    Post subject: Reply with quote

You've shown 11 PARSEd fields, and eight in a COBOL copybook. They're not going to match up, but I'm not going to check on why.

What problem does 0.889 give you? You need to store it rounded with two decimal places, or something else?
Back to top
View user's profile Send private message
Magesh_J
Intermediate


Joined: 21 Jun 2014
Posts: 259
Topics: 54

PostPosted: Mon May 09, 2016 8:56 pm    Post subject: Reply with quote

Hi William,

Thanks for looking in to my request.

I would like to know, how we should handle decimal points.
0.896, if i convert this to ZD, how it gets converted, if i view in file aid, it is showing as 8.96, but i need this to be 0.90
, we are giving only total length in the control card, and not the decimal length.

Please advise, how does the sort determines the decimal point.

i need the output values in S9(7)v99.

Thanks
Magesh
Back to top
View user's profile Send private message
William Collins
Supermod


Joined: 03 Jun 2012
Posts: 437
Topics: 0

PostPosted: Tue May 10, 2016 12:47 am    Post subject: Reply with quote

OK, a simpler question. SORT does not know a single thing about decimal alignment or rounding, you have to do it all yourself.

With a variable number of decimal places present, you are going to end up PARSEing your field, integer part and decimal part. Then stick them together next to each other, then look to do any zero-padding, then the rounding (look at the final digit, if greater than 4 (GE 5) add one to the number excluding the final digit. Then locate your rounded-and-fixed-number-of-decimal-places data to wherever you want finally.

Inserting actual decimal points can be done with the EDIT and a mask. Alignment is just on the length of the field, and the decimal point is at a fixed place in the mask.
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12375
Topics: 75
Location: San Jose

PostPosted: Tue May 10, 2016 10:29 am    Post subject: Reply with quote

Magesh_J,

As william pointed out, DFSORT does not differentiate the decimal dot. So if your requirement is to just have 2 decimals , then you need to define the rules for rounding.

if you have the following values what do you do?

Code:

0.838  ROUNDED TO 0.84 OR 0.85 ?   
1.009  ROUNDED TO 1.01 OR 1.10 ?   
2.994  ROUNDED TO 2.95 OR 3.00 ?   
2.996  ROUNDED TO 3.00 OR ???     


btw if you have plans of building the parsed values you don't have to store them you can use % to just skip them. Something like this

Code:

INREC  PARSE=(%00=(ENDBEFR=C',',FIXLEN=10,PAIR=QUOTE),   
             %=(ENDBEFR=C','),     
             %=(ENDBEFR=C','),     
             %=(ENDBEFR=C','),     
                                                       
             %01=(ENDBEFR=C'.',FIXLEN=7),               
             %02=(ENDBEFR=C',',FIXLEN=3),               
                                                       
             %03=(ENDBEFR=C'.',FIXLEN=7),               
             %04=(ENDBEFR=C',',FIXLEN=3),               
                                                       
             %05=(ENDBEFR=C'.',FIXLEN=7),               
             %06=(ENDBEFR=C',',FIXLEN=3),               
                                                       
             %07=(ENDBEFR=C'.',FIXLEN=7),               
             %08=(ENDBEFR=C',',FIXLEN=3),               
                                                       
             %09=(ENDBEFR=C'.',FIXLEN=7),               
             %10=(ENDBEFR=C',',FIXLEN=3),               
                                                       
             %=(ENDBEFR=C','),     
             %11=(ENDBEFR=C',',FIXLEN=9,PAIR=QUOTE)),   
BUILD=(%00,                         
      %01,JFY=(SHIFT=RIGHT),         
      %02,               
                                     
      %03,JFY=(SHIFT=RIGHT),         
      %04,               
                                     
      %05,JFY=(SHIFT=RIGHT),         
      %06,               
                                     
      %07,JFY=(SHIFT=RIGHT),         
      %08               
                                     
      %09,JFY=(SHIFT=RIGHT),         
      %10)     


Now you can validate the 3 decimal digit and then perform the rounding.
_________________
Kolusu
www.linkedin.com/in/kolusu


Last edited by kolusu on Mon Jul 24, 2017 10:52 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Magesh_J
Intermediate


Joined: 21 Jun 2014
Posts: 259
Topics: 54

PostPosted: Thu May 12, 2016 2:09 pm    Post subject: Reply with quote

Thanks William and Kolusu for the kind solution.

Please find the below round off details.

Code:

0.838  ROUNDED TO 0.84
1.009  ROUNDED TO 1.01
2.994  ROUNDED TO 2.99
2.996  ROUNDED TO 3.00


Kolusu wrote:

DFSORT does not differentiate the decimal dot.


I have told that i may get values s9(7)v999. But all my host file variables are s9(7)v99, so I have instructed source team to send only with two decimal points.

If they come with 2 decimals points

I will get values max off -9999999.99, so when i do the parse, i have to give Fix length of 11 and when i convert it to ZD i should give length 9 ?
or what is the length i should give.

If they cant, then i should add +.01 if 3rd byte of decimal is greater than 5 and add none when it is less than or equal to 5, then i can ignore the last byte of the field and then convert it to ZD. But still same question what is the length i should give when i convert it to ZD, The parse with '.' will remove the decimal, so i need to add the decimal point manually or to use the edit STTTTTTT.TT and the convert to ZD ?

Please advise.


Thanks
Magesh
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12375
Topics: 75
Location: San Jose

PostPosted: Thu May 12, 2016 6:00 pm    Post subject: Reply with quote

Magesh_J wrote:

I have told that i may get values s9(7)v999. But all my host file variables are s9(7)v99, so I have instructed source team to send only with two decimal points.

If they come with 2 decimals points

I will get values max off -9999999.99, so when i do the parse, i have to give Fix length of 11 and when i convert it to ZD i should give length 9 ?
or what is the length i should give.

If they cant, then i should add +.01 if 3rd byte of decimal is greater than 5 and add none when it is less than or equal to 5, then i can ignore the last byte of the field and then convert it to ZD. But still same question what is the length i should give when i convert it to ZD, The parse with '.' will remove the decimal, so i need to add the decimal point manually or to use the edit STTTTTTT.TT and the convert to ZD ?

Please advise.


Thanks
Magesh


Magesh,

You are complicating a simple request. Unless it is a numeric edited field neither COBOL nor DFSORT would care as to where the decimal dot is.

So if you have a 9 field and it contains 123456789 you can read the same data in different ways depending on your Cobol declaration.

So if you have
Code:

N1  PIC S9(1)V9(8). the value 123456789 will be 1.23456789

N2  PIC S9(2)V9(7). the value 123456789 will be 12.3456789


N3  PIC S9(3)V9(6). the value 123456789 will be 123.456789
 
...


So forget about the intricacies of handling the decimal digit. You only need to be concerned about handling the maximum value in a 9 byte zd field.

From the looks of it you can have 8 digits ( 1 byte sign and 7 byte numeric data for integer portion ) and may have a max 3 digits for decimals.

So those values fit in perfectly into S9(7)V99 as you are rounding the decimals.

Here is the Job which would give you the desired results.
Code:

//STEP0100 EXEC PGM=SORT                                     
//SYSOUT   DD SYSOUT=*                                       
//SORTIN   DD DISP=SHR,DSN=Your Input CSV file
//SORTOUT  DD SYSOUT=*                                       
//SYSIN    DD *                                             
  OPTION COPY                                               
  INREC IFOUTLEN=71,                                         
  IFTHEN=(WHEN=INIT,                                         
         PARSE=(%00=(ENDBEFR=C',',FIXLEN=10,PAIR=QUOTE),     
                %=(ENDBEFR=C','),       
                %=(ENDBEFR=C','),       
                %=(ENDBEFR=C','),       
                                                             
                %01=(ENDBEFR=C'.',FIXLEN=8),                 
                %02=(ENDBEFR=C',',FIXLEN=3),                 
                                                             
                %03=(ENDBEFR=C'.',FIXLEN=8),                 
                %04=(ENDBEFR=C',',FIXLEN=3),                 
                                                             
                %05=(ENDBEFR=C'.',FIXLEN=8),                 
                %06=(ENDBEFR=C',',FIXLEN=3),                 
                                                             
                %07=(ENDBEFR=C'.',FIXLEN=8),                 
                %08=(ENDBEFR=C',',FIXLEN=3),                 
                                                             
                %09=(ENDBEFR=C'.',FIXLEN=8),                 
                %10=(ENDBEFR=C',',FIXLEN=3),                 
                                                             
                %=(ENDBEFR=C','),       
                %11=(ENDBEFR=C',',FIXLEN=9,PAIR=QUOTE)),     

         BUILD=(%00,                                   $ FIELD-1       
                C'|',                                  $ SEPARATOR     
                50X,                                   $ 50 SPACES     
                %11,                                   $ FIELD-11     
                C'|',                                  $ SEPARATOR     
                                                                       
                075:%01,JFY=(SHIFT=RIGHT),             $ NUM-1         
                    %02,                               $ DEC-1         
                                                                       
                090:%03,JFY=(SHIFT=RIGHT),             $ NUM-2         
                    %04,                               $ DEC-2         
                                                                       
                105:%05,JFY=(SHIFT=RIGHT),             $ NUM-3         
                    %06,                               $ DEC-3         
                                                                       
                120:%07,JFY=(SHIFT=RIGHT),             $ NUM-4         
                    %08,                               $ DEC-4         
                                                                       
                135:%09,JFY=(SHIFT=RIGHT),             $ NUM-5         
                    %10)),                             $ DEC-5         
                                                                       
*** CHECK IF NUM-1 FIELD HAS 3 DECIMAL DIGITS AND ROUND IT       
                                                                 
  IFTHEN=(WHEN=(085,1,FS,LE,5),                                 
  OVERLAY=(12:075,10,SFF,ZD,LENGTH=9,C'|'),HIT=NEXT),           
                                                                 
  IFTHEN=(WHEN=(085,1,FS,GT,5),                                 
  OVERLAY=(12:075,10,SFF,ADD,+01,ZD,LENGTH=9,C'|'),HIT=NEXT),   
                                                                 
*** CHECK IF NUM-2 FIELD HAS 3 DECIMAL DIGITS AND ROUND IT       
                                                                 
  IFTHEN=(WHEN=(100,1,FS,LE,5),                                 
  OVERLAY=(22:090,10,SFF,ZD,LENGTH=9,C'|'),HIT=NEXT),           
                                                                 
  IFTHEN=(WHEN=(100,1,FS,GT,5),                                 
  OVERLAY=(22:090,10,SFF,ADD,+01,ZD,LENGTH=9,C'|'),HIT=NEXT),   
                                                                 
*** CHECK IF NUM-3 FIELD HAS 3 DECIMAL DIGITS AND ROUND IT       
                                                                 
  IFTHEN=(WHEN=(115,1,FS,LE,5),                                 
  OVERLAY=(32:105,10,SFF,ZD,LENGTH=9,C'|'),HIT=NEXT),           
                                                                 
  IFTHEN=(WHEN=(115,1,FS,GT,5),                                 
  OVERLAY=(32:105,10,SFF,ADD,+01,ZD,LENGTH=9,C'|'),HIT=NEXT),   
                                                                 
*** CHECK IF NUM-4 FIELD HAS 3 DECIMAL DIGITS AND ROUND IT       
                                                                 
  IFTHEN=(WHEN=(130,1,FS,LE,5),                                 
  OVERLAY=(42:120,10,SFF,ZD,LENGTH=9,C'|'),HIT=NEXT),           
                                                                 
  IFTHEN=(WHEN=(130,1,FS,GT,5),                                 
  OVERLAY=(42:120,10,SFF,ADD,+01,ZD,LENGTH=9,C'|'),HIT=NEXT),   
                                                                 
*** CHECK IF NUM-5 FIELD HAS 3 DECIMAL DIGITS AND ROUND IT       
                                                                 
  IFTHEN=(WHEN=(145,1,FS,LE,5),                                 
  OVERLAY=(52:135,10,SFF,ZD,LENGTH=9,C'|'),HIT=NEXT),           
                                                                 
  IFTHEN=(WHEN=(145,1,FS,GT,5),                                 
  OVERLAY=(52:135,10,SFF,ADD,+01,ZD,LENGTH=9,C'|'))             
                                                                 
//*                                                             


The output from this job is
Code:

05/06/2016|000099988|000000000|000000000|000000000|00000006}|009900099|
05/06/2016|000088777|000000000|000000000|000000000|000000089|008898888|

_________________
Kolusu
www.linkedin.com/in/kolusu


Last edited by kolusu on Mon Jul 24, 2017 10:51 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Magesh_J
Intermediate


Joined: 21 Jun 2014
Posts: 259
Topics: 54

PostPosted: Fri Jun 03, 2016 2:24 pm    Post subject: Reply with quote

Thanks Kolusu for the solution. working great
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Utilities All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


MVSFORUMS
Powered by phpBB © 2001, 2005 phpBB Group