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

Extract records for a specific condition IFTHEN=(WHEN=GROUP)


IBM Mainframe Forums -> DFSORT/ICETOOL
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Fri Jul 11, 2025 6:48 pm
Reply with quote

There was an earlier post almost similar to my requirement but with one additional challenge and I would like to get some inputs on how to handle it.

I need to extract records for the below scenario.

Input file has following record set rules. A record set always starts with one '001' record, followed by one or more '002' records and finally ends with 2 '005' records.
Per my requirement in the record set if there are no '002' records, then we need to OMIT the '001' and '005' records from that set.

Input -
001
002
005
005
001
005
005
001
002
002
002
005
005

Output -
001
002
005
005
001
002
002
002
005
005

I was trying to tweak the earlier solution provided for one '005' records but could not figure out since there are 2 '005' records in my input file.
Could you suggest a solution.
//SYSIN DD *
OPTION COPY

INREC IFTHEN=(WHEN=GROUP,
BEGIN=(1,3,CH,EQ,C'002'),
PUSH=(6:1,5,SEQ=1),
RECORDS=2)
OUTFIL OMIT=(11,1,CH,EQ,C'1',
OR,
1,3,CH,EQ,C'005',
AND,
6,3,CH,EQ,C'002'),
IFOUTLEN=5,
IFTHEN=(WHEN=(6,1,CH,NE,C' '),
BUILD=(6,5,
/,
1,5))
Back to top
View user's profile Send private message
Joerg.Findeisen

Senior Member


Joined: 15 Aug 2015
Posts: 1442
Location: Bamberg, Germany

PostPosted: Sat Jul 12, 2025 6:45 am
Reply with quote

Please use the code tags when presenting code/data to the forum. icon_exclaim.gif

Basically you can use JOINKEYS, or a few more IFTHENs to solve the task. From you sample data it's not clear if '001' record has more content than just the indicator.

The following sample will work for up to 999 record sets.
Code:
OPTION COPY                                                       
INREC IFTHEN=(WHEN=GROUP,                                         
  BEGIN=(1,3,CH,EQ,C'001'),PUSH=(10:ID=3,15:1,5),RECORDS=1),     
  IFTHEN=(WHEN=GROUP,BEGIN=(10,3,CH,NE,C' '),PUSH=(10:10,10)),   
  IFTHEN=(WHEN=GROUP,                                             
   BEGIN=(1,3,CH,EQ,C'002'),END=(1,3,CH,EQ,C'001'),PUSH=(14:3,1))
OUTFIL FNAMES=(SORTOUT),                                         
  INCLUDE=(1,3,CH,NE,C'001',AND,14,1,CH,EQ,C'2'),                 
  REMOVECC,NULLOFL=RC4,                                           
  SECTIONS=(10,3,                                                 
    HEADER3=(15,5)),BUILD=(1,5)                                   
END

My sample input looks like this to better identify the records that were included during the test:
Code:
001 A
002 A
005 A
005 A
001 B
005 B
005 B
001 C
002 C
002 C
002 C
005 C
005 C
001 D
002 D
005 D
005 D
001 E
005 E
005 E

Output:
Code:
****** ***************************** Top of Data ******
000001 001 A                                           
000002 002 A                                           
000003 005 A                                           
000004 005 A                                           
000005 001 C                                           
000006 002 C                                           
000007 002 C                                           
000008 002 C                                           
000009 005 C                                           
000010 005 C                                           
000011 001 D                                           
000012 002 D                                           
000013 005 D                                           
000014 005 D                                           
****** **************************** Bottom of Data ****
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Sat Jul 12, 2025 8:24 am
Reply with quote

Hi Joerg.Findeisen,

Thank you very much for the quick response.

This is exactly the solution I was looking for.

Sorry I didn't mention in detail on the input file definition. The input file is going to be 312 bytes long and the key field is at position 10 and just 1 byte long. It is either '1' , '2' or '5'.

