Error No 5 Record is out of range Error No 5 Record is out of range mstrcmtr (Programmer) (OP) 28 Apr 18 13:59 What are the reasons of the following error and how to avoid this error Record is out of range Working in multi user environment RE: Error No 5 Record is out of range Mike Lewis (Programmer) 28 Apr 18 15:31 Pretty well what the message says. Typically, it happens if you try to go to a record number that is beyond the end of the table. So, if the table has 100 records, and you GOTO 101, you will get that error. Also if you try to go to a negative record number (there is an exception to that, but it's probably not relevant so I won't confuse the issue). You might also see it if the index is corrupted. If you think that might be the case, try to REINDEX the table. The fact that you are in a multi-user environment is probably not relevant. Mike __________________________________ Mike Lewis (Edinburgh, Scotland) Visual FoxPro articles, tips and downloads RE: Error No 5 Record is out of range Olaf Doschke (Programmer) 28 Apr 18 21:20 I recently rambled about RECNO as bad way to remember a record position to go back to in thread184-1786102: Grid go recno()+1/-1 with index set order to Take any table, no special settings required. Do this: CODEUSE your.dbf GO Bottom SKIP 1 ? RECNO(), RECCONT() GOTO RECNO() This just shows one of several situations, in which RECNO() can be a record number you can read and "have" but not GOTO. Bye, Olaf. RE: Error No 5 Record is out of range myearwood (Programmer) 7 May 18 21:13 mstrcmtr IF NOT EOF() SKIP ENDIF Don't skip when at eof() Mike Yearwood - Former FoxPro MVP RE: Error No 5 Record is out of range Olaf Doschke (Programmer) 7 May 18 21:28 The lesson rather is, when remembering the position to go back to, you can't always go back to what RECNO() gave you previously. And it's answering why you can get this error 5. In my sample code that doesn't happen at the line SKIP 1, but at GOTO RECNO(), which you would naively expect to always work. Besides notice the output of this: CODEON ERROR ?? ERROR(), MESSAGE() USE foxcode.dbf GO Bottom ? EOF(), RECNO(), RECCOUNT() && output .F., 1008, 1008 SKIP 1 ? EOF(), RECNO(), RECCOUNT() && output .F., 1009, 1008 ? "GOTO RECNO():" GOTO RECNO() ? "SKIP 1:" SKIP 1 Your exact record count may vary as you can extend foxcode, but it's a system table for intellisense you should have with VFP7 and above. SKIP 1 at EOF() errors with error 4, not error 5, so it's very likely you encounter error 5 = record out of range from a GOTO RECNO of a record number you previously encountered. There is an obvious truth in not skipping 1 at EOF, that errors with error 4, but is not directly related. You can already be quite sure you won't be able to GOTO the same record, if you save the current RECNO(), while you're at EOF(), that's more to the point. The ideal way to get back to a record you started with is remembering its primary key value, not its record number. If you stick for RecNo, as it's generally available, say you store lnRecno=RECNO() then you need to deal with errors you encounter at GOTO lnRecno, there are more cases than the one higher than RecCount Recno at EOF() this code shows, in buffering modes RECNO() of new records is negative and only becomes positive when it's saved. And in record buffering that will happen if you leave the record. If you also store RecCount() at the time you could get to the record previously having the negative record number by navigating to the previous RECCOUNT and then SKIP forward -lnRecno records, which is skipping forward, as lnRecno<0. But instead of getting all that complicated about the GOTO handling, rather remember IDs of the record you want to go back to and use that for record navigation via SEEK. you still always should cover cases of not finding a record, which could be deleted in the meantime, so any such mechanism of remembering a position to go back to us bound to fail under special conditions and likely works in first tests, if you never test special cases. Bye, Olaf. RE: Error No 5 Record is out of range David Higgs - G4NVB (TechnicalUser) 8 May 18 07:06 Just recently I was suffering the same issues, I found:- This didn't work:- CODE --> IF NOT EOF() SKIP 1 ELSE SKIP -1 ENDIF But this did:- CODE --> IF NOT EOF() SKIP 1 ENDIF * IF EOF() SKIP -1 ENDIF Regards, David. Recreational user of VFP. RE: Error No 5 Record is out of range Mike Lewis (Programmer) 8 May 18 07:43 Quote (Mike Y.)CODE --> IF NOT EOF() SKIP ENDIF I disagree. If you are on the last record, you are not yet at EOF, so the above code will skip to eof, which is not where you want to be. I would prefer: CODE --> SKIP IF EOF() SKIP -1 ENDIF Mike __________________________________ Mike Lewis (Edinburgh, Scotland) Visual FoxPro articles, tips and downloads RE: Error No 5 Record is out of range David Higgs - G4NVB (TechnicalUser) 8 May 18 08:09 Replacing my double IF/ENDIF Statements with Mike's code worked ok in my application. Although they are doing the same job Mike's Code was more elegant than mine! Thanks Mike. Regards, David. Recreational user of VFP. RE: Error No 5 Record is out of range Olaf Doschke (Programmer) 8 May 18 08:39 David, it's OK to check EOF() before SKIP 1, too, because you always can be at EOF through a LOCATE not finding something, for example. It's off topic in regard of the error 5, though, as you don't get it through skipping forward or backward alone. Notive SKIP at EOF causes error 4. Well, when we're at navigation, then the full way to do it: You already can öook it up, it's in foxpro sample code multiple times! In FFC base classes you can take _navbtns from _datanav.vcx for navigation. Here's the essential code: CODE* first botton: Locate this.RefreshForm() CODE* previous button: IF NOT BOF() SKIP -1 ENDIF this.RefreshForm() CODE* next button IF NOT EOF() SKIP ENDIF IF EOF() SKIP -1 ENDIF this.RefreshForm() CODE* last botton: Go Bottom this.RefreshForm() The idea of a refreshform() method could in the simplest case just call THISFORM.REFRESH(), it cascades and even the navbar you are working from could, for example, enable/disable buttons depending on record pointer. When you already SKIP -1 after detecting EOF(), that means you can't detect being at the bottom via checking EOF() in Refresh() code, so that would need another SKIP 1 and EOF() check because checking RECNO()=RECCOUNT() won't give you the correct answer in the general case data is sorted by any index. So notice how quirky that all gets. It's no wonder many navbars fail to work properly all of the time, but they never cause error 5, unless you offer a goto button using a wrong recno. Nevertheless, exactly what you had in terms of next button is good and better by not simply doing SKIP without first checking EOF(), to avoid error 4. To avoid being at EOF AFTER clicking the next button you test EOF() again after SKIP and then SKIP -1, as here. But this doesn't prevent any other reason to get to EOF(). And not any other reason to get to error 5. You can't make this airtight by a perfect navigation, but it contributes to less EOF() problems if you incorporate that. Anyway, you need to watch out before any REPLACE, silently doing nothing at EOF(). Notice, FOUND() is just a synonym for NOT EOF(), that means when FOUND() is false, Locate has really put the record pointer to EOF. Go Bottom only puts it to the last record before EOF, so that is perfect for the "last" button and GO TOP is the usual way to go to the first record, but LOCATE without any FOR condition is better optimized, especially in case of data sorted by an index, again, so your "first/top" button would do LOCATE and your "last/bottom" button would do GO BOTTOM, another asymmetry. Final words still are: Even with the perfect navbar button behaviour you're not failsafe against any other code working in thw wrong workarea are explicitly the right but not repositioning after getting to EOF(). Even with button disabling to avoid impossible navigation, this only happens when you actively call the refreshform, there is no event, if a LOCATE repositions a record pointer, etc. So navbar button can reflect a wrong situation. It's a very general rule that you can't rely on the outset being in your full control and you don't need to check before doing something. So also in case of the error 5, you can do so in TRY..CATCH Bye, Olaf. RE: Error No 5 Record is out of range David Higgs - G4NVB (TechnicalUser) 8 May 18 16:33 Olaf, Many thanks for your reply, very interesting. I will follow your Code and advice posted on this thread. Regards, David. Recreational user of VFP. RE: Error No 5 Record is out of range Olaf Doschke (Programmer) 8 May 18 17:20 OK, I tidied up a bit and split code for the various buttons, there's still more to it, if you want to enable/disable buttons. Also this doesn't yet address activating the correct workarea, that's a prerequisite. What never makes things airtight is, that you typically have code doing LOCATEs. Setting a FILTER or requiring data changes the current situation, too. I don't think much of navbars, as the natural way to navigate a list is the scrollbar a grid provides. It might be nice to have top/bottom as extra buttons, but otherwise, you have a window listing a few rows and you pick one by a click. It's also possible to navigate that with keyboard only. Bye, Olaf.