The only thing I say is you can't determine the checkbox value, which will be stored to the logical if allowed by Valid by reading THIS.Value within a checkbox interactivechange event. The table.logicalfield value still is the old one. Storage of a controlsource does NOT happen within InteractiveChange, what changes with each keystroke or click or other interactive change triggering the event is a controls value property. programmaic changes are also not triggering the interactivechange event, that's why Mike asks about other sources of change.
I think you assume reading the underlying value gives you the current value, but the most current value of a control always is its value property, not it's controlsource. If that wasn't the case and every interaction would already change the underlying field, what would be the point of the valid event returning 0 or .F.?
Also note, whenever you verify what I say by looking into a browse window of the underlying table, you cause the valid to run when you click on the browse and thus already store the value. This is almost as they say in physics an observer falsifying the experimental result by being there or not.
In very many cases it is wise to look at the recordsource of the grid instead of grid control, especially when looking at other rows than the current one, as the grid controls only visually are copied per row, the column controls only are actively working on the current row. But the most current value the user sees from a control and your code also can read is the control.value, also outside grids, that's just naturally from the meaning of events.
So whenever you want to react to the user control showing and hiding this with checking and unchecking a checkbox, you look into the checkbox.value, not into the checkbox controlsource, that's still having the old value no matter what buffer mode you use or not.
Put this and only this into a checkbox interactive change bound to a logical field of a table via controlsource:
Code:
MESSAGEBOX("This.VALUE: "+TRANSFORM(This.Value)+CHR(13)+"crsLogicl.lField:"+TRANSFORM(EVALUATE(This.Controlsource)))
You will see they always will be inverse, the checkbox VALUE will be what you expect the value to become from the click, the underlying table field still has its old value.
Notice, what is confusing is, visually the checkbox does NOT yet show its VALUE, this may be partly because of the modal messagebox not yet allowing the checkbox to refresh, but more likely is because your event code now may interfere and change the value. Not so useful within a checkbox only toggling between two values, but more generally waiting with the visual display of the interactively changed value until this event is through saves to refresh the visual appearance twice in case code overrides the value.
When you said:
tkee said:
When it is, the checkbox still shows as checked even though the underlying value has been changed
Did you actually verify that with such a messagebox? Then you now know why that shows two differing values. It's not because the controlsoruce has a bug, it's because you expect it to update eaerlier than it does.
Is that now more clear, perhaps? Generally, I know developers (even experts sometimes) expect a table gets the new value with each single interactive change, at least in case of unbuffered tables where there is no buffering going on at all, but that's not the case. The control only updates its controlsource when the valid events occurred and allowed the update.
And as a sidenote: A controls display also doesn't change it's display value when the controlsource changes its value, that's not triggering a cascading event in all bound controls, it's when a control gets focus it refreshes, or when you do Thisform.Refresh(). You can verify the latter, simply put Thisform.Refresh() into the checkbox interactivechange event, and since it rereads the controlsource value, it then will become readonly/disabled in a very subtle way.
Bye, Olaf.