Each record set can have maximum 152 records.

'1' record has content for 312 bytes long, so is record '2' and '5'.

Now I will have to edit the sort card based on the 1 byte key field at position 10 and input file with length 312 bytes long.

If you could share the changes to be made based on the above then it would be of great help. I will also try from my end. Thank you!
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Mon Jul 14, 2025 10:26 pm
Reply with quote

Joerg.Findeisen -

I tried to edit the SORT card per my requirement as mentioned in the earlier message, and I could see the elimination happening as expected for all the record sets that doesn't have the '2' records.

However all the '1' records are also missing from the output file. Can you point out where I'm going wrong. Thanks!

Edited SORT card per my requirement -

OPTION COPY
INREC IFTHEN=(WHEN=GROUP,
BEGIN=(10,1,CH,EQ,C'1'),PUSH=(313:ID=3,318:1,312),RECORDS=1),
IFTHEN=(WHEN=GROUP,BEGIN=(313,3,CH,NE,C' '),PUSH=(318:318,318)),
IFTHEN=(WHEN=GROUP,
BEGIN=(10,1,CH,EQ,C'2'),END=(10,1,CH,EQ,C'1'),PUSH=(317:10,1))
OUTFIL FNAMES=(SORTOUT),
INCLUDE=(10,1,CH,NE,C'1',AND,317,1,CH,EQ,C'2'),
REMOVECC,NULLOFL=RC4,
SECTIONS=(313,3,
HEADER3=(318,312)),BUILD=(1,312)
END
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2286
Location: USA

PostPosted: Tue Jul 15, 2025 12:17 am
Reply with quote

Please, be polite to your potential readers! icon_exclaim.gif

It is more important the code to be understandable by a human, rather than runnable by a computer!

mohan_shine wrote:
Edited SORT card per my requirement -

Code:
  OPTION COPY
  INREC IFTHEN=(WHEN=GROUP,
                BEGIN=(10,1,CH,EQ,C'1'),
                PUSH=(313:ID=3,
                      318:1,312),
                RECORDS=1),
        IFTHEN=(WHEN=GROUP,
                BEGIN=(313,3,CH,NE,C' '),
                PUSH=(318:318,318)),
        IFTHEN=(WHEN=GROUP,
                BEGIN=(10,1,CH,EQ,C'2'),
                END=(10,1,CH,EQ,C'1'),
                PUSH=(317:10,1))

  OUTFIL FNAMES=(SORTOUT),
         INCLUDE=(10,1,CH,NE,C'1',
             AND,317,1,CH,EQ,C'2'),
         REMOVECC,NULLOFL=RC4,
         SECTIONS=(313,3,
                   HEADER3=(318,312)),
         BUILD=(1,312)
  END
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Tue Jul 15, 2025 1:18 am
Reply with quote

Thank you Sergeyken for formatting the code in a readable format.

I'm still figuring out the proper SORT card that will include the record '1's from skipping. Kindly let me know if you have any inputs. Thank you!
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Tue Jul 15, 2025 9:05 am
Reply with quote

I was able to format the SORT card per my requirement and it worked.

Big thanks to Joerg.Findeisen for providing the solution and that was very informative and helpful.

FINAL EDITED SORT CARD THAT WORKED-
----------------------
OPTION COPY
INREC IFTHEN=(WHEN=GROUP,
BEGIN=(10,1,CH,EQ,C'1'),
PUSH=(313:ID=3,
318:1,312),
RECORDS=1),
IFTHEN=(WHEN=GROUP,
BEGIN=(313,3,CH,NE,C' '),
PUSH=(313:313,318)),
IFTHEN=(WHEN=GROUP,
BEGIN=(10,1,CH,EQ,C'2'),
END=(10,1,CH,EQ,C'1'),
PUSH=(317:10,1))

