The cursor is named revalquery, so you bind to "revalquery.field"
If you query before calling a form, the form has to work in the same datasession, if the form has a private datasession you have no access to the query result. Therefore the norm is doing a query in form init or even in the dataenvironment code, not in the caller form. The aspect of a form being self contained, working on its own, plays a role here. What the form needs as input then only is the pinNumber.
T17Rax said:
The substr() functions doesn't appear to agree on control binding.
You still don't gripe what you're doing here. You copy a field substring into a variable. You don't store the expression to the variable, you store the result of the expression to the variable.
This causes no binding whatsover. Binding is done via controlsource only. Nothing in these lines has a controlsource. Variables are nothing but the name for a value you store in them, in this case you do this very literally via the STORE command. The expressions used take a substring of a field. Just because the field is the source of a value also doesn't cause any binding. A field also is not a control having a controlsource, that's exclusive to controls. If you want to forward the expressions you would need to store "substr(coins,1,2)" to tenPence for example, to set the tenPence variable to the expression. Passing that in also does nothing at first, you then would need to set some controls controlsource property to tenPence (and not to "tenPence", that would bind to the variable and show the expression in the textbox, not its value).
You don't show what happens to the parameters passed in, so it's not clear what happens and even passing in the expression instead of its value could still not cause the binding you want. I'm quite sure it wouldn't work, because assume the current situation would result in a string like "10", setting a controls controlsource to "10" wouldn't work, it would error. In the best case you display 10, as eval("10") is 10. A controlsource has to be an expression, typically a fieldname or tablename.fieldname to be twoway, more complex expressions need to be put into brackets to work or cause "... is not a variable" error.
So besides passing in the wrong thing, even if you mend that and mend what you do in init it's a waste, as this could be done at design time once and for all. You only would need to pass in the expressions to which controls should bind to, if your form would be very general purpose for many different data sources. Dynamic forms like that are a thing I would rather avoid, this is not elegant, this is bound to be halfway dynamic enough to do a few things and then get stuck if one time you need further controls and other times not. Form design goes hand in hand with data design and table changes lead to form changes and vice versa, as the database is the persistence of data and the form is its representation and human interface to data. Don't try to cover generic cases here you can use to display any data just by passing expressions in. That may sound like a universally working thing, but you lose control of it- no pun intended here.
Last not least, even when going that route, expressions with functions don't allow two way binding, your controls can only display the expression results, you can't bind one textbox to the leftmost character of one field and the next control to the next two chars. The simple reason is while you can [tt]STORE field TO control.value[/tt] and VFP can do the inverse [tt]REPLACE field WITH control.value[/tt] VFP couldn't apply the same simplistic ionversion [tt]REPLACE substring(field,1) WITH control.value[/tt]. What would be needed to write back the changed single character is [tt]REPLACE field WITH control.value+substr(field,2)[/tt]. There are other REPLACE command that would do that, but surely not the simple swap of value and controlsource expression. Surely there is no simple logic turning your thinking into reality on a sub field level. You expect too much intelligence of the mapping here.
To be clear, the replace statements are not what VFP executes behind the scenes, but you could imagine that happening when a control reads a value for display and write back its value in the valid event. The controlsource can only work in both read and write directiony for controlsource expressions that can be put into both the [tt]STORE exression To control.value[/tt] and [tt]REPLACE expression WITh control.value[/tt] commands. The REPLACE is the limiting facotr, as it can only address fields. It's not the full truth as you can bind to variables, you can bind to "tenPence" and that would mean the write back is done by [tt]STORE control.value TO tenpence[/tt].
And then finally, if you bind to a cursor, that's readonly binding anyway, even if it wouldn't be binding to an expression it's still one way. If you want to save back edited changes you need to bind to something updatable, and that should either be the DBF itself or an updatable cursor, which writed back to the DBF. There are half solutions only enabling the control to write but not write back to the DBF, eg querying INTO CURSOR somecursor READWRITE.
You're far off from what you want in my interpretation, unless you only want to display something.
Bye, Olaf.