Testing an automated process in Progress version 9 character base.
Needing to dynamically compare records and was expecting to be able to use coding to dynamically compare the fields but all I am getting is the field names
not the data ... as a work around I used a similar variation of this code to generate a program module with all the fields listed sequentially. Just wondering if there is an easier way to do this. All thoughts welcome.
/* drc.p
table
recid1
recid2
*/
DEFINE BUFFER drc1 FOR .
DEFINE BUFFER drc2 FOR .
DEFINE VARIABLE inI AS INTEGER NO-UNDO.
DEFINE VARIABLE chF1 AS CHARACTER NO-UNDO.
DEFINE VARIABLE chF2 AS CHARACTER NO-UNDO.
DEFINE VARIABLE chV1 AS CHARACTER NO-UNDO.
DEFINE VARIABLE chV2 AS CHARACTER NO-UNDO.
FIND FIRST drc1
WHERE RECID(drc1) =
NO-LOCK NO-ERROR.
FIND FIRST drc2
WHERE RECID(drc2) =
NO-LOCK NO-ERROR.
FOR EACH table_field
WHERE table_field.table = ""
NO-LOCK.
DO inI = 1 TO (IF table_field.extent = 0 THEN 1 ELSE table_field.extent):
ASSIGN chF1 = "STRING(drc1."
+ table_field.fieldname
+ (IF table_field.extent = 0
THEN ""
ELSE "")
+ ")"
chF2 = "STRING(drc2."
+ table_field.fieldname
+ (IF table_field.extent = 0
THEN ""
ELSE "")
+ ")"
chV1 =
chV2 = .
IF NOT chV1 = chV2
THEN
DISPLAY
table_field.fieldname
chV1
chV2.
END.
END.
/* df.p
Field
*/
""
Message was edited by:
bjdobs
Did you try the buffer-compare method or statement?
That is a great command ... I missed finding that while searching the online 4gl command reference ... this command would certainly be simpler and would give me feedback that there is a difference and in what fields are involved.
However to speed up testing it would help knowing what the difference is with the fields not just that the fields are different.
Ok I found the issue with the code I was using ... the compiler cannot use an include for the chV1/2 assignments as it doesn't have the proper reference at compile time.
If I switch to using a open compile and pass via a run command then this works ... thanx for pointing out the buffer-compare command this will simplify the process.
One of the key issues here is the is compile time only ... I think you have got that, but want to be sure. For runtime dynamic, one needs the various dynamic verbs and structures.
ok here is a working Dynamic Comparison with data detail.
DEFINE BUFFER A FOR BLAH.
DEFINE BUFFER B FOR BLAH.
FIND LAST A NO-LOCK.
FIND LAST B WHERE RECID(B) <> RECID(A) NO-LOCK
RUN drc.p "BLAH" RECID(A) RECID(B).
//
/* drc.p
Table
recid1
recid2
*/
&IF "" <> "" AND "" <> "" AND "" <> "" &THEN
DEFINE VARIABLE chV1 AS CHARACTER NO-UNDO.
DEFINE VARIABLE chV2 AS CHARACTER NO-UNDO.
DEFINE VARIABLE chField AS CHARACTER NO-UNDO.
DEFINE VARIABLE chFlist AS CHARACTER NO-UNDO.
DEFINE VARIABLE chFld AS CHARACTER NO-UNDO.
DEFINE VARIABLE inI AS INTEGER NO-UNDO.
DEFINE VARIABLE inJ AS INTEGER NO-UNDO.
DEFINE NEW SHARED BUFFER B1 FOR .
DEFINE NEW SHARED BUFFER B2 FOR .
FORM
chField FORMAT "x(75)" LABEL "Fld" SKIP
chV1 FORMAT "x(75)" LABEL "V 1" SKIP
chV2 FORMAT "x(75)" LABEL "V 2"
SKIP(1)
WITH FRAME diff-frame
WIDTH 80
NO-BOX
NO-ATTR-SPACE
SIDE-LABELS
DOWN.
FIND FIRST B1 WHERE RECID(B1) = NO-LOCK NO-ERROR.
FIND FIRST B2 WHERE RECID(B2) = NO-LOCK NO-ERROR.
IF AVAILABLE B1 AND AVAILABLE B2
THEN DO:
BUFFER-COMPARE B1 TO B2 SAVE RESULT IN chFlist.
IF chFlist = "" THEN
MESSAGE "Records are identical" VIEW-AS ALERT-BOX.
ELSE
DO inI = 1 TO NUM-ENTRIES(chFlist).
ASSIGN chFld = ENTRY(inI,chFlist).
FIND FIRST _field
WHERE field.file-name = ""
AND field.field-name = chFld
NO-LOCK NO-ERROR.
DO inJ = 1 TO (IF field.extent = 0
THEN 1
ELSE field.extent):
ASSIGN chField = chFld
+ IF field.extent = 0
THEN ""
ELSE "".
RUN df.p (OUTPUT chV1, OUTPUT chV2) "" chField.
IF NOT chV1 = chV2
THEN DO:
DISPLAY chField chV1 chV2 WITH FRAME diff-frame.
DOWN WITH FRAME diff-frame.
END.
END.
END.
END.
ELSE
MESSAGE "No records to compare" VIEW-AS ALERT-BOX.
&ELSE
MESSAGE "Missing Parameters" VIEW-AS ALERT-BOX.
&ENDIF
//
/* df.p
**
Returns dynamic values for
table name
field name
*/
DEFINE OUTPUT PARAMETER chV1 AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER chV2 AS CHARACTER NO-UNDO.
DEFINE SHARED BUFFER B1 FOR .
DEFINE SHARED BUFFER B2 FOR .
ASSIGN chV1 = STRING(B1.)
chV2 = STRING(B2.).
I'd rather do somethnig like this (dynamic coding like suggested by Thomas). This will work fully without .
/* untested code follows */
DEFINE INPUT PARAMETER pcTable AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER prRowid1 AS ROWID NO-UNDO.
DEFINE INPUT PARAMETER prRowid2 AS ROWID NO-UNDO.
DEFINE VARIABLE i AS INTEGER NO-UNDO.
DEFINE VARIABLE hField1 AS HANDLE NO-UNDO.
DEFINE VARIABLE hField2 AS HANDLE NO-UNDO.
DEFINE VARIABLE hBuffer1 AS HANDLE NO-UNDO.
DEFINE VARIABLE hBuffer2 AS HANDLE NO-UNDO.
CREATE BUFFER hBuffer1 FOR TABLE pcTable.
CREATE BUFFER hBuffer2 FOR TABLE pcTable.
hBuffer1:FIND-BY-ROWID(prRowid1) NO-LOCK.
hBuffer2:FIND-BY-ROWID(prRowid2) NO-LOCK.
DO i = 1 TO hBuffer1:NUM-FIELDS:
ASSIGN hField1 = hBuffer1:BUFFER-FIELD(i)
hField2 = hBuffer2:BUFFER-FIELD(i) .
IF hField1:BUFFER-VALUE <> hField2:BUFFER-VALUE THEN
MESSAGE "Difference between" hField1:BUFFER-VALUE "and" hField2:BUFFER-VALUE
VIEW-AS ALERT-BOX.
END.
Amazing!!! Even after working with this language for over a decade I still see there are areas I need to explore further. Comes from "get the job done yesterday" without any time to explore other possibilities.
Thank-you Mike!!! That opens a whole new avenue.
If the objective is to delta a lot of records, then put the src/tgt table field handles into a TT, then FOR EACH through the TT records using
tt-name.src-field-handle:buffer-value = tt-name.tg-field-handle:buffer-value
comparisons to do the diff. One only has to de-reference each src/tgt field once, which saves a fair bit of overhead.
Works a treat!