CuriousOne
CuriousOne

Reputation: 51

Progress 4GL nesting blocks to display related data

First all I'm very new to Progress 4GL and still trying to get my head around how nesting FOR EACH blocks works. I have the following two tables that I'm getting information out of, ivc_header and ivc_mchgs:

ivc_header
    invoice_nbr     | sold_to_cust_nbr | sold_to_cust_seq | invoice_amt
        1000051     |        70        |        0         |   $1,000
        1000049     |        70        |        1         |   $1,500
        1000010     |       310        |        0         |   $2,000
        1000011     |       310        |        1         |   $2,500

ivc_mchgs
    invoice_nbr | line_nbr | misc_seq_nbr | extension
       1000051  |     1    |      1       |   $300
       1000051  |     1    |      2       |   $200
       1000051  |     2    |      1       |   $100
       1000049  |     1    |      1       |   $400
       1000049  |     1    |      2       |   $100
       1000049  |     2    |      1       |   $150
       1000010  |     1    |      1       |    $50
       1000010  |     1    |      2       |    $50
       1000010  |     2    |      1       |   $100
       1000011  |     1    |      1       |    $75
       1000011  |     1    |      2       |    $80
       1000011  |     2    |      1       |    $90

Just FYI, the primary key for ivc_header is invoice_nbr and for ivc_mchgs the primary is a composite key consisting of invoice_nbr, line_nbr, and misc_seq_nbr. The foreign key is invoice_nbr.

Just a note about the data, the information in ivc_mchgs are miscellaneous charges by invoice line_nbr.

What I'm trying to get is the total invoice_amt and extension by sold_to_cust_nbr + sold_to_cust seq. After doing some research I've decided to put the totals in variables instead of using Progress' built in ACCUMULATE function.

Here is the code that I have:

DEFINE VARIABLE cCustNum AS CHARACTER           NO-UNDO.
DEFINE VARIABLE dInvoiceSubTotal AS DECIMAL     NO-UNDO.
DEFINE VARIABLE dSurchargeTotal AS DECIMAL      NO-UNDO.

FOR EACH ivc_header 
    NO-LOCK
    WHERE (ivc_header.sold_to_cust_nbr = "000070")
          OR (ivc_header.sold_to_cust_nbr = "000310")
    BREAK BY ivc_header.sold_to_cust_nbr:
    IF FIRST-OF(ivc_header.sold_to_cust_nbr) THEN
        ASSIGN dInvoiceSubTotal = 0.
        ASSIGN dInvoiceSUbTotal = dInvoiceSUbTotal + ivc_header.invoice_amt.
    IF LAST-OF(ivc_header.sold_to_cust_nbr) THEN
        DISPLAY ivc_header.sold_to_cust_nbr + ivc_header.sold_to_cust_seq   FORMAT "x(9)" LABEL "CustNum"
            dInvoiceSUbTotal LABEL "SubTotal".
FOR EACH ivc_mchgs WHERE ivc_header.invoice_nbr = ivc_mchgs.invoice_nbr 
    NO-LOCK
    BREAK BY ivc_mchgs.invoice_nbr:
    IF FIRST-OF(ivc_mchgs.invoice_nbr) THEN
        ASSIGN dSurchargeTotal = 0.
        ASSIGN dSurchargeTotal = dSurchargeTotal + ivc_mchgs.extension.
    IF LAST-OF (ivc_mchgs.invoice_nbr) THEN
        DISPLAY
                dSurchargeTotal LABEL "Surcharge".
    END.
END.

This code will give me the total invoice_amt by sold_to_cust_nbr + sold_to_cust_seq and totals the extension by invoice_nbr. What I can't figure out how to do is get a total of extension by sold_to_cust_nbr + sold_to_cust_seq.

Any help is appreciated.

Thanks

Upvotes: 1

Views: 362

Answers (2)

Screwtape
Screwtape

Reputation: 1367

On the assumption you want both the exchange total by invoice and summary, then you could just do this:

DEFINE VARIABLE cCustNum AS CHARACTER           NO-UNDO.
DEFINE VARIABLE dInvoiceSubTotal AS DECIMAL     NO-UNDO.
DEFINE VARIABLE dSurchargeTotal AS DECIMAL      NO-UNDO.
DEFINE VARIABLE dSurchargeSubTl AS DECIMAL      NO-UNDO.

FOR EACH ivc_header 
    NO-LOCK
    WHERE (ivc_header.sold_to_cust_nbr = "000070")
          OR (ivc_header.sold_to_cust_nbr = "000310")
    BREAK BY ivc_header.sold_to_cust_nbr:
    IF FIRST-OF(ivc_header.sold_to_cust_nbr) THEN
        ASSIGN dInvoiceSubTotal = 0
               dSurchargeSubTl = 0.
    ASSIGN dInvoiceSUbTotal = dInvoiceSUbTotal + ivc_header.invoice_amt.
    IF LAST-OF(ivc_header.sold_to_cust_nbr) THEN   
        DISPLAY ivc_header.sold_to_cust_nbr + ivc_header.sold_to_cust_seq  FORMAT "x(9)" LABEL "CustNum"
            dInvoiceSUbTotal LABEL "SubTotal"
            dSurchargeSubTL LABEL "Srchg SubTl".
    FOR EACH ivc_mchgs WHERE ivc_header.invoice_nbr = ivc_mchgs.invoice_nbr 
        NO-LOCK
        BREAK BY ivc_mchgs.invoice_nbr:
        IF FIRST-OF(ivc_mchgs.invoice_nbr) THEN
            ASSIGN dSurchargeTotal = 0.
        ASSIGN dSurchargeTotal = dSurchargeTotal + ivc_mchgs.extension.
        IF LAST-OF (ivc_mchgs.invoice_nbr) THEN DO:
            DISPLAY dSurchargeTotal LABEL "Surcharge".
            ASSIGN dSurchargeSubTl = dSurchargeSubTl + dSurchargeTotal.
        END.
    END.
END.

The elegant way would be to combine both queries using a left outer join, and use the ACCUMULATE functions, but this should work.

Upvotes: 0

Tom Bascom
Tom Bascom

Reputation: 14020

I think you might not be aware that you can specify multiple BY clauses.

IOW you might want to code the inner FOR EACH something like this:

FOR EACH ivc_mchgs NO-LOCK WHERE ivc_header.invoice_nbr = ivc_mchgs.invoice_nbr 
    BREAK BY ivc_mchgs.invoice_nbr
          BY ivc_mchgs.sold_to_cust_nbr
          BY ivc_mchgs.sold_to_cust_seq:

    IF FIRST-OF(ivc_mchgs.invoice_nbr) THEN
        ASSIGN dSurchargeTotal = 0.

    IF FIRST-OF(ivc_mchgs.sold_to_cust_nbr ) THEN ...

etc.

Upvotes: 3

Related Questions