Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Something for the weekend: Moving the record pointer

Status
Not open for further replies.

Mike Lewis

Programmer
Jan 10, 2003
17,516
Scotland
Well, it's been quiet here in the forum this week. I hope this lack of activity isn't causing your brains to go to sleep. Just in case it is, here is a little question to give you something to think about over the weekend.

You have a table open in the current work area. The record pointer can be pointing at any record (including EOF). There might or might not be an index order set. There might or might not be a filter in force. DELETED might be ON or OFF.

Your job is to write some code that will move the record pointer to the physical top of the file. By "physical top of the file", I mean the first physical record, not necessarily the first record in index order. This applies even if the record is marked for deletion, and if it is not included in any current filter.

You may assume that the table is not empty.

Apart from the change in the record pointer, the code should leave the environment exactly as it finds it (so if you change any setting, you must change it back again afterwards).

Easy enough, no? Kudos will go to the person who solves the problem in the least amount of code, that is, the fewest number of lines and the shortest lines.

(If you are one of the first to post a solution, consider using the [ignore][/ignore] tags to temporarily hide your answer so that others can have a shot.)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
How about this?

Code:
Go 1 in alias
If you add the assumption the workarea is currently selected, then it's even just GO 1.
Now for the honest folk not taking a glimpse, a few lines for explanation, so it looks the solution takes a lot more...

It might make you wonder, if that really is sufficient.
An index doesn't renumber records, so record 1 is the first physical record, so the order doesn't matter, that's easy.
But what about recno 1 is excluded by the filter or by being deleted while SET DELETED ON? Doesn't GO 1 then skip this record and directly move on to the next record fulfilling the settings of DELETED and FILTER of that workarea?
If you verify that assumption via browse you get it confirmed, but that's because you browsed, simply check RECNO() after GO 1.
For test purposes SET FILTER TO RECNO()>1, SET DELETED ON and delete the first record (eg in a test table or cursor), then GO 1, ? RECNO().

The only thing, which might bite you with this simple GO is, you have the workarea in record buffer mode and leaving the record causes a problem, but that's a separate problem, only indirectly related to the move of the record pointer, you would have that problem with any move, not only programmatically.

What are the consequences of this? You can always be on a deleted record or on a record, which actually is excluded by the filter. The only dreaded situation of course is, there is no recno 1, but we might make that code a little more complicated to catch that case too:
Code:
If RecCount()>0
   Go 1 in alias
Endif

Bye, Olaf.
 
Sorry, the plan to misguide everyone about the length of code needed failed. In preview, the inner sections were invisible.

Bye, Olaf.
 
rereading:
You have a table open in the current work area.
So in alias isn't needed. I found out it one more thing, though: just 1 will GO 1.
So that's my final solution:
Code:
1
It may look odd to have code with a line just being a 1, but it works.
Bye, Olaf.
 
Olaf's first solution will do the job correctly, but it is too verbose. It can be shortened considerably.

His second post is better. But please have a shot at yourself before looking at that solution.

Also, just to emphasise a couple of points relevant to his first post: (i) the table in question is in the current work area; (ii) you know that the table is not empty.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Obviously, this was too easy for the combined brains of the forum. Fro the record, here is the optimum solution (kudos to Olaf for getting it straight away):

[tt]1[/tt]

I assume it's physically impossible to improve on that, but nothing in Foxpro ever surprises me.

I can see that next time I will have to make the question a lot harder.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I just came across this accidentally.
Not on Friday, it's been a long time ago, already.

I was trying to do a calculation in the command window and forgot to prefix it with a questionmark to show the result. Otherwise I wouldn't have known the solution, as it's undocumented (I think). So this puzzle is really for the senior FoxPro developers.

Astonishingly I remembered it differently, in the back of my head it would switch the workarea, not move the record pointer. Maybe I thought so, because with no table open, it'll cause the table open dialog and I interpreted that as a reaction to an empty workarea number, while it just is a reaction to the current workarea being empty. That makes me wonder, if you may use it to open a dbf at a certain recno instead of top... Indeed you can.

