Рассчитать итог и промежуточный итог без цикла?

Я начинаю изучать новый абап. Но у меня проблемы. Я хочу сделать вывод результата, как показано ниже, без использования операторов «LOOP» и «AT».

У меня есть внутренняя таблица, например:

Category Amount
    AAA     10
    AAA     20
    BBB     30
    CCC     40
    CCC     50
    CCC     60

Мне нужно отобразить вывод как:

Category Amount
    AAA       10
    AAA       20
    SUBTOTAL  30
    BBB       30
    SUBTOTAL  30
    CCC       40
    CCC       50
    CCC       60
    SUBTOTAL  150
    TOTAL     210

Может кто-нибудь помочь с этим?


person Joey    schedule 10.10.2018    source источник
comment
Не могли бы вы поделиться тем, что вы пробовали, и объяснить, где именно вы застряли?   -  person Sandra Rossi    schedule 10.10.2018
comment
Связанный вопрос с упрощенной версией этой проблемы: Получить итог без LOOP в abap   -  person Philipp    schedule 06.07.2020


Ответы (3)


Если ваш вопрос касается того, как построить внутреннюю таблицу (в памяти) с помощью выражений конструктора (ABAP >= 7.40), а не отображать ее на экране или в файле спула (итоговые и промежуточные итоги — это функции, хорошо интегрированные в ALV и простые в использовании). use), то вот один из способов сделать это (ASSERT здесь, чтобы показать, что конечное значение соответствует ожидаемому):

TYPES : BEGIN OF ty_line,
          category TYPE string,
          amount   TYPE decfloat16,
        END OF ty_line,
        ty_lines TYPE STANDARD TABLE OF ty_line WITH DEFAULT KEY.

DATA(gt_main) = VALUE ty_lines( ( category = 'AAA' amount = 10 )
                                ( category = 'AAA' amount = 20 )
                                ( category = 'BBB' amount = 30 )
                                ( category = 'CCC' amount = 40 )
                                ( category = 'CCC' amount = 50 )
                                ( category = 'CCC' amount = 60 ) ).

DATA(lt_display) = VALUE ty_lines(
        ( LINES OF VALUE #(
              FOR GROUPS <g> OF <line> IN gt_main
              GROUP BY ( category = <line>-category )
              ( LINES OF VALUE #( FOR <line2> IN GROUP <g> ( <line2> ) ) )
              ( category = 'SUBTOTAL'
                amount = REDUCE #( INIT subtotal TYPE ty_line-amount
                                   FOR <line2> IN GROUP <g>
                                   NEXT subtotal = subtotal + <line2>-amount ) ) ) )
        ( category = 'TOTAL'
          amount = REDUCE #( INIT total TYPE ty_line-amount
                             FOR <line> IN gt_main
                             NEXT total = total + <line>-amount ) ) ).

ASSERT lt_display = VALUE ty_lines( ( category = 'AAA'      amount = 10 )
                                    ( category = 'AAA'      amount = 20 )
                                    ( category = 'SUBTOTAL' amount = 30 )
                                    ( category = 'BBB'      amount = 30 )
                                    ( category = 'SUBTOTAL' amount = 30 )
                                    ( category = 'CCC'      amount = 40 )
                                    ( category = 'CCC'      amount = 50 )
                                    ( category = 'CCC'      amount = 60 )
                                    ( category = 'SUBTOTAL' amount = 150 )
                                    ( category = 'TOTAL'    amount = 210 ) ).
person Sandra Rossi    schedule 11.10.2018

Я делаю этот код, как показано ниже.

TYPES: LTY_DISPLAY TYPE STANDARD TABLE OF TY_DISPLAY WITH EMPTY KEY.

LT_DISPLAY = REDUCE LTY_DISPLAY
             ( INIT LIST = VALUE LTY_DISPLAY( )
               SUBTOTAL = VALUE LTY_DISPLAY( )
               TOTAL = VALUE LTY_DISPLAY( )
               LV_TEXT TYPE STRING

               FOR GROUPS <GROUP_KEY> OF <WA> IN GT_MAIN GROUP BY ( CATEGORY = <WA>-CATEGORY ) ASCENDING
               NEXT lV_TEXT = <GROUP_KEY>
                    LIST = VALUE LTY_COSP( BASE SUBTOTAL FOR <WA1> IN GROUP <GROUP_KEY> ( <WA1> ) )
                    SUBTOTAL = VALUE LTY_COSP( BASE LIST ( CATEGORY = 'SUBTOTAL' && LV_TEXT
                                                           AMOUNT = REDUCE #( INIT SUM TYPE P
                                                                               FOR M IN GROUP <GROUP_KEY>
                                                                               NEXT SUM = SUM + M-AMOUNT ) ) )
                    TOTAL = VALUE LTY_COSP( BASE SUBTOTAL ( CATEGORY = 'TOTAL' 
                                                              AMOUNT = REDUCE #( INIT SUM TYPE P
                                                                                  FOR M IN GT_MAIN
                                                                                  NEXT SUM = SUM + M-AMOUNT ) ) ) ).
person Joey    schedule 11.10.2018

Если вы не хотите перебирать внутреннюю таблицу, используя цикл at, вы всегда можете использовать функциональный модуль, который будет просматривать внутреннюю таблицу для вас и печатать итоги и промежуточные итоги.

REUSE_ALV_GRID_DISPLAY — один из таких функциональных модулей.

Вы можете найти учебник по следующей ссылке: http://www.saphub.com/abap-tutorial/abap-alv-total-subtotal/

Вышеприведенное реализовано в парадигме процедурного программирования и является более новым, чем исходный способ создания отчетов в SAP (где вы использовали бы операторы печати).

Однако есть еще более новый способ — использовать объектно-ориентированную реализацию отчетов ALV. Загляните в CL_GUI_ALV_GRID.

Вот вводная статья о CL_GUI_ALV_GRID: https://wiki.scn.sap.com/wiki/display/ABAP/OBJECT+ORIENTED+ALV+Guide

person Bilal Saleem    schedule 10.10.2018
comment
Хотя ответ имеет смысл в реальном мире (ALV вычисляет/отображает итоги и промежуточные итоги), вопрос больше касается решения с помощью выражений конструктора ABAP, а не отображения ожидаемого результата (если я правильно интерпретирую, изучая новый ABAP, без LOOP, конечно). - person Sandra Rossi; 11.10.2018
comment
@SandraRossi, но тогда вы пропускаете другую половину вопроса: хотите вывести результат, как показано ниже. Наличие данных во внутренней таблице не создаст никакого вывода. - person Gert Beukema; 12.10.2018
comment
@GertBeukema верно, поэтому я обновил свой ответ, чтобы сказать, что я освещаю один аспект вопроса, а не решение ALV. - person Sandra Rossi; 12.10.2018