Search code examples
foreachprogress-4glopenedge4gl

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


Solution

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