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

getfldstate,getnextmodified and checking for changed data

Status
Not open for further replies.

arielap

Technical User
Aug 2, 2003
71
GB
Trying to sort out why setting a 'file has changed maker' is unpredictable in this app. (VFP7, XP)

The files are standalone DBFs and changes may be made in either single record forms or grids. There are too many fields for simple 'if this val <> oldval()' and I've been using getfldstate and/or getnextmodified

With getfldstate(-1) the problem seems to be that just passing through a field with a Valid sets a 2 in the string, whether the content is changed on not.
(eg code, in Return button of single record form :
needsbak= iif('2 '$ getfldstate(-1),.t.,f.)

With a grid, getnextmodified still returns 0 after records have been changed.
(code in form's Return click is ;
if getnextmodified(0,'rec_cyt',.T.) > 0
needsbak=.t.

What am I missing please - ?



 
Hi,

Dont know what you are missing, but I am missing a clear cut question. What is exactly your problem? And why do you think you have 2 many reccords to do a this.val<>old.val?

Regards,

Jockey(2)
 
Problem - how to determine if any data in a table has changed.

Many fields have valids and both the apparently useful functions give positive numbers (ifswim) even if no changes aree made - This is a keyboard intensive app & the users skip over fields with the Enter key.

>> And why do you think you have 2 many reccords to do a this.val<>old.val?<<

I wanted a simple check for changes just in the 'return' code for each section. I use this.val<>old.val for files with only a few fields needing validation but others have up to about 80 fields in a table needing this - and it's a slow network.
 
Hi,

use te debugger and set a breakpoint on this.val<>old.val

Regards,

Jockey(2)
 
Arielap,

Sorry, but your problem is not still not clear. In particular, what do you mean by this.val and old.val?

If you want a simple test to see if any data in a record has been edited (since it was read into the buffer), the following will do it:

Code:
llChanged = .F.
FOR lnI = 1 TO FCOUNT()
  lcFieldName = FIELD(lnI)
  IF OLDVAL(lcFieldName) <> CURVAL(lcFieldName)
    llChanged = .T.
    EXIT
  ENDIF
ENDFOR

After this code has run, llChanged will be .T. if any of the fields has been edited.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
>>this.val and old.val?<<

sorry -shorthand.
this.val(ue) - current value in a field, ie =curval()
oldval(same object) - value when last read off disk

I've been using more-or-less your example code, but getfldstate &/or getnextmodified seemed like a more efficient way of checking for changed data than trundling
through all fields.
But apparently not so :(

thanks anyway

.

 
Arielap,

getfldstate &/or getnextmodified seemed like a more efficient way of checking for changed data than trundling
through all fields.

It's not a direct comparison. GETNEXTMODIFIED() loops through all the records in the buffer, looking for any type of modification. It considers a record to be modified if any field has changed, and also if a field has changed and then been changed back again (which the code I showed you doesn't do), and also if the deletion status has changed.

The code I showed you, and also GETFLDSTATE(), operate on the current record. You can use them with either table or row buffering, whereas GETNEXTMODIFIED() only works with table buffering. GETFLDSTATE() also detects changes to the deletion status.

As for efficiency, any difference is likely to be pretty small. It's true that my code requires you to loop through the fields until you detect a change, but that's all done in memory and so should be pretty fast. In any case, with GETFLDSTATE() you might need to loop through the digits in the returned value (depending on what you are trying to achieve). GETNEXTMODIFIED() requires you to loop through the records in the buffer.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
thanks - that's clarified things a bit .

I tried getfldstate to set a backup marker, bmark, in the 'Return to Menu'' code for single records -:
bmark=IIF('2' $ getfldstate(-1),.t.,.f.)
but it always returns .t. even if no changes made.

These records have lots of fields needing valid methods, and this seems to be the trigger. In a test DBF with no fields needing checks, Getfldstate(-1) worked as hoped.

So I've given up & gone back to looping through all fields.


 

So I've given up & gone back to looping through all fields.

I think that's a good idea. I really don't think you'll find the performance anything to worry about.

Just a couple more points to keep in mind. First, you can't use this technique with a newly-inserted record. That's because OLDVAL() will always return NULL. If you know the record is a new one, just test for a non-blank value in each of the fields.

Also, make sure you don't perform the test on General fields. OLDVAL() generates a run-time error on a General field.

Apart from that, it should work fine.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
>>First, you can't use this technique with a newly-inserted record<<.

Thanks - yes I did know that (I just set the backup marker .t. on leaving a new record).

------
I've just met another oddity - don't know if I'm doing something stupid or not but -:

This app. includes a simple form so that the section head
(only) can change his staff's password data.
It just restores from a .MEM file into a cursor -:
RESTORE FROM TTPWS.mem && an array PWS(n,3)
CREATE CURSOR TMP (NAME C (30),INITS C (3), PW C (10))
APPE FROM ARRAY PWS
then copies the edited cursor to an array -:
COPY TO ARRAY PWS (having cleared the original pws array)
& saves that back to the original <name>.mem.

No problem unless either -:
a record in the cursor is deleted
or a field is blanked out
or I add 'for not empty(name)' to the copy to array line.

when the copied array items are now all .F.
(fwiw the identical code worked for years in Fox2.6)





 
Areilap,

Off-hand, I can't see any reason for that. However, I strongly recommend you to start a new thread for this question, and give the thread a title that relates to this new problem. This will alert other forum members to the nature of the preoblem, and will increase your chance of getting a good answer.

Keeping questions separate in this way also helps other people who might have a similar problem. It also generally helps keep the forum un-cluttered.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top