Hi, I missed entire conversation, but the problem "Validation row movement in a grid" is very interesting to me.
Pleas see my decision of the problem.
I am interested in any comments.
Here table is in TABLE BUFFERING mode (not row buffering). User enters data directly in the grid. We want to save or restore changed data when user moves from current row to other row.
I have placed 4 new properties to the my base grid class:
BeforeRowCheck - if to check in this grid changing status and validate movement
BeforeRowChanged - flag
BeforeRow, BeforeColumn - to activate old sell, if needs. It is better,
in my opinion, compared to use of GO.
In BeforeRowColChange:
This.BeforeRow = This.ActiveRow
This.BeforeColumn = This.ActiveColumn
IF This.BeforeRowCheck
IF ThisForm.lAppendingMode
* while adding - not to check - unexpected message
ELSE
This.BeforeRowChanged = IsNewOrChanged( This.RecordSource )
IF !This.BeforeRowChanged AND This.ActiveColumn>0
* if current control is in process of changing
LOCAL lcCurrentControl
lcCurrentControl = This.Columns[This.ActiveColumn].CurrentControl
This.BeforeRowChanged = ;
This.Columns[This.ActiveColumn].&lcCurrentControl..Value <> ;
EVALUATE(This.Columns[This.ActiveColumn].&lcCurrentControl..ControlSource)
ENDIF
ENDIF
ENDIF
In AfterRowColChange:
IF This.BeforeRowCheck AND This.BeforeRowChanged ;
AND This.BeforeRow>0 AND This.BeforeRow<>This.ActiveRow
* THIS WORKS ONLY IF Table Buffering is ON (5) (nor Row Buffering).
LOCAL lnAnswer, llRetBeforeRow
lnAnswer = ThisForm.AskToSave(.t.)
DO CASE
CASE m.lnAnswer = IDCANCEL
llRetBeforeRow = .t.
CASE m.lnAnswer = IDYES
* second par is not to refresh the form in Save
llRetBeforeRow = !ThisForm.Save( 0, .t.)
CASE m.lnAnswer = IDNO
* second par is not to refresh the form in Restore
llRetBeforeRow = !Thisform.Restore(.t.)
ENDCASE
IF m.llRetBeforeRow
This.ActivateCell( This.BeforeRow, This.BeforeColumn)
ENDIF
ENDIF
Additional functions:
***
* Return .t. if user has added a new record or changed current or new record
*
FUNCTION IsNewOrChanged( tcAlias )
IF EMPTY(m.tcAlias)
tcAlias = ALIAS()
ENDIF
IF EMPTY(m.tcAlias) OR CURSORGETPROP("Buffering",m.tcAlias)=1
RETURN .f.
ENDIF
LOCAL lcFldState
lcFldState = GETFLDSTATE( -1, m.tcAlias)
RETURN !ISNULL(m.lcFldState) AND ("2"$m.lcFldState OR "3"$m.lcFldState OR "4"$m.lcFldState)