How to use SETLL and READE to solve this program

Tags:
AS/400
Physical File
I have to write those records in PF whose criteria is as follows: * [b] C - [/b] = 'y' * [b] record must be latest for particular id [/b]here is the data - pf name - FILEA (to be read) and FILEB ( to be write) [b] A B C [/B] 10 1 N 11 1 Y 11 2 Y * 13 1 N 14 1 N 14 2 Y 14 3 Y * 15 1 Y * I have to write only that data which has * in front of them. Please help me friends.

Software/Hardware used:
as400 machine

Answer Wiki

Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Discuss This Question: 35  Replies

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
  • rpglecodingusingas400
    data is like this: 10 1 N 11 1 Y 11 2 Y * 13 1 N 14 1 N 14 2 Y 14 3 Y * 15 1 Y *
    115 pointsBadges:
    report
  • TomLiotta
    You could use SETLL and READE, but it doesn't make much sense. Those don't fit the problem well at all. The simplest is probably just to run a basic SQL statement:
    insert into FILEB
       select
           A, max(B), max(C)
         from FILEA
         where C ='Y'
       group by A
       order by A
    That's all that's needed and it's a much better fit then SETLL can be. If FILEB doesn't exist, you can use a CREATE TABLE FILEB AS result-set WITH DATA statement instead of an INSERT. Use the SELECT statement as the result-set.
    .
    Tom
    125,585 pointsBadges:
    report
  • rpglecodingusingas400
    i agreed with you, but i have to do without using sql. Only loops and flags and setll and read.
    115 pointsBadges:
    report
  • TomLiotta
    Since SETLL and READE don't make sense to use for this, and since you are restricted from using SQL as a solution, it seems very much like an academic assignment. You need to show the code you have worked out first, then we can possibly comment on your code. We can't provide code for you. -- Tom
    125,585 pointsBadges:
    report
  • philpl1jb
    So you should 1. develop a "read" loop from File A. 2. Within the loop you would have if logic to determine if the current record should be processed 3. for a record that should be processed you should do the necessary steps 4. and write the record for file B 5. Continue with the read loop You can post your code on this site with the issues and we will help .. guide you.
    51,365 pointsBadges:
    report
  • ravula
    Fipf01 if e k disk Fipf02 o e disk C *loval setll format1 C read format1 c dow not %eof C if VAL='Y*' C move num num2 c move sign sign2 c move val val2 c write format2 c endif c read format1 c enddo c eval *inlr=*on
    700 pointsBadges:
    report
  • ravula
    hello please try the above code it moay works for you. thanks, satya
    700 pointsBadges:
    report
  • ravula
    ============IPF01 A R FORMAT1 A NUM 3S 0 A SIGN 1S 0 A VAL 3A A K VAL ===========IPF02 A R FORMAT2 A NUM2 3S 0 A SIGN2 1S 0 A VAL2 3A A K VAL2 here these are the files which i used , data which you have given i have inserted into ipf01 and after executing the program , it inserts the data you wish into ipf02
    700 pointsBadges:
    report
  • philpl1jb
    ravula That's very impressive but it was a homework problem ..we try to help people learn, not do homework for them! There is no learning in copying. Phil
    51,365 pointsBadges:
    report
  • rpglecodingusingas400
    thanks everyone.. but i tired a lot, thats learning assigment ur rite... but i am unable do so.. i ll send u my code i tired than please correct it whether i am rite or wrong while using setll and reade.
    115 pointsBadges:
    report
  • rpglecodingusingas400
    ravula and phil thanks.. ravula i already applied the same code before... it wont solve my problem..because i have to print the latest records means the record which i hv marked as *.
    115 pointsBadges:
    report
  • rpglecodingusingas400
    i am not a student , i am it professional.. as400 and rpg is new to me..thats why facing such kind of problem.
    115 pointsBadges:
    report
  • philpl1jb
    "ravula i already applied the same code before" Ravula's code followed my logic and met your spec. It wrote the records to file B only for rows with C if VAL=’Y*’ The command c write format2 writes the records print the latest records -- PRINT? you said write them to the file B. Do you want to PRINT them to a spool file or Write them to a file or both. Phil
    51,365 pointsBadges:
    report
  • rpglecodingusingas400
    100 Ist record (grp 1) 101 2nd record(grp2) 101 3rd record(grp2) 101 4th record(grp2) 102 … 102 … 103 .. 104 8th record(grp5) Suppose I have to traverse the whole pf having data as above. I need to traverse each set of key perform some action specifically n then traverse further set of Key. According to my knowledge of setll and reade commands. I will do like this… Suppose key=101 Setll key filea If %equal Dow not %eof Reade key filea ……… ……… Condition; Enddo Write fileb Endif In this way I can traverse the one group , but how do I change the key to point the another set of keys. As i told u i am new to rpg.. might be answering to the above question can solve my previous problem...
    115 pointsBadges:
    report
  • rpglecodingusingas400
    phil code given by ravula will half justify of condition. i have to satisfy the C='y' as well as write the latest records. which i mentioned as *.
    115 pointsBadges:
    report
  • TomLiotta
    ...please try the above code it moay works for you.

    @ravula: The code you posted could work, but it would copy too many records. Your code copies every record with 'Y', but only some of those should be copied. You are missing logic to select only highest numbered 'Y' record in each group. Also, you don't have any READE statements.
    .
    For some unknown reason, a solution needs those elements.
    .
    Tom
    125,585 pointsBadges:
    report
  • philpl1jb
    Solution 1 sequential read through all of IPF01 but control break processing this only writes records when new ID is found f============IPF01 A R FORMAT1 A ID 3S 0 A SEQ 1S 0 A YN 1A A K ID A K SEQ Fipf01 if e k disk Fipf02 o e disk C *loval setll format1 C read format1 c dow not %eof C if VAL=’Y’ C if ID ID2 and ID2 *blanks C write FORMAT2 C endif C move ID ID2 c move seq seq2 c move YN YN2 c c endif c read format1 c enddo * write last value c if ID2 *blanks C write FORMAT2 C endif c eval *inlr=*on
    51,365 pointsBadges:
    report
  • philpl1jb
    To make it more efficient we need a different key .. and that probably means a logical file. This program will only read the records that you want to print... at least as I understand the spec's. ----- Logical file ILF01 A R FORMAT1 PFILE(IPF01) A K ID A K SEQ DESCND A S YN EQ('Y') Although the syntax of this logical file may need a bit of adjustment it will allow you to build a more efficient program. Filf01 if e k disk Fipf02 o e disk C *loval setll format1 C read format1 c dow not %eof C setll *LOVAL Ilf01 C Read ILF01 C Dow Not %EOF(ILF01) C Exsr wrtRec C Setgt (ID ) ILF01 C Read ILF01 C Enddo C Eval *INLR = *ON C Return C wrtRec Begsr C eval ID2 = ID C eval Seq2 = seq C eval YN2 = YN C Write Format2 C EndSR I had picked up some MOVE's in the code I borrowed. Do not use MOVE in RPGLE .. EVAL I'm wondering if the C Setgt (ID ) ILF01 should be C Setgt (ID : *HIVAL ) ILF01C or Setgt (ID : *LOVAL ) ILF01 but I think the single key will be sufficient. This positions you just before a record with a higher key than the current value of ID.
    51,365 pointsBadges:
    report
  • philpl1jb
    Sorry forgot this editor takes out the greater than and less than symbols so this line C if ID ID2 and ID2 *blanks should be C if ID ne ID2 and ID2 ne *blanks where ne are those two symbols that mean greater than and less then ..
    51,365 pointsBadges:
    report
  • philpl1jb
    But I'm much more likely to Solve this problem with the sequential read solution then with the special logical file based solution. The cost of maintaining the logical doesn't make much sense in most cases.
    51,365 pointsBadges:
    report
  • philpl1jb
    "No, no, you're not thinking; you're just being logical." Niels Bohr
    51,365 pointsBadges:
    report
  • TomLiotta
    The tricky part is getting to the first record in the next group. The only reasonable thing to do is set B to *HIVAL, then use SETLL to position just after the A+B compound key. The next record then needs to be READ to prime the loop for the next group. After the priming READ, READE can get that group's records. . Although it can work, it's not a good way to get the problem solved when compared to other methods. I suppose that the value in assigning the task is in seeing how statements work even if the method isn't very useful for anything. . Tom
    125,585 pointsBadges:
    report
  • philpl1jb
    Sorry .. late at night .. the logical based one had some stry lines shown below Filf01 if e k disk Fipf02 o e disk --- these three lines are duplicate please remove delete C *loval setll format1 delete C read format1 delete c dow not %eof -------- end the bad rows
    51,365 pointsBadges:
    report
  • philpl1jb
    And finally an answer which reads the first row of each set and then jumps to the end of the set and reads from the end of the set until it finds a row that meets your requirements. It then jumps past the current set and repeats the process. with big sets, this might be of value. Fipf01 if e k disk Fipf02 o e disk **** read first rec of set put ID in field wrkID C setll *LOVAL IPF01 C Read IPF01 C Dow Not %EOF(IPF01) C eval WrkID = ID C Exsr ChkID C Setgt (wrkID) IPF01 C Read IPF01 C Enddo C Eval *INLR = *ON C Return **** go to end of the set and read backwards **** setgt positions just beyond the value **** readp reads backwards **** readpe reads backwards but if the readp doesn't match the key then it returns %EOF C chkID Begsr C Setgt (wrkID) IPF01 C Readpe (wrkID) IPF01 C Dow not %EOF(IPF01) and YN ne ('Y') ***** not equal symbols here C Readpe (wrkID) IPF01 ****** reads backwards until it finds a 'Y' ****** or runs out of data that equals the key C Enddo C If not %EOF(IPF01) C Exsr wrtRec C Endif C Endsr C wrtRec Begsr C eval ID2 = ID C eval Seq2 = seq C eval YN2 = YN C Write Format2 C EndSR
    51,365 pointsBadges:
    report
  • TomLiotta
    And finlly an answer...

    "An" answer, but can't be "the" answer because it doesn't meet all of the (very questionable) requirements. You have to use SETLL and READE to solve it.
    .
    Weird, but we don't make the rules. I don't know if it counts if you use a READE and simply discard the results.
    .
    Tom
    125,585 pointsBadges:
    report
  • philpl1jb
    and there were a few &EOF that didn't specify a file .. that's not my standard.\\ Just more code that I picked up .. sure wish the EDIT feature of this page worked.
    51,365 pointsBadges:
    report
  • philpl1jb
    FINALLY uses SetLL, SetGt, Read, READPE and a whole bunch of other commands FINALLY doesn't use READE FINALLY is my finally Someone else can do BEYOND FINALLY. Beyond FINALLY is entertaining quotes.
    51,365 pointsBadges:
    report
  • TomLiotta
    The code feels tricky, though not too difficult. I could post a working example, but I'd like to see the OP's best try first. Mine does use a READ at a critical point, but just SETLL and READE to get to each output record. I put it up under my pastebin ID, so I can link it here when I see what shows up. -- Tom
    125,585 pointsBadges:
    report
  • rpglecodingusingas400
    thanku so much guys... i ll try it.. and get back to you ..
    115 pointsBadges:
    report
  • philpl1jb
    FINALLY Tricky .. yes .. I prefer Solution 1 the sequential read. Simple, straight forward, works, can be maintained. ---- "Who are you going to believe, me or your own eyes?" Groucho Marx
    51,365 pointsBadges:
    report
  • TomLiotta
    I'd go simple SQL first. Without SQL and in the absence of problematic requirements that exclude this method, I might just use the Cycle and write my output at L1 total time. -- Tom
    125,585 pointsBadges:
    report
  • rpglecodingusingas400
    hey phil thanks ur help worked, finally i did it. bcoz of ur code i also learnt the use of SETGT ,READPE. now feeling comfortable with these commands.
    115 pointsBadges:
    report
  • TomLiotta
    Post your working code here, and we'll see if we can help improve it. I'll post mine after yours. Tom
    125,585 pointsBadges:
    report
  • philpl1jb
    Great .. SETGT and,READPE aren't operations that I need to use frequently.
    51,365 pointsBadges:
    report
  • TomLiotta
    Since a couple days have gone by, I might as post this code. I changed file and field names to help a little in seeing what's happening in code. The files are MYDATA and MYDATA2. The fields are K1 and K2 for the two useful keys. (K2 isn't required. Logic could be changed to track the highest K2 value in each group.) MYDATA was created with:
    CREATE TABLE 
       MYLIB/MYDATA (
                      K1 INT NOT NULL WITH DEFAULT, 
                      K2 INT NOT NULL WITH DEFAULT, 
                      F1 CHAR ( 1 ) NOT NULL WITH DEFAULT
                    )
    Keys could have been added with a PRIMARY KEY clause, but I chose to use a ADDPFCST command:
    ADDPFCST FILE( MYLIB/MYDATA ) TYPE( *PRIKEY ) KEY( K1 K2 )
    MYDATA2 was simply duplicated. Then MYDATA was populated with a series of INSERT statements like this:
    INSERT INTO MYLIB/MYDATA VALUES( 10, 1, 'N' )
    INSERT INTO MYLIB/MYDATA VALUES( 11, 1, 'Y' )
    The RPG is free-form to help visualize the logic:
         Fmydata    if   e           k disk    extfile( 'MYLIB/MYDATA' )
         f                                     rename( mydata:mydatar )
         Fmydata2   o    e             disk    extfile( 'MYLIB/MYDATA2' )
         f                                     rename( mydata:mydata2r )
    .
         D k1save          s                   like( k1 ) inz( *loval )
         D k2save          s                   like( k2 ) inz( *loval )
    .
          /free
            dou  *inlr ;
    .
               setll ( k1save:k2save )  mydata ;
    .
               if  %found ;
    .
                   read  mydata ;
                   k1save = k1 ;
    .
                   dou  %eof( mydata ) ;
                       reade ( k1save )  mydata ;
                   enddo ;
    .
                   if  F1 = 'Y' ;
                      write  mydata2r ;
                   endif ;
    .
                   k2save = *hival ;
    .
               else ;
    .
                   *inlr = *on ;
    .
               endif ;
    .
            enddo ;
    .
            return ;
          /end-free
    Each time the program runs, MYDATA2 can be viewed with RUNQRY and cleared with CLRPFM. Running in debug can help show why any minor parts work.
    .
    Tom
    125,585 pointsBadges:
    report

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Thanks! We'll email you when relevant content is added and updated.

Following