Portal | Manuals | References | Downloads | Info | Programs | JCLs | Master the Mainframes
IBM Mainframe Computers Forums Index
 
Register
 
IBM Mainframe Computers Forums Index Mainframe: Search IBM Mainframe Forum: FAQ Memberlist Usergroups Profile Log in to check your private messages Log in
 

 

Edit last record
Goto page 1, 2  Next
 
Post new topic   Reply to topic    IBMMAINFRAMES.com Support Forums -> DFSORT/ICETOOL
View previous topic :: :: View next topic  
Author Message
Captain Paralytic
Warnings : 1

New User


Joined: 21 Apr 2010
Posts: 40
Location: UK

PostPosted: Fri Aug 27, 2010 5:01 pm    Post subject: Edit last record
Reply with quote

I am trying to create control input records for a TWS/OPC utility.

From input records like:
Code:
UHY#S            P 711231
UHYA1            A 711231
UHYA1AVL         P 711231
UHYA2            A 711231
UHYA5            A 711231

I am using:
Code:
OPTION COPY                                                 
INCLUDE COND=(18,1,CH,EQ,C'A')                               
INREC BUILD=(C'ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=', 
             20,6,C',ADID=',1,17,C';',80X)                   
 OUTREC BUILD=(1,80,SQZ=(SHIFT=LEFT))

To produce:
Code:
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA1;
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA1AVL;
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA2;
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA5;

So far so good, but the last record needs to end with a full stop rather than a semi-colon, thus:
Code:
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA1;
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA1AVL;
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA2;
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA5.


Any ideas?
Back to top
View user's profile Send private message

PeterHolland

Global Moderator


Joined: 27 Oct 2009
Posts: 2422
Location: Netherlands, Amstelveen

PostPosted: Fri Aug 27, 2010 5:32 pm    Post subject:
Reply with quote

Why use something like DFSORT if a small REXX could do the job.
Back to top
View user's profile Send private message
expat

Global Moderator


Joined: 14 Mar 2007
Posts: 8593
Location: Back in jolly old England

PostPosted: Fri Aug 27, 2010 5:54 pm    Post subject:
Reply with quote

Click HERE to see a similar topic.

Not exactly the same, but maybe enough to help you through.
Don't know why, but this topic just stuck in my head icon_eek.gif
Back to top
View user's profile Send private message
Captain Paralytic
Warnings : 1

New User


Joined: 21 Apr 2010
Posts: 40
Location: UK

PostPosted: Fri Aug 27, 2010 6:32 pm    Post subject:
Reply with quote

PeterHolland wrote:
Why use something like DFSORT if a small REXX could do the job.

Because:

  1. A REXX will need to be kept in a separate library or have an extra step to write it to a temporary PDS
  2. DFSORT is understood by many more people in my organisation than REXX
  3. I like to grow my DFSORT skills
Back to top
View user's profile Send private message
PeterHolland

Global Moderator


Joined: 27 Oct 2009
Posts: 2422
Location: Netherlands, Amstelveen

PostPosted: Fri Aug 27, 2010 6:40 pm    Post subject:
Reply with quote

Quote:

A REXX will need to be kept in a separate library or have an extra step to write it to a temporary PDS


Huh? And how about the sort control records, they are not kept in a
library, or are they used in-stream.
A batch REXX (REXX being one of your skills) can pre-allocate the input/output.
Then you only need to do some EXECIO for those datasets, and some
formatting of the input. And all that in 1 step, very readable for everyone.
And the REXX statements can be in-stream also.
Back to top
View user's profile Send private message
Captain Paralytic
Warnings : 1

New User


Joined: 21 Apr 2010
Posts: 40
Location: UK

PostPosted: Fri Aug 27, 2010 7:02 pm    Post subject:
Reply with quote

Quote:
Huh? And how about the sort control records, they are not kept in a
library, or are they used in-stream.
In-stream

Quote:
A batch REXX (REXX being one of your skills) can pre-allocate the input/output.
Then you only need to do some EXECIO for those datasets, and some
formatting of the input.
The input isn't actually coming from a dataset per-se, it is coming from a query to TWS/OPC

Quote:
And all that in 1 step, very readable for everyone.
And the REXX statements can be in-stream also.
As I said, to use "in-stream" REXX, you need a separate step to write them to a temporary PDS.
Also, "very readable" is one thing. Since the others don't understand it, if I want others to support it, I stick to things that they will support.
Back to top
View user's profile Send private message
sqlcode1

Active Member


Joined: 08 Apr 2010
Posts: 578
Location: USA

