The same code better formatted:


Code:
        Object oTimer is a DFTimer
        
            Set Auto_Activate_State to True
            
            Set Timeout to 100 // fire often
            Property Integer piRow // remember last row we worked on
            
            Procedure OnTimer Integer iwParam Integer ilParam
                Forward Send OnTimer iwParam ilParam
                RowID riID riOldId
                Integer iRow iColumn iCurrent hoNav
                Variant vNav
                Boolean bOk
                tDataSourceRow[] DataSource
                Move 0 to iColumn
                
                If (OPERATION_MODE=0) Begin // don't do this if the user is currently in a DDO operation
                    Get piRow to iRow
                    // get the raw data
                    Get pDataSource of (phoDataSource(oDbCJGrid1)) to DataSource
                    // make sure our last row count isn't out-of-bounds
                    If (SizeOfArray(DataSource)<=iRow) Move 0 to iRow // start from top again
                    If (SizeOfArray(DataSource)>iRow) Begin // make sure it has at least one row
                        // refind the row and see if the data changed. hold the current rowid so we can reset it
                        Move DataSource[iRow].riID to riID
                        Move (GetRowID(SOMETABLE.File_Number)) to riOldId
                        
                        Clear SOMETABLE
                        Move (FindByRowId(SOMETABLE.File_Number, riID)) to bOk
                        If (SOMETABLE.SOMEFIELD<>DataSource[iRow].sValue[iColumn] ) Begin
                            Move SOMETABLE.SOMEFIELD to DataSource[iRow].sValue[iColumn]
                            // Move the datasource back
                            Set pDataSource of (phoDataSource(oDbCJGrid1)) to DataSource
                            // Here is the magic. We get the current row and then move to itself.
                            // The nice part is that this doesn't do any DDO operations, so your
                            // data is intact AND you get a refresh of the list.
                            Get GetFocusedRowIndex of oDbCJGrid1 to iCurrent
                            Get phoReportNavigator of oDbCJGrid1 to hoNav
                            Get ComNavigator of oDbCJGrid1 to vNav
                            Set pvComObject of honav to vNav
                            Send ComMoveToRow of hoNav iCurrent False False
                        End
                        // Reset record buffer
                        Move (FindByRowId(INVOICE.File_Number, riOldId)) to bO
                        Increment iRow
                    End
                    Set piRow to iRow
                End
            End_Procedure // OnTimer
        End_Object // oTimer