OldRecord vs. TempTable

NathanB

New Member
I am doing an evaluation of a current line in a table against a potential change to that line coming from a Temporary Table through a Business Object Update Method. I only want users to be able to change the Comment fields on the table (Part.MfgComment and Part.PurComment) and no other fields.

The database uses an evaluation of the existing record under the name 'oldRecord_Pre68_C1' and I have sucessfully used an evaluation of the two comment fields via something like:

if available oldRecord_Pre68_C1 and oldRecord_Pre68_C1.MfgComment <> ttPart.MfgComment then do:

But I also want to make sure that NONE of the other fields in the row have changed. I don't want to have to write out each field comparison through something like:

if available oldRecord_Pre68_C1 and oldRecord_Pre68_C1.MfgComment <> ttPart.MfgComment and oldRecord_Pre68_C1.Field1 = ttPart.Field1 and oldRecord_Pre68_C1.Field2 = ttPart.Field2 and... oldRecord_Pre68_C1.Fieldn = ttPart.Fieldn and then do:

This is too long and I might miss something. Is there any way to evaluate the etire table through a simplified statement?
 

TomBascom

Curmudgeon
Like, maybe, BUFFER-COMPARE?
BUFFER-COMPARE statement
Performs a bulk comparison of two records (source and target) by comparing source and target fields of the same name for equality and storing the result in a field. You can specify a list of fields to exclude, or a list of fields to include. You can also specify WHEN...THEN phrases. For all such phrases you specify, the AVM evaluates the WHEN portion, and if it evaluates to TRUE, the AVM executes the THEN portion.

Syntax

BUFFER-COMPARE source [ { EXCEPT | USING } field ... ] TO target [ CASE-SENSITIVE | BINARY ] [ SAVE [ RESULT IN ] result-field ] [ [ EXPLICIT ] COMPARES ]: [ WHEN field compare-operator expression THEN statement-or-block ] ... [ END [ COMPARES ] ] [ NO-LOBS ] [ NO-ERROR ]
 

NathanB

New Member
Tom,

This sounds like it will be the answer but I am struggling to the get syntax correct.

You supplied:

BUFFER-COMPARE source [ { EXCEPT | USING } field ... ] TO target [ CASE-SENSITIVE | BINARY ] [ SAVE [ RESULT IN ] result-field ] [ [ EXPLICIT ] COMPARES ]: [ WHEN field compare-operator expression THEN statement-or-block ] ... [ END [ COMPARES ] ] [ NO-LOBS ] [ NO-ERROR ]

Can you help me understand how to use this? What fields do I replace? What is needed before this statement as far as defined variables?

I am very new to programming and usually bite off way more than I can chew.

Thanks,

NB
 

TomBascom

Curmudgeon
Code:
define buffer cust1 for customer.
define buffer cust2 for customer.

define variable differences as character no-undo.

find first cust1 no-lock.
find last  cust2 no-lock.

buffer-compare cust1 to cust2 save result in differences.

message differences.
 

GregTomkins

Active Member
I'd just like to add that BUFFER-COMPARE is truly exactly the kind of statement that makes P4GL the unrivaled bastion of awesomeness that it is. Along with its sidekick BUFFER-COPY. Seriously.
 

NathanB

New Member
Tom and Greg,

Here is where I'm at as of this morning:

Business Case:

Users are allowed to update Part.PurComment and Part.MfgComment but no other fields on Part.

Approach:

define variable differences as logical no-undo.

For each ttPart, each Part where ttPart.Company = Part.Company and ttPart.PartNum = Part.PartNum no-lock.

buffer-compare ttPart Except ttPart.PurComment to Part save result in differences Explicit Compares no-error: When Differences = No Then undo.
end compare.

{lib\PublishInfoMsg.i &InfoMsg = "'differences'"}.
End.

Problem: What is the proper syntax for this Buffer-Compare statement? Current results are infomsg is displayed every time Part.Update BO Method is called and Update is not blocked.

Any suggestions you can give would be wonderful.

Thanks,

NB
 

GregTomkins

Active Member
You said "Users are allowed to update Part.PurComment and Part.MfgComment" yet your compare is skipping PurComment. Not really sure what you are trying to do here.

Apart from that the syntax looks OK, but the MESSAGE statement (which I assume is buried inside the .i) should perhaps have an 'if differences' clause in front of it.

FYI, in case you don't realize this, BUFFER-COMPARE is quite unusual in that its behaviour is dependent on the data type of the variable you save the result in (the SAVE RESULT syntax is also unusual). If 'differences' is LOGICAL, then it will be T or F depending if the record matches. If 'differences' is CHARACTER, then it will contain a comma separated list of fields that do not match.
 

NathanB

New Member
Greg,

I think this should be the final push.

The following syntax is producing the desired results:

define variable differences as logical no-undo.
Set differences = Yes.
For each ttPart, each Part where ttPart.Company = Part.Company and ttPart.PartNum = Part.PartNum no-lock.
buffer-compare ttPart Except ttPart.PurComment to Part save result in differences /*Explicit Compares no-error: When Differences = No Then undo*/.
/*end compare.*/
If differences = No then do:
{lib\PublishInfoMsg.i &InfoMsg = "'differences'"}.
End.
If differences = Yes then do:
{lib\PublishInfoMsg.i &InfoMsg = "'no differences'"}.
End.
End.

Only piece that isn't clicking for me yet is how to define multiple exceptions. Could you explain the syntax for a list of exception fields (brackets, comma seperators, etc.)?

Thanks,

NB
 
Top