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

Array manipulation


IBM Mainframe Forums -> CLIST & REXX
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
Narmadha Krishnamurthy

New User


Joined: 19 Aug 2008
Posts: 8
Location: Chennai

PostPosted: Tue Aug 18, 2009 6:03 pm
Reply with quote

Hello,

I am a novice to REXX and I am trying to automate a routine task. Here's my problem :

I have a huge record of 2000 bytes which has an array starting position 500 and ending at position 1500. The array stores 200 strings of 4 bytes each, in sorted order by spaces (AAB1 ABC3 ACR2 ADE1 etc). The purpose of my macro is, when given a particular string, I should be able to find the position of the string in the input file and insert it there. I don't want to edit the same file. I just want to find the position and write it along with the other strings to an output file.

I thought I could read the file, move all the records to a stem, then access the array starting position 500, move it to another stem, access the strings one by one and compare against the string I have, when I find a string that is greater than the one I have, say at i th position, I could move the string to i+1 th position, move my string to i th position and write the data to the output file.

Here is where I am:

As the first step, I wrote the following small piece of macro, to check if I am able to access the records of the input file using a stem:

Code:

/*Rexx*/                                                       
Address TSO                                                     
"ALLOC FILE(myindd) DA('T.INPT') SHR"       
"EXECIO * DISKR  myindd (STEM INPTrec."                         
"Free F(myindd)"                                               
do                                                             
  i = 1 TO INPTrec.0                                             
  say INPTrec.i                                                 
end       


and I get the following error message:

FILE MYINDD NOT FREED, DATA SET IS OPEN
INPTREC.1 TO 1060
***

I guess my bookish knowledge isn't helping here. Please bear with me if my mistakes are absurd and kindly let me know if my approach will work. Any advice on the code is most welcome.


Thank you in anticipation!
Back to top
View user's profile Send private message
expat

Global Moderator


Joined: 14 Mar 2007
Posts: 8797
Location: Welsh Wales

PostPosted: Tue Aug 18, 2009 6:14 pm
Reply with quote

try changing
Code:
"EXECIO * DISKR  myindd (STEM INPTrec."

to
Code:
"EXECIO * DISKR  myindd (STEM INPTrec. FINIS"
Back to top
View user's profile Send private message
Narmadha Krishnamurthy

New User


Joined: 19 Aug 2008
Posts: 8
Location: Chennai

PostPosted: Tue Aug 18, 2009 6:23 pm
Reply with quote

Hello Expat,

I still don't get the display I am hoping to see...I get the following display

INPTREC.1 TO 10
***

I thought my piece of code will display the records one by one from the Input file. Am I wrong in my understanding?
Back to top
View user's profile Send private message
Marso

REXX Moderator


Joined: 13 Mar 2006
Posts: 1353
Location: Israel

PostPosted: Tue Aug 18, 2009 6:34 pm
Reply with quote

Two small modifications to your REXX:
1. FINIS added to the EXECIO command.
2. "do i=" on one line (otherwise they are 2 different commands).
Code:
/*Rexx*/
Address TSO
"ALLOC FILE(myindd) DA('T.INPT') SHR"
"EXECIO * DISKR myindd (FINIS STEM INPTrec."
"Free F(myindd)"
do i = 1 TO INPTrec.0
   say INPTrec.i
end


I wouldn't work with a stem for the array, as there is no function to insert an item in the middle of a stem.
Instead, I would use something like that:
Code:
PARSE VAR INPTrec.I 1 LeftSide 500 TheList 1501 RightSide
Do Disp = 1 By 5
   TheWord = Substr(TheList,Disp,4)
   If TheWord = '' Then Leave
   If TheWord > MyNewWord Then Leave
End
TheList = Insert(MyNewWord,TheList,Disp,5)
OUTrec.I = LeftSide || Left(TheList,1000) || RightSide


I haven't tested this piece of art, you will have to do some debugging.
Learn about the functions, test them with TRACE and come back to tell us how you succeeded.
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Tue Aug 18, 2009 9:30 pm
Reply with quote

The open dataset is probably from an earlier open and read. It is hard to close it by running the exec a second time. Trying logging on again.
Back to top
View user's profile Send private message
Narmadha Krishnamurthy

New User


Joined: 19 Aug 2008
Posts: 8
Location: Chennai

PostPosted: Tue Aug 18, 2009 10:45 pm
Reply with quote

Hello Marso,

Thank you for your kind help! All your corrections worked and your logic had hit the bull's eye! It was a fine piece of art!

So here is the code that works

