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 [tt]LOCATE[/tt] and your "last/bottom" button would do [tt]GO BOTTOM[/tt], 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.