Вложенные блоки Progress 4GL для отображения связанных данных

Во-первых, я новичок в Progress 4GL и все еще пытаюсь понять, как работает вложение блоков FOR EACH. У меня есть следующие две таблицы, из которых я получаю информацию: ivc_header и 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

К вашему сведению, первичный ключ для ivc_header — invoice_nbr, а для ivc_mchgs — составной ключ, состоящий из invoice_nbr, line_nbr и misc_seq_nbr. Внешний ключ — invoice_nbr.

Просто примечание о данных, информация в ivc_mchgs - это разные расходы по счету line_nbr.

То, что я пытаюсь получить, — это общий инвойс_амт и расширение на sold_to_cust_nbr + sold_to_cust seq. Проведя некоторое исследование, я решил поместить итоги в переменные вместо использования встроенной в Progress функции НАКОПИТЬ.

Вот код, который у меня есть:

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.

Этот код даст мне общую сумму invoice_amt по sold_to_cust_nbr + sold_to_cust_seq и суммирует расширение по invoice_nbr. Чего я не могу понять, как это сделать, так это получить общее расширение с помощью sold_to_cust_nbr + sold_to_cust_seq.

Любая помощь приветствуется.

Спасибо


person CuriousOne    schedule 15.09.2016    source источник


Ответы (2)


Если предположить, что вам нужна как общая сумма обмена по счету-фактуре, так и сводка, вы можете просто сделать это:

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.

элегантным способом было бы объединить оба запроса, используя левое внешнее соединение, и использовать функции ACCUMULATE, но это должно работать.

person Screwtape    schedule 15.09.2016

Я думаю, вы могли не знать, что вы можете указать несколько предложений BY.

IOW вы можете закодировать внутреннее FOR EACH примерно так:

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

и т.п.

person Tom Bascom    schedule 15.09.2016
comment
Спасибо за подсказку о нескольких предложениях BY, вы были правы, я не знал. - person CuriousOne; 15.09.2016