View Full Version : File position problem (POSDBF)
01-01-1995, 02:00 AM
I hope someone can help me with this problem. I have a file which has a userid or wsid in the first field. The second field has a printer id. The file is called ?USERPRNT?. The last record in this file is a dummy record. If the first pass does not find a ?userid? then I want to make a second pass looking for a ?wsid?. I have enclosed a copy of how I am setting up for the second pass: SKPUSR: posdbf opnid(userprnt) position(*start) rcvf At this point the dummy record is still selected. The program skips the check steps and uses the default printer id. The first pass works correctly. I am having trouble when I have to do this second pass. It looks like the file is not being reset to the first record. Any ideals or help would be greatly appreciated. Thanks, William?..
06-14-2000, 10:31 AM
William, What you are seeing is the way CL works. You cannot resposition a data base file more than once in a cl program. I suggest that when you reach the end of file call another CL program to search for the workstation id. HTH Doug
06-14-2000, 11:09 AM
William, Instead of POSDBF, how about using OVRDBF? You can use OVRDBF to position by key by using the KEYA KEYB or KEY keywords, or by rrn. I use this quite often when processing records. If you have to postition more than once, (I THINK) you can DLTOVR and then OVRDBF again. Let me know, Bret Myrick
06-14-2000, 12:04 PM
Bret, Can you give me an example. I have tried different ways but the second RCVF still shows end of file record. Thanks, William
06-14-2000, 12:18 PM
William, Are you performing a DLTOVR and OVRDBF prior to the subsequent OVRDBF? Bret
06-14-2000, 01:50 PM
Bret, If no match after the first RCVF. I then branch to a label and do the DLTOVR and OVRDBF then a RCVF again. William..
06-14-2000, 03:00 PM
William, Did that work? It's late and the comment seemed vague to me. Bret
06-14-2000, 06:14 PM
William, As Doug pointed out, you can not set the file pointer once the EOF condition is set. You can bypass this limitation by preventing the program from reading records pass the last record in the file. Use the RTVMBRD command to retrieve the current number of records NBRCURRCD parameter. Keep a counter as you read through the records in the file, when this counter reaches the current number of records, it's time to set the file pointer to the beginning of the file OVRDBF file_name POSTION(*START). HTH
06-15-2000, 05:16 AM
Here is an article I found in the News/400: Reread a File in CL After Reaching End-of-File by John Earl NEWS/400, December 1998 , pg. 94 Article ID: 6674 Related Topics: CL One of the frustrating things about CL programs is that once you read to the end of a file, there is no way to reposition the file within that routing step. If you want a CL program to read through a file multiple times, you can't let that program ever actually reach the end of the file. There are a number of popular schemes you can use to detect the end of a file before your program actually receives message "CPF0864 End of file detected for file &1 and &2," but these methods are slow and potentially error prone. However, one method stands above the rest, and it uses the TFRCTL (Transfer Control) command. When you want to cycle repeatedly through the same set of data, your program can use TFRCTL to transfer control to the same program name to get a new invocation stack. Because TFRCTL starts a new invocation of the program, there is no problem with hitting the end of a file and receiving CPF0864. You can cycle through the file as many times as you like. The code for a program named "MyProgram" that uses this technique would look something like this: Pgm DclF MyFile Read: RcvF MonMsg ( CPF0864 ) Exec( GoTo Restart ) . . . GoTo Read Restart: TfrCtl MyProgram EndPgm Just be careful not to code yourself into an infinite loop! You'll need to add logic to the above example to account for that possibility. John Earl, Technical Editor, NEWS/400
06-15-2000, 07:42 AM
Bret, Sorry about that, everyone decided to have problems about time to go home. It did not work. When it did not find the user in the first RCVF it branched to the second RCVF. I then did the DLTOVR, OVRDBF (with *START). File was not reset, still at end. I think I will try to put a dummy record (last record in file) in the file. Then check for it, if found branch to next RCVF and do the reset. This way the file will never reach the EOF. This project sounded so simple when I started it!! Thanks, William
06-15-2000, 09:09 AM
William, The example I posted assumes a key field. Try using the OVRDBF with keyword POSITION(*RRN 1). This should reposition the file to record # 1. Bret
06-15-2000, 12:15 PM
Once a file hits End-of-file in a CL program, you cannot reread the file in the same instance of the CL program. Period. You need to retrieve the number of records in the file with RTVMBRD and then read exactly that many records from the file and NOT HIT eof - then you can reposition the file pointer. This of couse presumes that the number of records in the file will not change. You can also do TFRCTL or break your CL program into 2 CL programs and have the first CL program call the 2nd CL program each time to read the file. Chris
06-15-2000, 02:57 PM
Here's a fragment I used last year, when I wanted to infinitely loop thru a program. I don't know if/how it'll apply to a file that can change its contents. <PRE> PGM DCL &CTR *DEC (3 0) DCL &RCDS *DEC (10 0) DCLF myfile RTVMBRD FILE(myfile) NBRCURRCD(&RCDS) OVRDBF FILE(myfile) SHARE(*YES) OPNDBF FILE(myfile) OPTION(*INP) NEXT: RCVF /* should probably test for &RCDS = 0 before this */ MONMSG CPF0864 EXEC(GOTO DONE) /* do stuff with record from file */ /* do more stuff */ CHGVAR &CTR (&CTR + 1) IF (&CTR = &RCDS) DO CHGVAR &CTR 0 POSDBF OPNID(myfile) POSITION(*START) ENDDO GOTO NEXT END: ENDPGM </PRE> The RTVMBRD would have to be moved to the end of the loop or in its own outer execution loop or something in order to get the &RCDS of the file if it changes. This example just does an infinite loop (unless I delete a record from MYFILE).
06-15-2000, 03:00 PM
Ooops. I left off the initialization value of the counter. The declaration for &CTR should be DCL &CTR *DEC (3 0) VALUE(0) (3 0) worked for my purposes but you might want to make it much larger. I tried to find the thread on posting code in the original font but couldn't...
Powered by vBulletin® Version 4.1.5 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.