Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.
CURVAL()
, OLDVAL()
These functions give you access to the extra buffers that FoxPro maintains for buffered records and tables. CURVAL()
tells you the current value of a field on disk, while OLDVAL()
tells you the value a field had the last time you retrieved it from disk.
uValue = CURVAL( cExpr [ , cAlias | nWorkArea ] )
uValue = OLDVAL( cExpr [ , cAlias | nWorkArea ] )
These two functions let you figure out what’s going on so you can save your changes without clobbering somebody else’s. For tables, CURVAL()
keeps its finger on the pulse of the actual data that’s sitting on the disk. For views, CURVAL()
contains the data value sitting in the buffers—you may need to REFRESH()
the view before CURVAL()
is up to date. OLDVAL()
looks at a copy of the data that’s originally created when you open the table buffered, and gets updated whenever you issue TableUpdate()
or TableRevert()
.
You can use these functions in two ways, which correspond to the optimistic and pessimistic views of the world. You can try to TableUpdate()
and, if it fails, combine GETFLDSTATE()
with these two to figure out what items are causing the failure. Or, if your glass is half empty, you can go through the data first and use these functions to identify and resolve conflicts, then update the table. The catch we see with this second technique is that, unless you explicitly lock the record, another user could still make changes to the data after you had checked it but before you committed your changes. This means that followers of this second technique would still need to incorporate the code of the first method, above. Too much work for us, we think.
You're not restricted to passing a single field name to these functions. They actually can return information about an expression. Whatever you pass, note that they expect a character string, not a name. |
VFP 7 Service Pack 1 fixes a bug that can cause data corruption under very obscure circumstances (in fact, we heard of this only when we saw it on the list of bugs fixed in the service pack): Calling OLDVAL() in a transaction involving at least 100 appended records when the internal name table is nearly full (that is, you've created a very large number of variables or objects). |
USE Employee
SET MULTILOCKS ON
? CURSORSETPROP("Buffering", 3)
* Make some changes to a record.
* Now see what happened to Last_Name field.
* Note that there are two cases which are NOT mutually exclusive.
IF Last_Name <> OLDVAL("Last_Name")
WAIT WINDOW "You changed the last name"
ENDIF
IF OLDVAL("Last_Name") <> CURVAL("Last_Name")
WAIT WINDOW "Someone else changed last name"
ENDIF
Buffering, CursorSetProp(), GetFldState(), TableRevert(), TableUpdate()