[SHARING] Maintain -- Any Simple Way to Compare Two Entire Stack Rows?
Here's what I want to do -- compare Stack row 1 to stack row 2 and see if there are any differences. Do I need to do this field by field, explicitly specifying each in a massive OR clause or is there a way to compare the entire rows to each other? Or perhaps a subscript way to reference the columns so that I can build a short loop? Essentially what I'm looking to do is this --
If StkUserInformation(1) EQ StkUserInformation(2) then begin . . . endbeginThis message has been edited. Last edited by: Kerry,
February 24, 2009, 10:43 AM
GCohen
You can add to the MFD a single 'Group Field' that covers all of the fields in the table. See the Documentation of GROUP Fields. Then you can just compare ... IF GRP NE LAST GRP
But if this is a relational database you can't use LAST but I assume you know how to get the two records you want to compare.
Release 7.6.9 Windows HTML
February 24, 2009, 10:52 AM
John_Edwards
.
Who was that masked man?
J.
February 24, 2009, 11:09 AM
John_Edwards
.
Error [FOC03651] in madap_dev/Madap_Applicant_Information.WINFORMS' at or near line 8: The command Group Field Keys is not yet implemented.
I'd love to see a .all attribute added to Maintain stacks. That would be pretty sweet.
J.This message has been edited. Last edited by: John_Edwards,
February 24, 2009, 02:04 PM
Dave Ayers
John,
Yes, a '.all' would be cool !
But in the meantime, perhaps you could Compute a new field in your stack that is the concatenation of all the fields - and then do your comparisons on that pseudo-Group field. It will take a bit of explicit coding, depending on how many fields you have, but then the comparison code would be very simple.
WebFocus/Maintain 7.6.4-8 on Win2000 and 2003 Server
February 24, 2009, 02:23 PM
Maintain Wizard
Dave just beat me to the suggestion. However, instead of doing a COMPUTE into a stack, you COULD do a define in the Master: DEFINE FULLNAME/A50 = FRST | LA;$
You could then compare the records. So no, there is no way to compare a record except field by field. However, you could either create a Defined field or a Computed field.
Mark
February 24, 2009, 02:24 PM
John_Edwards
Comparing the fields would be easier methinks.
J.
February 25, 2009, 05:51 AM
Alan B
You could always throw everything into a Stack of a0, and just compare those. It might be a little easier.
MAINTAIN FILE car
Case Top
carstk/stack of a0;
case1();
case2();
EndCase
Case case1
for all next car.country car.car car.model car.bodytype into carstack;
EndCase
Case case2
Repeat carstack.foccount cntr/i4=1;
carstk(cntr) = carstack(cntr).country;
carstk(cntr) = carstk(cntr) | '/' | carstack(cntr).car;
carstk(cntr) = carstk(cntr) | '/' | carstack(cntr).model;
carstk(cntr) = carstk(cntr) | '/' | carstack(cntr).bodytype;
carstk(cntr) = carstk(cntr) | '/' | carstack(cntr).seats;
carstk(cntr) = carstk(cntr) | '/' | carstack(cntr).dealer_cost;
carstk(cntr) = carstk(cntr) | '/' | carstack(cntr).retail_cost;
carstk(cntr) = carstk(cntr) | '/' | carstack(cntr).sales;
endRepeat cntr=cntr+1;
Repeat carstk.foccount cntr=1;
type "*** <carstk(cntr) ";
endRepeat cntr=cntr+1;
EndCase
END
Alan. WF 7.705/8.007
February 25, 2009, 09:42 AM
John_Edwards
Yeah, just comparing all the fields individually instead of concatenating all the individual fields lets me ignore all the type-casting headaches. That seems like the most reasonable solution.
If there isn't a function that's OK. I just didn't want to do the long form if there was a proper way to do it in a shorter form that I was not aware of.
Thanks folks!
J.
February 25, 2009, 09:48 AM
Alan B
John
What type-casting headaches do you mean?
Alan. WF 7.705/8.007
February 26, 2009, 03:39 PM
Waz
I believe there is a way to compare the columns.
There are Maintain internal functions and objects that may do the trick, but it is very low level, and I have only touched on it once about 10 years ago, and that was to dynamically change the colouring of screen objects from withing maintain.
Mark (MaintainWizard) are you still at IBI ? Someone there may give you the info. There is an expansive object hierarchy inside maintain that may be usable to do this sort of thing.
Waz...
Prod:
WebFOCUS 7.6.10/8.1.04
Upgrade:
WebFOCUS 8.2.07
OS:
Linux
Outputs:
HTML, PDF, Excel, PPT
In Focus since 1984
Pity the lost knowledge of an old programmer!
February 27, 2009, 09:40 AM
John_Edwards
I looked at the Object-Oriented stuff that nobody uses, but it doesn't work for the stack stuff.
I could build a separate case, but I have to do it for about a dozen different tables, for each only once. So all the case would do is add one more level of misdirection without making anything shorter or simpler.
Do I mark a thread "solved" if the answer is pretty much that I can't do what I would like to?
J.
February 27, 2009, 09:48 AM
j.gross
How about "[HOPELESS]"?
March 01, 2009, 02:44 PM
Waz
I am about 90% sure this can be done, I'll have a look in to it, may take a lot of time though, but would be quite useful.
Waz...
Prod:
WebFOCUS 7.6.10/8.1.04
Upgrade:
WebFOCUS 8.2.07
OS:
Linux
Outputs:
HTML, PDF, Excel, PPT
In Focus since 1984
Pity the lost knowledge of an old programmer!
March 02, 2009, 03:53 PM
Waz
quote:
Object-Oriented stuff that nobody uses
Unfortunately, I have used the Object Oriented Stuff.
Have a look at this.
MAINTAIN FILE CAR
MODULE IMPORT (mntstkz FOCCOMP);
Declare ( msc/mnt_StackCompare; ) ;
Case Top
Compute
i/i8;
testres/I9 ;
INFER CAR.ORIGIN.COUNTRY CAR.COMP.CAR CAR.CARREC.MODEL INTO stkCAR1 ;
INFER CAR.ORIGIN.COUNTRY CAR.COMP.CAR CAR.CARREC.MODEL INTO stkCAR2 ;
INFER CAR.ORIGIN.COUNTRY CAR.COMP.CAR CAR.CARREC.MODEL INTO stkCAR3 ;
INFER CAR.ORIGIN.COUNTRY CAR.COMP.CAR INTO stkCAR4 ;
FOR ALL NEXT CAR.ORIGIN.COUNTRY CAR.COMP.CAR CAR.CARREC.MODEL INTO stkCARS ;
Stack Copy From stkCARS Into stkCAR1(1) Where (COUNTRY EQ 'ENGLAND') ;
Stack Copy From stkCARS Into stkCAR2(1) Where (COUNTRY EQ 'ENGLAND') ;
Stack Copy From stkCARS Into stkCAR3(1) Where (COUNTRY EQ 'FRANCE') ;
Stack Copy From stkCARS Into stkCAR4(1) Where (COUNTRY EQ 'ENGLAND') ;
testres = Compare_Stacks("Stacks the same",stkCAR1,stkCAR2,1,1) ;
testres = Compare_Stacks("Data Different" ,stkCAR1,stkCAR3,1,1) ;
$$testres = Compare_Stacks("Stacks Different" ,stkCAR1,stkCAR4,1,1) ;
Endcase
Case Compare_Stacks TAKES varTest/A0, stk1/anyType, stk2/anyType, row1/I9, row2/I9 RETURNS varCompRes/I1 ;
Type "<varTest" ;
msc.Init(stk1,stk2) ;
msc.AllocCompareBuf();
varCompRes = msc.IsRowSame(row1,row2) ;
Type "Compare Result = <varCompRes" ;
Endcase
END
The key parts are:
MODULE IMPORT (mntstkz FOCCOMP);
Declare ( msc/mnt_StackCompare; ) ;
Case Compare_Stacks
As mentioned earlier in this post, there are internal functions in Maintain that "may do the trick", well this is one of them.
There is a hidden library called mntstkz, this has many methods, one of them is comparing stacks.
But be aware, that if the stacks structures are not the same, it will EXIT the maintain pgm.
I personally would like these libraries documented.
Waz...
Prod:
WebFOCUS 7.6.10/8.1.04
Upgrade:
WebFOCUS 8.2.07
OS:
Linux
Outputs:
HTML, PDF, Excel, PPT
In Focus since 1984
Pity the lost knowledge of an old programmer!
March 02, 2009, 04:53 PM
John_Edwards
Now we're gettin' warm.
Thanks bud -- I'll have a look at that. Since I am comparing records in the same stack the chance of the rows having a different format is zero.
For the moment you have replaced Derwin as my geek-idol.