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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Perplexed with loss of indexing

Status
Not open for further replies.

FoxEgg

Programmer
Mar 24, 2002
749
AU
Why doesn't this work ?

I checked it in COMMAND WINDOW --------------- IT WORKS (keeps the indexing)
I checked every step-------------------------- IT WORKS (keeps the indexing)

I then run the same code in a form in a TextBox.Init --- IT Loses the INDEXING AND SO FAILS THE SEEK

Code:
SELECT patient_episodes
SET ORDER TO pt_episode
SET ORDER TO 
MESSAGEBOX("DBF() is")              <--- checks name and is OK
MESSAGEBOX(DBF())                   <--- checks name and is OK

MESSAGEBOX("oGlobal.prop1 is ")     <--- this is OK
MESSAGEBOX(oGlobal.prop1)           <--- this is OK
GO top                              <--- not necessary but is OK

MESSAGEBOX("cdx(1) is")             <--- this is OK in Command Window
MESSAGEBOX(cdx(1))                  <--- this is OK in Command Window
                         but loses index when run in Form Code

SET EXACT OFF

SEEK ALLTRIM(oGlobal.prop1)   <--- works in Command Window not in Form Code (because of lost index)
MESSAGEBOX(FOUND())           <--- ditto

Why is it so ?

Appreciate any advice

John Fox


Sydney, Australia
 
CORRECTION !!! (apologies for misrepresentation)

It does NOT lose the index... But the SEEK fails in the FORM.... (and I know that the table contains the correct data.. so SEEK should work)

So I still don't get it... It reports FOUND() = .T. in Command

and .F. in Form

Grrrrr,,,

Will keep Checking for errors... but I have been at this for hours


JF


Sydney, Australia
 
Hold Fire for the moment Northern Hemisphere

I am trying several things and getting SOME improvement..

Let me gather more behaviour info ...Cheers

JF

Sydney, Australia
 
Solved.. or at least IT IS NOW WORKING...

I moved it all to the Form.Init

I wonder if it was because I put it in the TextBox.Init where I had set the control source to the same field.

Apologies for bothering the readers..

JF

Sydney, Australia
 
You never explained when oGlobal.prop1 is set.

You may have a misunderstanding about event order. Form.Init is not the first thing to run, if you start a form. And I'm not talking about Load, of course that's earlier, but also all control inits are before form init. Why? The form init has to be able to address all controls of the form. That's only possible, when they exist and therefore all their inits then already have run.

You did display oGlobal.prop1 and saw it's right. It could't be, if SEEK didn't find it. I think you were already in a tunnel vision not seeing the value can't be found.

Bye, Olaf.

 

Thanks Olaf (I read your Post)

I thought I had it solved BUT I AM STILL PERPLEXED.. because it worked ONCE !!!

By the way --- oGlobal.prop1 is universally available and works...( Young Prof Gagnon gave me that code ages ago)


OK so I put this code in the first form.... before calling second form

Code:
MESSAGEBOX(DBF())             &&(response is correct)
MESSAGEBOX(oGlobal.prop1)     &&(response is correct)
SEEK oglobal.prop1
MESSAGEBOX(FOUND())           && Works reports .T. ie response is correct)

*** check again *****

SELECT patient_episodes       &&(response is correct)
SET ORDER TO pt_episode       &&(response is correct)

MESSAGEBOX(DBF())             &&(response is correct)
MESSAGEBOX(cdx(1))            &&(response is correct)

I put EXACTLY the same code in the Init (and I also tried in the Load) of the second Form and

Code:
MESSAGEBOX(DBF())             &&(response is correct)
MESSAGEBOX(oGlobal.prop1)     &&(response is correct)
SEEK oglobal.prop1
MESSAGEBOX(FOUND())          [B] && DOES NOT WORK. It reports .F. ie response is incorrect)[/B]

*** check again *****

SELECT patient_episodes       &&(response is correct)
SET ORDER TO pt_episode       &&(response is correct)

MESSAGEBOX(DBF())             &&(response is correct)
MESSAGEBOX(cdx(1))            &&(response is correct)

How can that be ???
JF

..WAIT...ALSO NOTED

The Index in the Database container is called PT_EPISODES (in both databases)
The CDX(1) is reporting PATIENT_EPISODES
The DBF() is called PATIENT_EPISODES
Why should that be ???

More perplexed than ever !!!



Sydney, Australia
 
Good morning, John.

What do you mean by "the index in the database"? The dabase container does not show index files. It shows index tags within tables.

Is your CDX a structural index or a "standard" compound index? A structural index always has the same name as the DBF, and resides in the same directory. It is opened automatically when you open the table. If you have any other index for that table, it won't come into force unless you open it explicitly with SET INDEX (not SET ORDER) or with USE .... INDEX.

