Dynamic Record Comparison

Posted by Admin on 10-Mar-2009 19:01

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

All Replies

Posted by Admin on 10-Mar-2009 19:16

Did you try the buffer-compare method or statement?

Posted by Admin on 10-Mar-2009 19:39

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.

Posted by Admin on 10-Mar-2009 20:17

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.

Posted by Thomas Mercer-Hursh on 10-Mar-2009 21:24

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.

Posted by Admin on 10-Mar-2009 22:37

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.).

Posted by Admin on 11-Mar-2009 15:19

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.

Posted by Admin on 11-Mar-2009 16:03

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.

Posted by Tim Kuehn on 16-Mar-2009 06:37

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!

This thread is closed