PostPosted: Fri Aug 27, 2010 7:42 pm    Post subject:
Reply with quote

Captain Paralytic,
Your given sort card and expected output doesn't match. It doesn't even match the output you believe you are getting now.
For the same input if I run the sortcard you have provided,I am getting below output with 3 records only but you mentioned you are getting all 5 input records.

Code:
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA1;
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA2;
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA5;


Did you look at the link Kevin provided earlier. Below is the sort card to get what you want. I am assuming you only want to include, records with A in 18th position. If you do want all records in output, then remove INCLUDE COND line from the second step.

Code:

//STEP01   EXEC PGM=SORT                                               
//SYSOUT   DD SYSOUT=*                                                 
//SORTIN   DD YOUR INPUT FILE                                           
//T1 DD DSN=&&T1,UNIT=SYSDA,SPACE=(CYL,(5,5)),DISP=(,PASS)             
//S1 DD DSN=&&S1,UNIT=SYSDA,SPACE=(TRK,(1,1)),DISP=(,PASS)             
//SYSIN    DD *                                                         
 OPTION COPY                                                           
 INREC OVERLAY=(81:SEQNUM,8,ZD)                                         
 OUTFIL FNAMES=T1                                                       
 OUTFIL FNAMES=S1,REMOVECC,NODETAIL,OUTREC=(80X),                       
                              TRAILER1=('LASTRCD,+',81,8)         