Is it possible you have more than one CDX?

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Mike,

I had a look ...
There is only ONE patient_episodes.cdx in the same directory... It has the same name as the dbf() so I guess that makes it a STRUCTURED CDX

Mmmm That explains why CDX(1) comes up at Patient_Episodes (same as DBF())

BUT WHY IS THAT SEEK WORKS (Found() = .T.) IN ONE FORM
AND YET WITH EXACTLY THE SAME CODE IN ANOTHER SEEK (Found() = .F.) DOES NOT !!!
Even though the CDX and the DBF are the same !


I am clearly missing something

Will experiment some more... onward and downward...

J

Sydney, Australia
 
SEEK uses the index you set by SET ORDER, what is SET('ORDER')?

You speak of two "databases", I think you use the legacy term for a dbf. Get used to modern terms, this is a table, not a database.
If you have two DBFs with bothh same index, then either data differs (one DBF doesn't contain the data) or your active index differs. CDX(1) is tag 1 and is not automagically used.
SEEK can make use of an index you set by SET ORDER or SET INDEX, but you have to set it before using SEEK.

Bye, Olaf.
 
Correction CDX(1) returns the CDX file name, which besides dbf extension is the same as the table name. A CDX is not a single index like IDX is, it's a file containing several index TAGs.
You have to set order to a tag name.

Overall prerrequisites of using SEEK command:
1. Select the table you want to seek in
2. Set the order (index tag name). In case of CDX use SET ORDER TO TAG tagname.

Then SEEK will use that index tag.

Bye, Olaf.
 
Read below.... I found a correction...

Olaf

You are right AND
I did as recommended... Added the correct TAGS
But I got the EXACT SAME BEHAVIOUR.. it works in Command ... Fails in the FORM


I wondered could I have too many 'things' open
There is a PageFrame with 7 pages of data input
I couldn't imagine that would overload old VFP
SO I MADE A BRAND NEW BARE FORM

With nothing else on it ... and it WORKED

BUT ONLY FOR A MINUTE

Background:

In my original (the first) form (ie the one that finds the patient) I create THREE FORM LEVEL PROPERTIES
CLASTNAME LCLASTNAME and LNWHOLELEN

I suppose I should not have done that ... but I did and it works..

Now the BARE FORM works BUT with a pesky message saying PROPERTY CLASTNAME NOT FOUND..

So I ADD BACK THOSE PROPERTIES INTO the Bare Form .. AND THEN THE Found() FAILS... Bugger !!

REMOVE THEM AGAIN and I get the message saying PROPERTY CLASTNAME NOT FOUND.. (Again)

So I hit "ignore" and the little Bare Form WORKS WITH Found() = .T.

Then I did the same with my SECOND (7 PAGE) FORM.. it works with the same Error which I ignore and

AND The Grids work
AND the Second Form works

BRILLIANT

So ... now the question is How do I get rid of the pesky message saying "PROPERTY CLASTNAME NOT FOUND".
I don't even use them in this form !!!
I presume that they are a hangover from the first

Foxy




Sydney, Australia
 
OK so I have solved that last issue too...

In Form 1 it uses a command SET FILTER TO "Blah Blah" where "Blah Blah" includes those accursed FORM PROPERTIES that I described above.

SO to FIX IT ..... Immediately BEFORE I LEAVE Form one and call FORM two with that DO FORM (Second Form)...

I have to clear the FILTER

With a single SET FILTER TO
Immediately before the DO FORM (Second Form)

NOW EVERYTHING WORKS

OK SO thanks for your assistance

I apologize BUT there is no way you could have guessed that I was that incompetent

And the moral of the story (for me) is AVOID FORM PROPERTIES


Cheers

Bed Time

Sydney, Australia
 
And the moral of the story (for me) is AVOID FORM PROPERTIES

No, no, no. That's not a good reason for avoiding the use of form properties. It's like avoiding a word processor because your novel was rejected by the publisher.

If there's a moral to this story, it is to understand data sessions.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Mike...

Mate.. for me at my age... It is WHATEVER WORKS...

I make best endeavours to understand data sessions and TAGS and etc

Thanks for your omniscient assistance...

I have another quick question (separate tip reqd) ... I will post it before I crash.. Work starts in the morrow.

J

Sydney, Australia
 
Whew!

Just a couple of comments:

1. Don't use SET FILTER. It's as legacy as they come and has behaviors you may not be expecting.
2. Instead of SEEK use Seek(value,'tag'), where the 2nd parameter is the specific index tag to use for the seek. Then you don't have to worry about SET ORDER.

Just some things to think about going forward.
 
It's not the form properties, that you got wrong, but the public scope of a filter. a Filter is a property of a workarea, not of the form. a filter using THISFORM only works partly, a filter condition using _screen.activeform will mean every form will need to have that property for the filter to continue to work. The way to work with filters is to put the condition into a string and use macro substitution, so the filter does not depend on any object or property at all. It will always cause head scratching, if you mix things, like set filter and SEEK. Like GO you can go to records not in the filter.

But the most important thing is, if you use a data session in many forms, as you seem, you need to know what you're doing, eg closing all tables together with a form then isn't simple, if other forms still need them. Private datasession mean more work with reopening tables many times, but you keep the dependencies lower and can easier dispose.

Bye, Olaf.

 
Oh God !
Thank I am not in the same time zone... You would slay me

Olaf.. you are always right... the correct way is that of structural rigour...

ie the correct way is the correct way

BUT the problem is my Eng Degree is ~40 years ago and (as you know) Orthopaedic Surgery is pretty much making it up as you go along and that is what I do best... (IE it is easier to make it up as you go along than being using rigorous application of VFP maxims) I try not to cause to much grief to the experts.. and try to solve my own problems/// (and btw I wasn't a very good engineer either)

Actually, I do this programming for fun... its my practice software...

My wonderful FPD2.6 program which has NEVER EVER failed me in 20 + years is no longer supported by those evil 64 bit machines... SO I am forced to make something work.

Cheers...

PS if you break a bone post a query on Tek-Tips... I will probably have a good idea what to do.

JF

Latest project is hssaustralia.com.au opening Feb 15

Sydney, Australia
 
Hi Dan

I like the Seek() option
Will try it
Check out my post to Olaf

Cheers
J

FPD2.6 Legacy Human
Sydney, Australia
 
> You would slay me
> my Eng Degree is ~40 years ago
> I try not to cause to much grief to the experts

I don't know why you feel Dan and my advice is the wrath of the professional developers. We know you are no expert in this field and therefore we give you advice to avoid whole areas of possible problems, as you never will get into every detail level.

For example what Dan says about filters: Don't use SET FILTER

You already identified your problem being a set filter and now you think SEEK() as function is solving the problem you had with SEEK as command? I hope not, I hope you simply take that as better way of seeking for future reference. You still don't get that the SEEK was never the culprit, the SEEK changed record and that indirectly causes the workarea to apply/check its filter condition you set with SET FILTER. The condition referencing a property not existing anymore then causes an error, that's at least what you said. Nobody can see that and I'm not saying you should have given that fact, you couldn't know it plays a role and we also didn't get the faint idea a filter could play a role here.

That's what is a hard problem you can only solve getting hands on and knowing what influences to expect. There always are many things on top of the explicit command you execute in the debugger, not only events. Keeping hands off SET FILTER helps to avoid that. My advice differs in making a stable filter not depending on any properties shown, but I gave other advice to avoid shared data sessions. Indeed they also can solve your problem here, as you can simply position on a record before changing forms instead.

But in general avoiding things you don't have the time to fully understand all implications is good advice. Explaining why would cost too much time on both sides and so simply take that advice, instead of acting like you do, that would be my wish. You take the perspective your code works in general and you know you make some cludge, but your goal is not elegant code, it's sufficient it works. That's a pitty, but I'm ok with it, elegant code is seldom anyway in real world situations, as we also don't have infinite budget and time. But what is really not working is asking for a solution working in all cases. Most problems can only be identified by yourself in the end.

Taking such advices as don't use that are very limiting yourself. We indeed do that on ourselves, too. VFP has grown concepts, that don't work together, there are old and modern parts of the language and prioritizing the downward compatibility means you can do things, that don't make sense an more. I'd not put FILTERs in there, but the moment you switch to querying data instead of putting tables in form data environments, you should also stop using filters, you have a where clause to use, then. Anyway, using the old way means you lack old knowledge about when and how filters are applied. Not only in the moment you set them, also in the moment the record pointer moves, but also not in any case. I don't expect this detail knowledge from you, I instead gave advice what to do, to make the filter condition independent on anything but the table/workarea you filter.

If we'd always explain in detail why you should do something or avoid something else, you'd perhaps get a better feeling about it, but do you really have the time to become an expert in VFP? You're showing that you're forgetting things or getting them wrong. We'd need much more time to arrive at things you can anchor the new knowledge at. Still we try to give you easy to follow rules of thumb, is that so bad? It doesn't mean you have to go in and retro fit it and start from scratch, as you have to change too much, just try out new less problematic ways suggested in the future.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top