OUTFIL FNAMES=(SORTOUT),
INCLUDE=(10,1,CH,NE,C'1',
AND,317,1,CH,EQ,C'2'),
REMOVECC,NULLOFL=RC4,
SECTIONS=(313,3,
HEADER3=(318,312)),
BUILD=(1,312)
END
Back to top
View user's profile Send private message
Joerg.Findeisen

Senior Member


Joined: 15 Aug 2015
Posts: 1442
Location: Bamberg, Germany

PostPosted: Tue Jul 15, 2025 4:36 pm
Reply with quote

Thanks for replying back with your final solution.

PS: You still need to learn how to use the formatting buttons in this forum. Also Preview is of great help. icon_wink.gif
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2286
Location: USA

PostPosted: Tue Jul 15, 2025 6:19 pm
Reply with quote

mohan_shine wrote:
I was able to format the SORT card per my requirement and it worked.

Big thanks to Joerg.Findeisen for providing the solution and that was very informative and helpful.

FINAL EDITED SORT CARD THAT WORKED-
----------------------
OPTION COPY
INREC IFTHEN=(WHEN=GROUP,
BEGIN=(10,1,CH,EQ,C'1'),
PUSH=(313:ID=3,
318:1,312),
RECORDS=1),
IFTHEN=(WHEN=GROUP,
BEGIN=(313,3,CH,NE,C' '),
PUSH=(313:313,318)),
IFTHEN=(WHEN=GROUP,
BEGIN=(10,1,CH,EQ,C'2'),
END=(10,1,CH,EQ,C'1'),
PUSH=(317:10,1))

OUTFIL FNAMES=(SORTOUT),
INCLUDE=(10,1,CH,NE,C'1',
AND,317,1,CH,EQ,C'2'),
REMOVECC,NULLOFL=RC4,
SECTIONS=(313,3,
HEADER3=(318,312)),
BUILD=(1,312)
END


It is very pity when someone persistently refuses to follow the simplest advices... 12.gif

The most of people have absolutely no desire to dive deep into the mish-mesh of an outsider's code.

More than 50-60% of hidden bugs are revealed immediately after the code had been properly formatted.
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Tue Jul 15, 2025 7:19 pm
Reply with quote

I’m new to the forum and I didn’t know how to format the code, somehow it kept aligning to the left even after aligning. I will have to learn that trick now. I will definitely get better with that next time. Thanks for the feedback…
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Tue Jul 15, 2025 9:43 pm
Reply with quote

This is the formatted edited code, I just learnt it. Thanks for the feedback and it helps to groom the new members.

Code:
  OPTION COPY
  INREC IFTHEN=(WHEN=GROUP,
                BEGIN=(10,1,CH,EQ,C'1'),
                PUSH=(313:ID=3,
                      318:1,312),
                RECORDS=1),
        IFTHEN=(WHEN=GROUP,
                BEGIN=(313,3,CH,NE,C' '),
                PUSH=(313:313,317)),
        IFTHEN=(WHEN=GROUP,
                BEGIN=(10,1,CH,EQ,C'2'),
                END=(10,1,CH,EQ,C'1'),
                PUSH=(317:10,1))

  OUTFIL FNAMES=(SORTOUT),
         INCLUDE=(10,1,CH,NE,C'1',
             AND,317,1,CH,EQ,C'2'),
         REMOVECC,NULLOFL=RC4,
         SECTIONS=(313,3,
                   HEADER3=(318,312)),
         BUILD=(1,312)
  END
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2286
Location: USA

PostPosted: Tue Jul 15, 2025 10:47 pm
Reply with quote

What if record 002 goes after 005, but before next 001?
Is the result what's needed?

Code:
001 A
002 A
005 A
005 A
001 B
005 B
005 B
002 ?
001 C
002 C
002 C
002 C
005 C
005 C
001 D
002 D
005 D
005 D
001 E
005 E
005 E
002 ?
002 ?
005 ?
005 ?
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2286
Location: USA