/*                                                                     
//*                                                                     
//STEP02   EXEC PGM=SORT                                               
//SYSOUT   DD SYSOUT=*                                                 
//SYMNAMES DD DSN=&&S1,DISP=SHR                                         
//SORTIN   DD DSN=&&T1,DISP=SHR                                         
//SORTOUT  DD SYSOUT=*                                                 
//SYSIN    DD *                                                         
 OPTION COPY                                                           
 INCLUDE COND=(18,1,CH,EQ,C'A')                                         
 INREC IFTHEN=(WHEN=(81,8,ZD,EQ,LASTRCD),                               
               BUILD=(C'ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=',   
                      20,6,C',ADID=',1,17,C'.',80X)),                   
       IFTHEN=(WHEN=NONE,                                               
               BUILD=(C'ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=',   
                      20,6,C',ADID=',1,17,C';',80X))                   
 OUTREC BUILD=(1,80,SQZ=(SHIFT=LEFT))                                   
//*                                                                     


OUTPUT
Code:
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA1; 
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA2; 
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA5. 


Thanks,
Back to top
View user's profile Send private message
Captain Paralytic
Warnings : 1

New User


Joined: 21 Apr 2010
Posts: 40
Location: UK

PostPosted: Fri Aug 27, 2010 7:57 pm    Post subject:
Reply with quote

Quote:
Captain Paralytic,
Your given sort card and expected output doesn't match. It doesn't even match the output you believe you are getting now.

Hi sqlcode1, note that my post started with
"From input records like:"
I just grabbed a few of the input records and a few of the output ones.

Yes I did look at the post. I also came up with another couple of possibilities myself, using ICETOOL's SUBSET and the DISCARD operand, or two SUBSETs and combining their output.
Back to top
View user's profile Send private message
sqlcode1

Active Member


Joined: 08 Apr 2010
Posts: 578
Location: USA

PostPosted: Fri Aug 27, 2010 8:15 pm    Post subject:
Reply with quote

Captain Paralytic,
Quote:
I just grabbed a few of the input records and a few of the output ones.
I understand that you randomly selected few records to show output and this might work for you because you knew the actual/final requirements. For someone who is trying to answer your question, requirements might not be known, so having correct expected output actually does help.

Quote:
Yes I did look at the post. I also came up with another couple of possibilities myself, using ICETOOL's SUBSET and the DISCARD operand, or two SUBSETs and combining their output.
Glad that you came up with another solution. If I am guessing it right, in your solution you are using couple of SUBSET statements, first one to select all the records but last but to add semicolon ';' and then later in the socond SUBSET you select only last record to add period '.'. Something like below.

If this is the case, then I am afraid your solution may not be efficient. Wait until Frank or Kolusu gives you better explanation on why!!! I have learnt this hard way.

Code:

//TOOLIN   DD *                                                         
SUBSET FROM(IN) TO(OUT) USING(CTL1) TRAILER REMOVE INPUT             
SUBSET FROM(IN) TO(OUT) USING(CTL2) TRAILER KEEP INPUT               
/*                                                                     
//CTL1CNTL DD *                                                         
 OPTION COPY                                                           
 INCLUDE COND=(18,1,CH,EQ,C'A')                                         
 INREC BUILD=(C'ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=',           
              20,6,C',ADID=',1,17,C';',80X)                             
  OUTREC BUILD=(1,80,SQZ=(SHIFT=LEFT))                                 
/*                                                                     
//CTL2CNTL DD *                                                         
 OPTION COPY                                                           
 INCLUDE COND=(18,1,CH,EQ,C'A')                                         
 INREC BUILD=(C'ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=',           
              20,6,C',ADID=',1,17,C'.',80X)                             
  OUTREC BUILD=(1,80,SQZ=(SHIFT=LEFT))                                 
/*                                                                     
//*                                                                     


Thanks,
Back to top
View user's profile Send private message
Captain Paralytic
Warnings : 1

New User


Joined: 21 Apr 2010
Posts: 40
Location: UK

PostPosted: Fri Aug 27, 2010 8:19 pm    Post subject:
Reply with quote

Folks may be interested in the solution that I came up with, simplified here as a demonstration:
Code:
//JK1 EXEC PGM=ICETOOL                                   
//SYSOUT DD SYSOUT=*                                     
//TOOLMSG DD SYSOUT=*                                   
//DFSMSG DD SYSOUT=*                                     
//IN1 DD *                                               
000 $$$$$                                               
001 AAAAA                                               
002 CCCCC                                               
003 EEEEE                                               
004 GGGGG                                               
//OUT1 DD SYSOUT=*                                       
//TOOLIN DD *                                           
  SUBSET FROM(IN1) TO(OUT1) INPUT REMOVE LAST USING(CTL1)
  SUBSET FROM(IN1) TO(OUT1) INPUT KEEP LAST USING(CTL2) 
/*                                                       
//CTL1CNTL DD *                                         
  OUTFIL FNAMES=OUT1,BUILD=(1,9,C';')                   
//CTL2CNTL DD *                                         
  OUTFIL FNAMES=OUT1,BUILD=(1,9,C'.')                   

The output from this is:
Code:
000 $$$$$;
001 AAAAA;
002 CCCCC;
003 EEEEE;
004 GGGGG.
Back to top
View user's profile Send private message
Captain Paralytic
Warnings : 1

New User


Joined: 21 Apr 2010
Posts: 40
Location: UK

PostPosted: Fri Aug 27, 2010 8:26 pm    Post subject:
Reply with quote

I had originally tried OUTREC as in your post, but got the error:
OUTREC STATEMENT FOUND BUT NOT ALLOWED - USE OUTFIL STATEMENT INSTEAD
So changed to OUTFIL, finally using a COPY to perform the SQZ
Back to top
View user's profile Send private message
sqlcode1

Active Member


Joined: 08 Apr 2010
Posts: 578
Location: USA

PostPosted: Fri Aug 27, 2010 8:42 pm    Post subject:
Reply with quote

Captain Paralytic
Quote:
OUTREC STATEMENT FOUND BUT NOT ALLOWED - USE OUTFIL STATEMENT INSTEAD
Unless you changed anything from the original card, it should work.

Quote:
So changed to OUTFIL, finally using a COPY to perform the SQZ
Again glad that it worked using an alternate way.

Thanks,
Back to top
View user's profile Send private message
Captain Paralytic
Warnings : 1

New User


Joined: 21 Apr 2010
Posts: 40
Location: UK

PostPosted: Fri Aug 27, 2010 8:48 pm    Post subject: Reply to: Edit last record
Reply with quote

I've never understood why one needs an OUTFIL FNAMES=xxx statement for a USING CNTL for a SELECT (or SUBSET), when the DDNAME is already coded in the TO() parameter. If anyone can tell me I'd be interested.

However, for completeness, here is the actual solution I managed to make work:
Code:
//JK1     EXEC PGM=ICETOOL                                 
//SYSOUT  DD SYSOUT=*                                       
//TOOLMSG DD SYSOUT=*                                       
//DFSMSG  DD SYSOUT=*                                       
//IN2     DD UNIT=SYSDA,SPACE=(TRK,(1,1)),DISP=(MOD,PASS)   
//IN1     DD *                                             
UHY#S            P 711231                                   
UHYA1            A 711231                                   
UHYA1AVL         P 711231                                   
UHYA2            A 711231                                   
UHYA5            A 711231                                   
//OUT DD SYSOUT=*                                           
//TOOLIN   DD *                                             
COPY FROM(IN1) TO(IN2) USING(CTLI)                         
SUBSET FROM(IN2) TO(OUT) USING(CTL1) TRAILER REMOVE INPUT   
SUBSET FROM(IN2) TO(OUT) USING(CTL2) TRAILER KEEP INPUT     
/*                                                         
//CTLICNTL DD *                                             
 INCLUDE COND=(18,1,CH,EQ,C'A')                             
//CTL1CNTL DD *                                             
 OPTION COPY                                               
 INREC BUILD=(C'ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=',
              20,6,C',ADID=',1,17,C';',80X)                 
 OUTFIL FNAMES=OUT,BUILD=(1,80,SQZ=(SHIFT=LEFT))           
/*                                                         
//CTL2CNTL DD *                                             
 OPTION COPY                                               
 INREC BUILD=(C'ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=',
              20,6,C',ADID=',1,17,C'.',80X)                 
 OUTFIL FNAMES=OUT,BUILD=(1,80,SQZ=(SHIFT=LEFT))           
/*                                                         
//*                                                         
Back to top
View user's profile Send private message
Captain Paralytic
Warnings : 1

New User


Joined: 21 Apr 2010
Posts: 40
Location: UK

PostPosted: Fri Aug 27, 2010 9:02 pm    Post subject:
Reply with quote

sqlcode1 wrote:
Captain Paralytic
Quote:
OUTREC STATEMENT FOUND BUT NOT ALLOWED - USE OUTFIL STATEMENT INSTEAD
Unless you changed anything from the original card, it should work.

Quote:
So changed to OUTFIL, finally using a COPY to perform the SQZ
Again glad that it worked using an alternate way.

Thanks,

I also got:
ICE653A 0 SKIPREC, STOPAFT OR COND (SUBSET) OR STOPAFT (DATASORT) NOT ALLOWED
which was why I had to remove the COND statement.

The whole block of your code was copied and pasted as you wrote it.
Back to top
View user's profile Send private message
sqlcode1

Active Member


Joined: 08 Apr 2010
Posts: 578
Location: USA

PostPosted: Fri Aug 27, 2010 9:26 pm    Post subject:
Reply with quote

Captain Paralytic,
You had all these errors because you are using solution with SUBSET(s) which I already mentioned may not be efficient. I was referring to the original solution.

Like I mentioned, I have learnt this hard way and I would not use multiple SUBSET. It is unnecessary read for the input records.

Wait until Frank or Kolusu could explain you better on why you DON'T want to use multiple SUBSET(s).

Quote:
The whole block of your code was copied and pasted as you wrote it.
Since earlier you didn't mention your card with multiple subsets, that was what I said I assumed your code might look like. I took your original sortcard and put it in CNTL1 and CNTL2.

Regarding you errors, refer to this link for SUBSET
From DFSort Application Programming,

Quote:
The DFSORT control statements in xxxxCNTL are used if USING(xxxx) is specified. However, you must observe these rules for control statements in the xxxxCNTL data set:


MODS and OUTREC statements should not be present.

SKIPREC and STOPAFT operands, and INCLUDE and OMIT statements, should not be present.



Thanks,
Back to top
View user's profile Send private message
Frank Yaeger

DFSORT Moderator


Joined: 15 Feb 2005
Posts: 7130
Location: San Jose, CA

PostPosted: Fri Aug 27, 2010 10:49 pm    Post subject:
Reply with quote

Quote:
I've never understood why one needs an OUTFIL FNAMES=xxx statement for a USING CNTL for a SELECT (or SUBSET), when the DDNAME is already coded in the TO() parameter. If anyone can tell me I'd be interested.


You don't. That was "changed" quite a while ago.

For example, if you use:

Code:

SELECT FROM(IN) TO(OUT) ON(1,5,CH) FIRST USING(CTL1)   
//CTL1CNTL DD *                                       
  OUTFIL OVERLAY=(21:C'**')                           


OUTFIL will use FNAMES=OUT by default.

I ran your job without FNAMES=OUT and it worked fine. If it didn't work for you, then your DFSORT level is quite old.
Back to top
View user's profile Send private message
Frank Yaeger

DFSORT Moderator


Joined: 15 Feb 2005
Posts: 7130
Location: San Jose, CA

PostPosted: Fri Aug 27, 2010 10:58 pm    Post subject:
Reply with quote

Guys - this is the second thread today that has gone "way over the top". I removed all of the "garbage" and will continue to do so if people continue to post more. Let's keep it civil and helpful, please. I have better things to do with my time than edit these threads.
Back to top
View user's profile Send private message
Captain Paralytic
Warnings : 1

New User


Joined: 21 Apr 2010
Posts: 40
Location: UK

PostPosted: Tue Aug 31, 2010 2:37 pm    Post subject: Reply to: Edit last record
Reply with quote

Thanks for removing all that stuff Frank, I was going to ask you if you would.

Sqlcode1 suggested that you or someone known as Kolusu might explain why this is not a good method to use and possible suggest a better one?

Sqlcode1 suggests that this is very inefficient and PeterHolland was pushing REXX.

If I had my way, I would use CMS/TSO Pipelines, since this would be totally trivial and very efficient (doing everything in a single pass) thus:

Code:
'pipe (end \)',                                             
  '|< ddname=input',                                               
  '|pick 18.1 == /A/',                                       
  '|spec /ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=/ n',   
        '20.6 n /,ADID=/ n 1.17 strip n /;/ n',             
  '|d:drop last 1',                                         
  '|f:faninany',                                             
  '|> ddname=output',                                                   
  '\d:',                                                     
  '|change -1;-1 /;/./',                                     
  '|f:'     


But if I have a hard time convincing my colleagues of the efficacy of REXX, it is nothing to what I would face trying to get them to adopt pipelines!
Back to top
View user's profile Send private message
Frank Yaeger

DFSORT Moderator


Joined: 15 Feb 2005
Posts: 7130
Location: San Jose, CA

PostPosted: Tue Aug 31, 2010 10:36 pm    Post subject:
Reply with quote

Quote:
Wait until Frank or Kolusu could explain you better on why you DON'T want to use multiple SUBSET(s).


I wish people wouldn't put words in my mouth. Multiple SUBSET operators can be "appropriate" in some cases. If you're happy with the performance of your job, then by all means keep using it. Whether a job is efficient enough depends on how many records you are processing, what criteria you use to evaluate efficiency, etc. I try NOT to make blanket statements about performance since it usually depends.
Back to top
View user's profile Send private message
Skolusu

Senior Member


Joined: 07 Dec 2007
Posts: 2205
Location: San Jose

PostPosted: Tue Aug 31, 2010 11:12 pm    Post subject:
Reply with quote

Captain Paralytic,

I guess you are generating the Tivoli work scheduler control cards. Since the action is just a list, would it hurt to generate the last record twice ? If so you can use the following JCL
Code:

//STEP0100 EXEC PGM=SORT                                     
//SYSOUT   DD SYSOUT=*                                       
//SORTIN   DD *                                             
UHY#S            P 711231                                   
UHYA1            A 711231                                   
UHYA1AVL         P 711231                                   
UHYA2            A 711231                                   
UHYA5            A 711231                                   
//SORTOUT  DD SYSOUT=*                                       
//SYSIN    DD *                                             
  INCLUDE COND=(18,1,CH,EQ,C'A')                             
  SORT FIELDS=COPY                                           
  INREC IFTHEN=(WHEN=INIT,                                   
  BUILD=(C'ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=',     
         20,6,C',ADID=',1,17,C';',80:X)),                   
  IFTHEN=(WHEN=INIT,BUILD=(1,80,SQZ=(SHIFT=LEFT))),         
  IFTHEN=(WHEN=INIT,OVERLAY=(81:1,80)),                     
  IFTHEN=(WHEN=INIT,FINDREP=(INOUT=(C';',C'.'),STARTPOS=81))
  OUTFIL REMOVECC,BUILD=(1,80),TRAILER1=(81,80)             
//*


The output of this job is
Code:

ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA1;   
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA2;   
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA5;   
ACTION=LIST,RESOURCE=ADCOM,STATUS=A,VALTO=711231,ADID=UHYA5.   
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic    IBMMAINFRAMES.com Support Forums -> DFSORT/ICETOOL All times are GMT + 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 

Search our Forum:

Similar Topics
Topic Author Forum Replies Posted
No new posts How to update a portion of text in a ... Bill Woodger DFSORT/ICETOOL 25 Wed Nov 09, 2016 9:41 pm
No new posts sort with previous record anatol DFSORT/ICETOOL 9 Thu Oct 06, 2016 2:36 am
No new posts Get Record count in summary record fo... Atul Banke DFSORT/ICETOOL 21 Fri Sep 23, 2016 4:17 pm
No new posts Change date (DD/MM/YY) in 2nd record ... uday kiran DFSORT/ICETOOL 12 Wed Sep 07, 2016 10:57 pm
No new posts Using 'parm' to vary SORTOUT record v... Sysaron DFSORT/ICETOOL 13 Wed Sep 07, 2016 9:24 pm


Facebook
Back to Top
 
Mainframe Wiki | Forum Rules | Bookmarks | Subscriptions | FAQ | Tutorials | Contact Us