The following canChange and onChange event handlers work together to record all change attempts to a field (even if the modified row is abandoned later). An audit table is open in another query on the form.

function Field_canChange( )

this.initValue = this.value // Save initial value 

return true // Always allow change 

function Field_onChange( )

if not this.initValue == this.value // Perform exact comparison 

local r // Assign reference to audit rowset 

r = this.parent.parent.parent.parent.audit1.rowset 

if r.beginAppend( ) 

r.fields[ "Field" ].value := this.fieldName 

r.fields[ "Old value" ].value := this.initValue 

r.fields[ "New value" ].value := this.value 

r.fields[ "User" ].value := id( ) 

r.save( ) 

endif 

endif