PostPosted: Tue Jul 15, 2025 11:06 pm
Reply with quote

Another approach might be: using ICETOOL, with two intermediate work files.

From my point of view the general logic is more clear, and it would allow simple modifications for much more complicated selections.

Code:
//GROUPNUM DD  SPACE=(TRK,(10,10))                                   
//GROUP002 DD  SPACE=(TRK,(10,10))                                   
//*                                                                   
//TOOLIN   DD  *                                                     
 COPY FROM(SORTIN)    TO(GROUPNUM,GROUP002)   USING(SPLT)             
 COPY JKFROM          TO(SORTOUT)             USING(JOIN)             
//*                                                                   
//SPLTCNTL DD  *                                                     
 INREC IFTHEN=(WHEN=GROUP,                                           
               BEGIN=(10,1,CH,EQ,C'1'),                               
               PUSH=(313:ID=3))   NUMBER EACH GROUP SEQUENTIALLY       
 OUTFIL FNAMES=(GROUPNUM)        ALL NUMBERED INPUT RECORDS           
 OUTFIL FNAMES=(GROUP002),       ONLY GROUP NUMBERS WITH 002 RECORDS 
        REMOVECC,NODETAIL,                                           
        INCLUDE=(10,1,CH,EQ,C'2'),                                   
        SECTIONS=(313,3,                                               
                  TRAILER3=(313,3))   UNIQUE GROUP 002 NUMBER         
//*                                                                   
//JOINCNTL DD  *                                                     
 JOINKEYS F1=GROUPNUM,                                               
          FIELDS=(313,3,A),SORTED                                     
 JOINKEYS F2=GROUP002,                                               
          FIELDS=(1,3,A),SORTED                                       
 REFORMAT FIELDS=(F1:1,312)                                           
//*                                                                   
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Wed Jul 16, 2025 12:05 am
Reply with quote

Thank you sergeyken for providing alternate solution that could be handled flexibly.

I was able to execute your code and it produced the expected results.

For your question - "What if record 002 goes after 005, but before next 001?" -
This scenario will never occur in my case since we have the record set with the regular pattern where,

1) Header '001' record comes first,
2) Followed by '002' records (maximum 150)
3) Finally there will be 2 trailer '005' records.
Problem was only with the intermediate '002' records that goes missing from few record sets in the input file and your solution works perfectly for my problem.

Thanks again for helping me arrive with multiple flexible options. Great learning from experts!
Back to top
View user's profile Send private message
Joerg.Findeisen

Senior Member


Joined: 15 Aug 2015
Posts: 1442
Location: Bamberg, Germany

PostPosted: Wed Jul 16, 2025 3:13 am
Reply with quote

Given DD:F1 and DD:F2 point to the same input, this should be similar to the provided ICETOOL variant.

Code:
//SYSIN    DD *                                                     
  OPTION COPY                                                       
  JOINKEYS F1=F1,FIELDS=(313,3,A),SORTED                             
  JOINKEYS F2=F2,FIELDS=(313,3,A)                                   
  REFORMAT FIELDS=(F1:1,312)                                         
  END                                                               