Anyway, I recommend to use a more verbose version of the code as it's not very straight forward. If you have this as a type in a SCAN..ENDSCAN it may cause an endless loop.

Bye, Olaf.
 
I think this form of the command goes all the way back to dBASE and FoxBase. It wasn't documented in FoxBase (at least, not in FoxBase + 2.1, which is far as I go back), but I'm fairly sure it was documented in dBASE, all the way back to dBASE II.

Sorry, I made a typo in writing "typo": type->typo

Is this some kind of recursive error?

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
>Is this some kind of recursive error?

At least it is self-referentially.

Bye, Olaf.
 
I think this form of the command goes all the way back to dBASE and FoxBase.

Yes it does.

I actually used it recently to demonstrate why you don't always know why an error occurred from the resulting dialog.

"Hey Joe, pick a number between 1 and 100."

Type that number in the command window and the File Open dialog pops up. "What does that mean? You gave me the number.
 
FWIW, we did document this in HackFox. The syntax diagram for the GOTO command looks like this:

[pre]
[ GO | GOTO ] [ RECORD ] nRecordNumber | TOP | BOTTOM
[ IN nWorkArea | cAlias ]
[/pre]

I think it's the only command where the initial keyword is optional. (In fact, guess it would have to be.)

Tamar
 
Actually, I see it's documented in Help, too:

You can omit GO or GOTO entirely and specify just the record number. If you specify just the record number, you can move the record pointer only within the current work area.
 
Yes, now I find that sentence buried in the specification of the RECORD nRecordNumber parameter.

The syntax diagram in the VFP help is not making GO | GOTO optional, though:
Code:
GO [RECORD] nRecordNumber [IN nWorkArea | IN cTableAlias]
GO TOP | BOTTOM [IN nWorkArea | IN cTableAlias]
GOTO [RECORD] nRecordNumber [IN nWorkArea | IN cTableAlias]
GOTO TOP | BOTTOM [IN nWorkArea | IN cTableAlias]
So is the syntax only ammended in HackFox or did they also change it in the VFPX help file?

Bye, Olaf.
 
>Type that number in the command window and the File Open dialog pops up.
Also, if you GO N while the current workarea is empty.

Another reason for SET TABLEPROMPT OFF.
Another reason to specify IN workarea.
Another reason for being verbose and sepcific.

Bye, Olaf.
 
Another reason for SET TABLEPROMPT OFF.
Another reason to specify IN workarea.
Another reason for being verbose and sepcific.

Yes, yes, and yes.

IF you're running a version of VFP recent enough to HAVE SET TABLEPROMPT and HAVE IN workarea. [neutral]

 
Olaf Doschke said:
The syntax diagram in the VFP help is not making GO | GOTO optional, though
I guess there is a reason for that :
2+int(1.5) && or any function / variable with numeric value
jumps to the desired record

But :
int(1.5)+2
gives "Syntax error", because VFP didn't find the verb "int", I suppose.

Meanwhile :
Go int(1.5)+2
once again jumps to the desired record, because "Go" is a valid verb.

I guess "Go can be omitted only in some particular cases, but is not optional" is what the help tried to say


Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Actually, I see it's documented in Help, too:

I did check the Help before I stated that it was not documented in VFP, but I obvioiusly didn't look closely enough.

Also, it's only optional when the rest of the command consists of the record number and nothing else. Thus, you can't say any of the following:

[tt]1 IN 1
RECORD 1
TOP
BOTTOM[/tt]

as well as the case that Vilhelm-Ion noted.

So, in that respect, the syntax diagram is correct.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
If that syntax would work, I could
Code:
USE amillion
1 IN amillion

Bye, Olaf.

 
In the spirit of this thread :

Code:
#define in +
CREATE CURSOR cdummy (ii I AUTOINC )
APPEND BLANK
a_million = 0
1 in a_million
BROWSE

VFP is an amazing tool [orientalbow]




Respectfully,
Vilhelm-Ion Praisach
Resita, Romania
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top