Code:
/*Rexx*/                                                             
Address TSO                                                           
"ALLOC FILE(myindd) DA('T.INPUT') SHR"             
"ALLOC FILE(myoutdd) DA('T.OUTPUT') SHR"       
"EXECIO * DISKR  myindd (FINIS STEM INPTrec."                         
"Free F(myindd)"                                                     
Say 'Enter the string to be added'                                   
Pull Newstr                                                           
do i = 1 TO INPTrec.0                                                 
  PARSE VAR INPTrec.i 1 Leftside 501 oldstr 1501 Rightside         
  Do disp = 1 by 5 until oldstr = '    '                                 
     Opt = substr(oldstr,disp,4)                                   
     If oldstr = '    ' Then Leave                                       
     If oldstr < Newstr Then nop                                         
     If oldstr > Newstr Then Leave                                       
  end                                                                 
     If oldstr > Newstr Then                                             
        disp = disp - 1                                               
        oldstr = Insert(Newstr,oldstr,disp,5)                   
        outrec.I = Leftside||Left(oldstr,1000)||Rightside   
       "EXECIO * DISKW myoutdd (FINIS STEM outrec."             
end                                                             
"Free F(myoutdd)"     
Code'd
The only thing that is running in my mind is that, if I try to loop the code (like a recursive call based on a user reply) for adding multiple strings, this doesn't work. Any advice for the looping idea?

Once again, Many Thanks!
Back to top
View user's profile Send private message
Marso

REXX Moderator


Joined: 13 Mar 2006
Posts: 1353
Location: Israel

PostPosted: Wed Aug 19, 2009 5:58 pm
Reply with quote


  1. You're welcome.
  2. I think you got mixed with Opt and oldstr when you copied your program.
  3. Although your program works, there is still one big bug:
    The EXECIO * DISKW is located within the loop. It means you update the 1st line, rewrite the whole file, update the 2nd line, rewrite the whole file... and so on.
  4. When posting on the forum, always use BBCode.
    This will keep the indentation you use in your programs and make bugs like this one easier to spot.

Now, about your other question,
The trick is to split the logic into smaller blocks.
Look at this:
Code:
Say 'Enter the string to be added'
Pull Newstr
do i = 1 TO INPTrec.0
   PARSE VAR INPTrec.i 1 Leftside 501 oldstr 1501 Rightside
   Call Process_One_Rec
   outrec.I = Leftside||Left(oldstr,1000)||Rightside
end
EXECIO...
FREE...
Exit

Process_One_Rec:
   Do disp = 1 by 5 until opt = ' '
      Opt = substr(oldstr,disp,4)
      If opt = ' ' Then Leave
      If opt < Newstr Then nop
      If opt > Newstr Then Leave
   end
   If opt > Newstr Then
      disp = disp - 1
   oldstr = Insert(Newstr,oldstr,disp,5)
Return

It is almost the same code as you wrote but...
now you want multiple strings ? No problem!
Code:
Say 'Enter many strings to be added'
Pull NewstrList
Strmax = Words(NewstrList)
do i = 1 TO INPTrec.0
   PARSE VAR INPTrec.i 1 Leftside 501 oldstr 1501 Rightside
   Do Mult = 1 to Strmax
      Newstr = Word(NewstrList,Mult)
      Call Process_One_Rec
   end
   outrec.I = Leftside||Left(oldstr,1000)||Rightside
end
EXECIO...
FREE...
Exit

Again, I didn't validate this code.
Back to top
View user's profile Send private message
Narmadha Krishnamurthy

New User


Joined: 19 Aug 2008
Posts: 8
Location: Chennai

PostPosted: Wed Aug 19, 2009 7:07 pm
Reply with quote

Hello Marso,

Thank you again for the reply...Sorry about the Opt and Old str...I had to give different terms while pasting it here....will certainly use BBC code from now on.

Please clarify just one little thing in your code..
For adding multiple strings, what does the variable Newstrlist indicate? list of strings delimited by spaces?

Thanks and Regards,
Narmadha
Back to top
View user's profile Send private message
Marso

REXX Moderator


Joined: 13 Mar 2006
Posts: 1353
Location: Israel

PostPosted: Wed Aug 19, 2009 7:47 pm
Reply with quote

Yes, it is a list of strings delimited by spaces
for each record, you insert the words one by one into the array.

Don't give up reading the REXX reference books.
I still do (and I wrote my first rexx program around 1984...)
Back to top
View user's profile Send private message
Narmadha Krishnamurthy

New User


Joined: 19 Aug 2008
Posts: 8
Location: Chennai

PostPosted: Wed Aug 19, 2009 9:05 pm
Reply with quote

Hello Marso,

It is such an honour to be able to contact veterans like you on these forums. Very kind of you to help novices like me!

And yes, your code doesn't have to be tested. You seem to auto-run the code while writing icon_smile.gif

I will certainly follow your advice and keep reading as much Rexx manuals as possible.

Many Thanks for your kind help!

Regards,
Narmadha
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Wed Aug 19, 2009 9:22 pm
Reply with quote

Quote:
I still do (and I wrote my first rexx program around 1984...)

And that is about the time that rexx came out on MVS!
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 -> CLIST & REXX

 


Similar Topics
Topic Forum Replies
No new posts COBOL Ascending and descending sort n... COBOL Programming 5
No new posts To find an array of words (sys-symbol... JCL & VSAM 9
No new posts How to move values from single dimens... COBOL Programming 1
No new posts array indexing PL/I & Assembler 4
No new posts COBOL batch program using large size ... COBOL Programming 3
Search our Forums:

Back to Top