/*                                                                   
//JNF1CNTL DD *
  INREC IFTHEN=(WHEN=GROUP,BEGIN=(10,1,CH,EQ,C'1'),PUSH=(313:ID=3)) 
  END                                                               
/*                                                                   
//JNF2CNTL DD *     
  INREC IFTHEN=(WHEN=GROUP,BEGIN=(10,1,CH,EQ,C'1'),PUSH=(313:ID=3)),
    IFTHEN=(WHEN=(10,1,CH,NE,C'2'),OVERLAY=(313:3X))                 
  SUM FIELDS=(NONE)                                                 
  END                                                               
/*
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2286
Location: USA

PostPosted: Wed Jul 16, 2025 6:01 pm
Reply with quote

...del...
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Wed Jul 16, 2025 7:43 pm
Reply with quote

Thanks Joerg.Findeisen for the solution with join keys. This solution worked perfectly for my scenario. Appreciate all your help in guiding me through different approaches and methods to arrive at the solution icon_smile.gif
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Thu Jul 17, 2025 7:35 pm
Reply with quote

A small modification to the requirement.
I have the same file that is 312 bytes long and it has
1) Header '1' at position 10.
2) Followed by a definite detail record '2' at position 10 (1-150 occurrence).
Detail record also has an indicator at position 311.
This indicator is either 'P' or 'E'. It can also have 'P' and 'E' in the same
record set.
3) 2 trailer '3' records at position 10.

The order of the record set is always '1' followed by '2' and then '3'. There is no missing '2' records in this scenario.

If I want to split this input file into 2 sets where I want all the 'P' records written into one file (along with their '1' and '3' records) and all the 'E' records written into another file (along with their '1' and '3' records), which of the options would be a better choice. Please find the input and expected output. Kindly suggest.

Code:
Input
POLICYAAA1............
POLICYAAA2..........E.
POLICYAAA3............
POLICYAAA3............
POLICYBBB1............
POLICYBBB2..........P.
POLICYBBB3............
POLICYBBB3............
POLICYCCC1............
POLICYCCC2..........P.
POLICYCCC2..........E.
POLICYCCC2..........P.
POLICYCCC2..........E.
POLICYCCC3............
POLICYCCC3............

Output
POLICYAAA1............
POLICYAAA2..........E.
POLICYAAA3............
POLICYAAA3............
POLICYBBB1............
POLICYBBB2..........P.
POLICYBBB3............
POLICYBBB3............
POLICYCCC1............
POLICYCCC2..........P.
POLICYCCC2..........P.
POLICYCCC3............
POLICYCCC3............
POLICYCCC1............
POLICYCCC2..........E.
POLICYCCC2..........E.
POLICYCCC3............
POLICYCCC3............
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2286
Location: USA

PostPosted: Thu Jul 17, 2025 7:44 pm
Reply with quote

Please, try to make this modification by yourself. Let's see your own result, first of all.
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Thu Jul 17, 2025 10:27 pm
Reply with quote

I'm unable to find a direct approach but worked with 3 SORT steps.

Code:
Input
POLICYAAA1............
POLICYAAA2..........E.
POLICYAAA3............
POLICYAAA3............
POLICYBBB1............
POLICYBBB2..........P.
POLICYBBB3............
POLICYBBB3............
POLICYCCC1............
POLICYCCC2..........P.
POLICYCCC2..........E.
POLICYCCC2..........P.
POLICYCCC2..........E.
POLICYCCC3............
POLICYCCC3............


1) First sort card to,
Extract the header (1), trailer (3) and records with 'P' into one file.
Code:
Output1
POLICYAAA1............
POLICYAAA3............
POLICYAAA3............
POLICYBBB1............
POLICYBBB2..........P.
POLICYBBB3............
POLICYBBB3............
POLICYCCC1............
POLICYCCC2..........P.
POLICYCCC2..........P.
POLICYCCC3............
POLICYCCC3............


Extract the header (1), trailer (3) and records with 'E' into another file.

Code:
Output2
POLICYAAA1............
POLICYAAA2..........E.
POLICYAAA3............
POLICYAAA3............
POLICYBBB1............
POLICYBBB3............
POLICYBBB3............
POLICYCCC1............
POLICYCCC2..........E.
POLICYCCC2..........E.
POLICYCCC3............
POLICYCCC3............


2) Using the above Output 1 and Output 2 files created, I used the solution provided in this forum to eliminate the record sets if there are no '2' records in the input.

This worked and gave me 2 output files, but the work involved 3 sort steps in total.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2286
Location: USA

PostPosted: Thu Jul 17, 2025 11:21 pm
Reply with quote

As I mentioned, the ICETOOL method with two intermediate files can be modified for a more complex selection...

Code:
//SORTOUTP DD  SYSOUT=*            ONLY 'P' GROUPS                     
//SORTOUTE DD  SYSOUT=*            ONLY 'E' GROUPS                     
//ERROUT   DD  SYSOUT=*            NOT ALLOWED GROUPS                 
//*                                                                   
//GROUPNUM DD  SPACE=(TRK,(200,200))                                     
//GROUP002 DD  SPACE=(TRK,(10,10))                                     
//*                                                                   
//TOOLIN   DD  *                                                       
 SORT FROM(SORTIN)    TO(GROUPNUM,GROUP002)   USING(SPLT)             
 SORT JKFROM          TO(SORTOUTP,SORTOUTE)   USING(JOIN)             
//*                                                                   
//SPLTCNTL DD  *                                                       
 INREC IFTHEN=(WHEN=INIT,                                             
               OVERLAY=(316:SEQNUM,8,ZD)),   KEEP INITIAL RECORD SEQ   
       IFTHEN=(WHEN=GROUP,                                             
               BEGIN=(10,1,CH,EQ,C'1'),                               
               PUSH=(313:ID=3))   NUMBER EACH GROUP SEQUENTIALLY       
                                                                       
 SORT FIELDS=(313,3,CH,A,         BY GROUPS                           
               10,1,CH,A,         BY RECORDS                           
               21,1,CH,A),        BY TYPE 'P'/'E'                     
      EQUALS                                                           
                                                                       
 OUTFIL FNAMES=(GROUPNUM)        ALL NUMBERED INPUT RECORDS           
                                                                       
 OUTFIL FNAMES=(GROUP002),       ONLY GROUP NUMBERS WITH 002 RECORDS 
        REMOVECC,NODETAIL,                                           
        INCLUDE=(10,1,CH,EQ,C'2'),                                   
        SECTIONS=(313,3,21,1,                                         
                  TRAILER3=(313,3,   UNIQUE GROUP 002 NUMBER         
                            21,1))   PLUS GROUP TYPE                 
//*                                                                   
//JOINCNTL DD  *                                                     
 JOINKEYS F1=GROUPNUM,                                               
          FIELDS=(313,3,A),SORTED     GROUP ID 1                     
                                                                     
 JOINKEYS F2=GROUP002,                                               
          FIELDS=(1,3,A),SORTED       GROUP ID 2                     
                                                                     
 REFORMAT FIELDS=(F1:1,312,           ORIGINAL RECORD                 
                     313,3,           GROUP ID 1                     
                     316,8,           ORIGINAL RECORD NUM             
                  F2:1,3,             GROUP ID 2                     
                     4,1)             CONTAINING 'E'/'P'/'?'         
                                                                     
 SORT FIELDS=(316,8,CH,A),EQUALS      RESTORE ORIGINAL RECORDS ORDER 
                                                                     
 OUTFIL FNAMES=(SORTOUTE),                                           
        INCLUDE=(327,1,CH,EQ,C'E',                                   
              AND,(10,1,CH,NE,C'2',                                   
                OR,21,1,CH,EQ,C'E')),                                 
        BUILD=(1,312)                                                 
                                                                       
 OUTFIL FNAMES=(SORTOUTP),                                             
        INCLUDE=(327,1,CH,EQ,C'P',                                     
              AND,(10,1,CH,NE,C'2',                                   
                OR,21,1,CH,EQ,C'P')),                                 
        BUILD=(1,312)                                                 
                                                                       
 OUTFIL FNAMES=(ERROUT),                                               
        INCLUDE=(327,1,SS,NE,C'PE'),                                   
        NOTMTOFL=RC4,           RETURN RC=4 WHEN UNKNOWN GROUP DETECTED
        BUILD=(1,312)                                                 
//*                                                                   
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Thu Jul 17, 2025 11:55 pm
Reply with quote

Thank you sergeyken for suggesting the solution. I will make use of this approach so I could avoid writing multiple SORT steps.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2286
Location: USA

PostPosted: Fri Jul 18, 2025 1:35 am
Reply with quote

mohan_shine wrote:
Thank you sergeyken for suggesting the solution. I will make use of this approach so I could avoid writing multiple SORT steps.

I had no time to test it carefully. Some cases might be missing yet.

Please, do it - IT IS YOUR JOB... icon_pai.gif
Back to top
View user's profile Send private message
mohan_shine

New User


Joined: 11 Jul 2025
Posts: 14
Location: canada

PostPosted: Fri Jul 18, 2025 3:30 am
Reply with quote

Sure I will test it. Thank you!
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2286
Location: USA

PostPosted: Fri Jul 18, 2025 6:37 pm
Reply with quote

Many years I struggle advising all developers to make their code as clear as possible FOR A HUMAN, not only for a dumb machine.
Sadly, 99.99% of all readers always ignore any suggestion...
Code:
//*.....................................................................
//SORTOUTP DD  SYSOUT=*            ONLY 'P' GROUPS                   
//SORTOUTE DD  SYSOUT=*            ONLY 'E' GROUPS                   
//ERROUT   DD  SYSOUT=*            NOT ALLOWED GROUPS               
//*.....................................................................
//MASTER   DD  SPACE=(TRK,(200,200))                                 
//DETAILS  DD  SPACE=(TRK,(10,10))                                   
//*.....................................................................
//SYMNAMES DD  *         USED RECORDS LAYOUT, FOR CLARITY           
* MASTERFILE LAYOUT                                                 
REC_ID,10,1,CH                '1'/'2'/'3'                           
TYPE,21,1,CH                  'P'/'E'/'?'                           
FULL_RECORD,1,312,CH          ORIGINAL RECORD                       
* JOIN CONTROL FIELDS - CONTINUED                                   
GROUP_ID,*,3,ZD               III                                   
REC_NUM,*,8,ZD                NNNNNNNN                               
* JOINED FILE RECORD - CONTINUED                                     
JOIN_ID,*,3,ZD                III                                   
JOIN_TYPE,*,1,CH              'P'/'E'/'?'                           
*                                                                   
* SEPARATE DETAIL FILE LAYOUT (TRUNCATED FOR EFFICIENCY, OPTIONAL)   
F2_ID,1,3,ZD                  III                                   
F2_TYPE,*,1,CH                'P'/'E'/'?'                           
//*.....................................................................
//TOOLIN   DD  *                                                     
 SORT FROM(SORTIN)    TO(MASTER,DETAILS)      USING(SPLT)               
 SORT JKFROM          TO(SORTOUTP,SORTOUTE)   USING(JOIN)               
//*.....................................................................
//SPLTCNTL DD  *                                                         
* EXTEND MASTER FILE RECORDS TO SUPPORT FURTHER SELECTIVE JOIN           
 INREC IFTHEN=(WHEN=INIT,                                               
               OVERLAY=(REC_NUM:SEQNUM,8,ZD)),   KEEP INITIAL RECORD SEQ
       IFTHEN=(WHEN=GROUP,                                               
               BEGIN=(REC_ID,EQ,C'1'),                                   
               PUSH=(GROUP_ID:ID=3))   NUMBER EACH GROUP SEQUENTIALLY   
                                                                         
* TEMPORARY REORDER RECORDS TO SELECT ONLY UNIQUE COMBINATIONS 'P'/'E'   
 SORT FIELDS=(GROUP_ID,A,         BY GROUPS                             
              REC_ID,A,           BY RECORD TYPE                         
              TYPE,A),            BY SUB_TYPE 'P'/'E'                   
      EQUALS                                                             
                                                                         
* SAVE MASTER FILE TO PERFORM SELECTIVE JOIN                             
 OUTFIL FNAMES=(MASTER)          ALL NUMBERED INPUT RECORDS             
                                                                         
* SAVE DETAILS FILE TO PERFORM SELECTIVE JOIN                           
* EXTRA FIELDS TRUNCATED FOR EFFICIENCY (OPTIONAL)                       
 OUTFIL FNAMES=(DETAILS),        ONLY GROUP NUMBERS WITH 002 RECORDS     
        REMOVECC,NODETAIL,       KEEP ONLY UNIQUE TOTALS                 
        INCLUDE=(REC_ID,EQ,C'2'),   ONLY RECORDS '2' CONSIDERED         
        SECTIONS=(GROUP_ID,TYPE,        UNIQUE GROUPID+TYPE PAIRS     
                  TRAILER3=(F2_ID:GROUP_ID,   GROUP '2' ID             
                            F2_TYPE:TYPE))    PLUS GROUP TYPE         
//*.....................................................................
//JOINCNTL DD  *                                                       
 JOINKEYS F1=MASTER,                                                   
          FIELDS=(GROUP_ID,A),SORTED     GROUP ID MASTER               
                                                                       
 JOINKEYS F2=DETAILS,                                                 
          FIELDS=(F2_ID,A),SORTED        GROUP ID DETAIL               
                                                                       
* JOINED RECORD, ALL FIELDS LISTED FOR CLARITY                         
 REFORMAT FIELDS=(F1:FULL_RECORD,     ORIGINAL RECORD                 
                     GROUP_ID,        GROUP ID MASTER                 
                     REC_NUM,         ORIGINAL RECORD NUM             
                  F2:F2_ID,           JOIN_ID                         
                     F2_TYPE)         JOIN_TYPE 'E'/'P'/'?'           
                                                                       
 OMIT COND=(REC_ID,EQ,C'2',          SKIP UNNEEDED MATCHING RECORDS:   
        AND,TYPE,NE,JOIN_TYPE)       'E' IN GROUP OF 'P' OR VICE VERSA
                                                                       
 SORT FIELDS=(REC_NUM,A),EQUALS      RESTORE ORIGINAL RECORDS ORDER   
                                                                       
 OUTFIL FNAMES=(SORTOUTE),           ALL GROUPS WITH AT LEAST ONE 'E' 
        INCLUDE=(JOIN_TYPE,EQ,C'E'),                                   
        BUILD=(FULL_RECORD)          TRUNCATE TO INITIAL SIZE           
                                                                       
 OUTFIL FNAMES=(SORTOUTP),           ALL GROUPS WITH AT LEAST ONE 'E'   
        INCLUDE=(JOIN_TYPE,EQ,C'P'),                                   
        BUILD=(FULL_RECORD)          TRUNCATE TO INITIAL SIZE           
                                                                       
 OUTFIL FNAMES=(ERROUT),             ANY GROUP WITH NEITHER 'P' NOR 'E'
        INCLUDE=(JOIN_TYPE,SS,NE,C'PE'),                               
        NOTMTOFL=RC4,           RETURN RC=4 WHEN UNKNOWN GROUP DETECTED
        BUILD=(FULL_RECORD)          TRUNCATE TO INITIAL SIZE           
//*.....................................................................
Back to top
View user's profile Send private message
View previous topic : : View next topic  
Post new topic   Reply to topic All times are GMT + 6 Hours
Forum Index -> DFSORT/ICETOOL Goto page 1, 2  Next

 


Similar Topics
Topic Forum Replies
No new posts Sort SMF records? SYNCSORT 6
No new posts To Sort detail records in a file with... SYNCSORT 5
No new posts Identify and write records containing... SYNCSORT 11
No new posts Filter records where condition is in ... SYNCSORT 6
No new posts Write record twice based on condition... SYNCSORT 7
Search our Forums:


Back to Top