*************************************************************************** *!* Method: frmChild.BuildRevertCursor *!* Purpose: Builds revert cursor. SELECT * FROM... does not work *!* because SELECT draws from the base table. *!* Author: bxk 09.11.02 *!* Parameters: tcSource, cursor name used as source *!* tcDest, cursor name to be built *!* Returns: *************************************************************************** LPARAMETERS tcSource, tcDest PRIVATE ALL LIKE m.* && for the SCATTER MEMVAR LOCAL laFields, lnRows LOCAL lcField, lj, lnFields, lcColumn DIMENSION laFields[1,1] STORE 0 TO lnRows, lj, lnFields STORE "" TO laFields, lcField, lcColumn ASSERT PCOUNT() = 2 ; MESSAGE 'BuildRevertCursor() REQUIRES both Source Cursor Name, and Destination Name!' AFIELDS(laFields, tcSource) lnRows = ALEN(laFields, 1) + 1 lnCols = ALEN(laFields, 2) *!* Add column for fieldstate string DIMENSION laFields[lnRows, lnCols] laFields[lnRows, 1] = 'CFLDSTATESTR' lafields[lnRows, 2] = 'M' lafields[lnRows, 3] = 4 lafields[lnRows, 4] = 0 lafields[lnRows, 5] = .F. lafields[lnRows, 6] = .F. lafields[lnRows, 7] = "" lafields[lnRows, 8] = "" lafields[lnRows, 9] = "" lafields[lnRows, 10] = "" lafields[lnRows, 11] = "" lafields[lnRows, 12] = "" lafields[lnRows, 13] = "" lafields[lnRows, 14] = "" lafields[lnRows, 15] = "" lafields[lnRows, 16] = "" *!* clear defaults FOR li = 1 TO lnRows laFields[li, 9] = "" ENDFOR CREATE CURSOR (tcDest) FROM ARRAY laFields SELECT (tcSource) SCAN SCATTER MEMVAR MEMO m.cFldStateStr = GETFLDSTATE(-1, tcSource) INSERT INTO (tcDest) FROM MEMVAR ENDSCAN GO TOP IN (tcSource) *!* Update array of Revert Cursor names WITH THISFORM lnRows = ALEN(.aRevertCursors, 1) + 1 DIMENSION .aRevertCursors[lnRows, 2] .aRevertCursors[lnRows, 1] = tcSource .aRevertCursors[lnRows, 2] = tcDest ENDWITH RETURN *************************************************************************** *!* Method: frmChild.RestoreFromRevert *!* Purpose: Loop through RevertCursor array restoring views to before *!* form launch state. *!* Author: bxk 09.11.02 *!* Parameters: *!* Returns: *************************************************************************** LOCAL lnRows, lcView, lcCursor, lcLocate, loRevertlcFldState, lnFields, ; li, lj, laFields[1], lcField, lcColumn STORE 0 TO lnRows, lnFields, li, lj STORE "" TO lcView, lcCursor, lcLocate, lcFldState, lcField, lcColumn STORE .NULL. TO loRevert WITH THISFORM lnRows = ALEN(.aRevertCursors, 1) FOR li = 1 TO lnRows lcView = .aRevertCursors[li, 1] lcCursor = .aRevertCursors[li, 2] IF !EMPTY(lcView) && 02.06.03 bxk check for empty rows lcLocate = TRIM(lcView) + '.iRecID' SELECT (lcView) GO TOP IN (lcView) DO WHILE !EOF(lcView) SELECT (lcCursor) LOCATE FOR iRecID = EVALUATE(lcLocate) IF FOUND(lcCursor) SCATTER NAME loRevert MEMO SELECT (lcView) GATHER NAME loRevert FIELDS EXCEPT cFldStateStr lcFldState = ALLTRIM(loRevert.cFldStateStr) RestoreFldState(lcFldState, lcView) SKIP 1 IN (lcView) ELSE *!* newly added record, OK to revert lnVal = TABLEREVERT(.F., lcView) IF lnVal = 0 && Tablerevert was NOT successful SKIP 1 IN (lcView) ENDIF ENDIF ENDDO GO TOP IN (lcView) USE IN SELECT(lcCursor) ENDIF ENDFOR ENDWITH STORE .NULL. TO loRevert RETURN *************************************************************************** *!* Method: RestoreFldState *!* Purpose: Set buffer status for a record to passed value *!* Author: bxk 02.20.03 *!* Parameters: tcFldState - string created by call to GETFLDSTATE(-1, tcAlias) *!* tcAlias - alias of buffered record to process *!* Returns: *!* Modifications: *************************************************************************** LPARAMETERS tcFldState, tcAlias LOCAL li, lnVal, lnBufferMode STORE 0 TO li, lnVal, lnBufferMode lnBufferMode = CURSORGETPROP('buffering', tcAlias) ASSERT lnBufferMode > 1 ; MESSAGE 'RestoreFldState ONLY works on Buffered Views' IF lnBufferMode < 2 *!* Bail if buffering not enabled RETURN .F. ENDIF tcFldState = ALLTRIM(tcFldState) ASSERT LEN(tcFldState) = LEN(GETFLDSTATE(-1, tcAlias)) ; MESSAGE 'RestoreFldState - structure of tcAlias does NOT match tcFldState' IF LEN(tcFldState) # LEN(GETFLDSTATE(-1, tcAlias)) RETURN .F. ENDIF *!* start at 0 to get Delete flag FOR li = 0 TO LEN(tcFldState) - 1 lnVal = VAL(SUBSTR(tcFldState, li + 1, 1)) SETFLDSTATE(li, lnVal, tcAlias) ENDFOR RETURN *************************************************************************** *!* Method: frmChild.ProcessCancel *!* Purpose: *!* Author: bxk 11.09.01 *!* Parameters: *!* Returns: *!* Modifications: *************************************************************************** LPARAMETERS tlNoAsk WITH THIS .HIDE() .RestoreFromRevert() .RELEASE() ENDWITH RETURNIn an instance of this form, we call BuildRevertCursor as needed...
*!* Here is instance code from a form.Init... THISFORM.BuildRevertCursor('hcchrgadjudeditview', 'curRevertchrgadjud') THISFORM.BuildRevertCursor('hcchrgadjuseditview', 'curRevertchrgadjus')'Save' is only called from the Parent form. The 'Cancel' button simply calls process cancel. The child forms use the Parent form's datasession.