废除这段代码可以改进的地方

时间:2018-07-25 13:53:09

标签: loops select abap

请检查我的源代码,并在下面编写/建议如何加快此查询的速度(此处是性能问题)。该查询显示联产品的销售总额。

我在google中选中了循环选择不是一个好的解决方案,所以请帮助我改进此源代码?

此查询基于表vbfa,其中我从每种物料编号中搜索交货的数量和价值,并使用功能“收集”。 report result for two co-productssat_1sat_2

TYPES: BEGIN OF ts_marc,
werks     TYPE marc-werks,
matnr     TYPE marc-matnr,
mmsta     TYPE marc-mmsta,
kzkup     TYPE marc-kzkup,
stlnr     TYPE mast-stlnr,
stlty     TYPE stpo-stlty,
idnrk     TYPE stpo-idnrk,
erdat     TYPE vbfa-erdat,
rfmng     TYPE vbfa-rfmng,
meins     TYPE vbfa-meins,
rfwrt     TYPE vbfa-rfwrt,
waers     TYPE vbfa-waers,
vbelv     TYPE vbfa-vbelv,
plnnr     TYPE mapl-plnnr,
zkriz     TYPE mapl-zkriz,
rfmng1    TYPE vbfa-rfmng,
sum_rfmng TYPE vbfa-rfmng,
END OF ts_marc,
gtt_marc TYPE ts_marc.

TYPES: BEGIN OF ts_mapl,
werks TYPE mapl-werks,
matnr TYPE mapl-matnr,
plnnr TYPE mapl-plnnr,
zkriz TYPE mapl-zkriz,
END OF ts_mapl.

TYPES: BEGIN OF ty_s_ver,
rfmng TYPE vbfa-rfmng,
erdat TYPE vbfa-erdat,
vbelv TYPE vbfa-vbelv,
rfwrt TYPE  vbfa-rfwrt,
meins TYPE vbfa-meins,
waers TYPE vbfa-waers,
END OF ty_s_ver,
ty_t_ver TYPE STANDARD TABLE OF ty_s_ver WITH DEFAULT KEY.

TYPES: BEGIN OF ty_s_data,
werks  TYPE marc-werks,
matnr  TYPE marc-matnr,
mmsta  TYPE marc-mmsta,
kzkup  TYPE marc-kzkup,
stlnr  TYPE mast-stlnr,
stlty  TYPE stpo-stlty,
idnrk  TYPE stpo-idnrk,
plnnr  TYPE mapl-plnnr,
zkriz  TYPE mapl-zkriz,
tb_ver TYPE ty_t_ver,
END OF ty_s_data,
ty_t_data TYPE STANDARD TABLE OF ty_s_data WITH DEFAULT KEY.

TYPES: BEGIN OF ty_s_marc,
werks  TYPE marc-werks,
matnr  TYPE marc-matnr,
kzkup  TYPE marc-kzkup,
stlnr  TYPE mast-stlnr,
stlty  TYPE stpo-stlty,
idnrk  TYPE stpo-idnrk,
plnnr  TYPE mapl-plnnr,
zkriz  TYPE mapl-zkriz,
tb_ver TYPE ty_t_ver,
END OF ty_s_marc.

TYPES: BEGIN OF ty_s_alv,
werks TYPE marc-werks,
matnr TYPE marc-matnr,
mmsta TYPE marc-mmsta,
kzkup TYPE marc-kzkup,
stlnr TYPE mast-stlnr,
stlty TYPE stpo-stlty,
idnrk TYPE stpo-idnrk,
meins TYPE vbfa-meins,
rfwrt TYPE vbfa-rfwrt,
waers TYPE vbfa-waers,
vbelv TYPE vbfa-vbelv,
plnnr TYPE mapl-plnnr,
zkriz TYPE mapl-zkriz,
rfmng TYPE vbfa-rfmng,
erdat TYPE vbfa-erdat.
TYPES:  color(3) TYPE c,
END OF ty_s_alv,
ty_t_alv TYPE STANDARD TABLE OF ty_s_alv.

TYPES: BEGIN OF ts_vlpma,
werks TYPE marc-werks,
mmsta TYPE marc-mmsta,
kzkup TYPE marc-kzkup,
stlnr TYPE mast-stlnr,
stlty TYPE stpo-stlty,
idnrk TYPE stpo-idnrk,
meins TYPE vbfa-meins,
rfwrt TYPE vbfa-rfwrt,
waers TYPE vbfa-waers,
vbelv TYPE vbfa-vbelv,
plnnr TYPE mapl-plnnr,
zkriz TYPE mapl-zkriz,
rfmng TYPE vbfa-rfmng,
erdat TYPE vbfa-erdat,
matnr TYPE vlpma-matnr,
vbeln TYPE vlpma-vbeln,
END OF ts_vlpma.

data:     gt_marc  TYPE ts_marc.
***********************************
DATA: gt_vlpma TYPE TABLE OF ts_vlpma,
ls_vlpma TYPE ts_vlpma.
**************************************
DATA :it_data  TYPE ty_t_data.

DATA:   ls_data TYPE ty_s_data,
ls_ver  TYPE ty_s_ver,
gt_ver  TYPE ty_t_ver,
gt_ver1  TYPE ty_t_ver,
lt_vbfa TYPE STANDARD TABLE OF vbfa,
ls_vbfa TYPE vbfa.


DATA: gt_data TYPE ty_t_data.

DATA : ct_data TYPE ty_t_data.
DATA:  ls_alv  TYPE ty_s_alv.

DATA : ct_alv TYPE ty_t_alv.
DATA: lv_tabix TYPE i.

FIELD-SYMBOLS: <lfs_data> LIKE LINE OF gt_data.
FIELD-SYMBOLS: <lfs_ver> LIKE LINE OF gt_ver.
FIELD-SYMBOLS: <lfs_ver1> LIKE LINE OF gt_ver1.  
***************************************************************

 DATA :gt_mapl  TYPE ts_mapl.

 DATA: go_alv         TYPE REF TO cl_salv_table,
 go_layout      TYPE REF TO cl_salv_layout,
 g_key          TYPE salv_s_layout_key,
 lo_aggrs       TYPE REF TO cl_salv_aggregations,
 lr_sort        TYPE REF TO cl_salv_sorts,
 lr_sort_column TYPE REF TO cl_salv_sort,
 rcode          LIKE sy-subrc.


SELECT-OPTIONS: so_werks FOR gt_marc-werks OBLIGATORY NO-EXTENSION NO 
INTERVALS MEMORY ID wrk,
so_matnr FOR gt_marc-matnr NO INTERVALS,
so_erdat FOR gt_marc-erdat,
so_mmsta FOR gt_marc-mmsta NO INTERVALS DEFAULT 'Z9' OPTION NE.

START-OF-SELECTION.

SELECT marc~werks ,marc~matnr, marc~mmsta, marc~kzkup, mast~stlnr, 
stpo~stlty, stpo~idnrk,
mapl~plnnr, mapl~zkriz

FROM marc AS marc INNER JOIN mast AS mast ON
marc~werks = mast~werks AND
marc~matnr = mast~matnr AND
marc~kzkup = 'X' AND
mast~stlal = '01'

INNER JOIN stpo AS stpo ON
mast~stlnr = stpo~stlnr AND
stpo~kzkup = 'X' AND
stpo~stlty = 'M'
INNER JOIN mapl AS mapl ON
marc~werks = mapl~werks AND
marc~matnr = mapl~matnr AND
mapl~plnty = 'N' AND
plnal = '02' AND
loekz = ' '

INTO CORRESPONDING FIELDS OF TABLE @ct_data
WHERE marc~werks IN @so_werks
AND marc~matnr IN @so_matnr
AND marc~mmsta IN @so_mmsta.


SELECT marc~werks ,marc~matnr, marc~mmsta, marc~kzkup, mast~stlnr, 
stpo~stlty, stpo~idnrk,
mapl~plnnr, mapl~zkriz, vlpma~vbeln

FROM marc AS marc INNER JOIN mast AS mast ON
marc~werks = mast~werks AND
marc~matnr = mast~matnr AND
marc~kzkup = 'X' AND
mast~stlal = '01'

INNER JOIN stpo AS stpo ON
mast~stlnr = stpo~stlnr AND
stpo~kzkup = 'X' AND
stpo~stlty = 'M'

LEFT OUTER JOIN vlpma AS vlpma ON

marc~matnr = vlpma~matnr AND
lfart = 'LF'

INNER JOIN mapl AS mapl ON
marc~werks = mapl~werks AND
marc~matnr = mapl~matnr AND
mapl~plnty = 'N' AND
plnal = '02' AND
loekz = ' '

INTO CORRESPONDING FIELDS OF TABLE @gt_vlpma

 WHERE marc~werks IN @so_werks
 AND marc~matnr IN @so_matnr
 AND marc~mmsta IN @so_mmsta.


LOOP AT gt_vlpma INTO ls_vlpma.
SELECT rfmng erdat vbelv rfwrt meins waers FROM vbfa

INTO corresponding fields of TABLE gt_ver

WHERE
vbelv = ls_vlpma-vbeln and
posnv < '900000' AND
vbtyp_n = 'R' AND
vbtyp_v = 'J' AND
matnr = ls_vlpma-matnr AND
bwart = '601'
AND erdat IN so_erdat.
append lines of gt_ver to gt_ver1.
endloop.


LOOP AT ct_data INTO ls_data.
SELECT rfmng erdat vbelv rfwrt meins waers FROM vbfa

INTO corresponding fields of TABLE ls_data-tb_ver

WHERE
posnv < '900000' AND
vbtyp_n = 'R' AND
vbtyp_v = 'J' AND
matnr = ls_data-matnr AND
bwart = '601'
AND erdat IN so_erdat.


MODIFY ct_data FROM ls_data.
MOVE-CORRESPONDING ls_data TO ls_alv.

IF ls_data-tb_ver IS INITIAL.
APPEND ls_alv TO ct_alv.
ELSE.

LOOP AT ls_data-tb_ver INTO ls_ver.
SELECT werks, matnr , plnnr, zkriz
FROM mapl UP TO 1 ROWS INTO @gt_mapl

    WHERE
    werks EQ @ls_data-werks AND
    plnnr EQ @ls_data-plnnr AND
    plnty = 'N' AND
    plnal = '02' AND
    loekz = ' '.

    IF gt_mapl-zkriz EQ ls_data-zkriz.
      ls_ver-rfmng = ls_ver-rfmng * -1.
      ls_ver-rfwrt = ls_ver-rfwrt * -1.
    ENDIF.

  ENDSELECT.


  MOVE ls_ver-rfmng TO ls_alv-rfmng.
  MOVE ls_ver-rfwrt TO ls_alv-rfwrt.

  COLLECT ls_alv INTO ct_alv.

 ENDLOOP.

 ENDIF.
 CLEAR ls_alv.

 ENDLOOP.


cl_salv_table=>factory(
EXPORTING
list_display   = abap_false

IMPORTING
r_salv_table   = go_alv
CHANGING
t_table        = ct_alv  ).

go_alv->get_functions( )->set_all( ).
lo_aggrs = go_alv->get_aggregations( ).

 CALL METHOD go_alv->get_sorts "get sorts
 RECEIVING
 value = lr_sort.

TRY.

CALL METHOD lr_sort->add_sort "add column sort
  EXPORTING
  columnname = 'PLNNR' "sort column always keyfield

  RECEIVING
  value      = lr_sort_column.

  ENDTRY.

TRY.
CALL METHOD lo_aggrs->add_aggregation "add aggregation
EXPORTING
columnname  = 'RFWRT' "aggregation column name
aggregation = if_salv_c_aggregation=>total. "aggregation type

CATCH cx_salv_data_error .                            
CATCH cx_salv_not_found .                             
CATCH cx_salv_existing .                              
ENDTRY.

TRY.
CALL METHOD lo_aggrs->add_aggregation "add aggregation
  EXPORTING
    columnname  = 'RFMNG' "aggregation column name
    aggregation = if_salv_c_aggregation=>total. "aggregation type

CATCH cx_salv_data_error .                            
CATCH cx_salv_not_found .                             
CATCH cx_salv_existing .                              
ENDTRY.

TRY.
CALL METHOD lo_aggrs->add_aggregation "add aggregation
EXPORTING
columnname  = 'WERKS' "aggregation column name
aggregation = if_salv_c_aggregation=>total. "aggregation type

CATCH cx_salv_data_error .                            
CATCH cx_salv_not_found .                             
CATCH cx_salv_existing .                              
ENDTRY.


*Bring the total line to top
lo_aggrs->set_aggregation_before_items( ).

TRY.
CALL METHOD lr_sort_column->set_subtotal "add subtotal
EXPORTING
value = if_salv_c_bool_sap=>true.
CATCH cx_salv_data_error .
ENDTRY.

TRY.
CALL METHOD lr_sort->add_sort
EXPORTING
columnname = 'RFMNG'
subtotal   = if_salv_c_bool_sap=>true.

lr_sort->set_compressed_subtotal( 'RFMNG' ).    

CATCH cx_salv_not_found .                             
CATCH cx_salv_existing .                              
CATCH cx_salv_data_error .                            
ENDTRY.

TRY.
CALL METHOD lr_sort->add_sort
EXPORTING
columnname = 'PLNNR'
subtotal   = if_salv_c_bool_sap=>true.

lr_sort->set_compressed_subtotal( 'PLNNR' ).   

CATCH cx_salv_not_found .                            
CATCH cx_salv_existing .                              
CATCH cx_salv_data_error .                            
ENDTRY.


TRY.
CALL METHOD lr_sort->add_sort
EXPORTING
columnname = 'MATNR'
subtotal   = if_salv_c_bool_sap=>true.

lr_sort->set_compressed_subtotal( 'MATNR' ).
CATCH cx_salv_not_found .                            
CATCH cx_salv_existing .                              
CATCH cx_salv_data_error .                          
ENDTRY.

go_layout = go_alv->get_layout( ).
g_key-report = sy-repid.
go_layout->set_key( g_key ).
go_layout->set_default( 'X' ).
go_layout->set_save_restriction( if_salv_c_layout=>restrict_user_dependant ).
go_alv->display( ).

3 个答案:

答案 0 :(得分:0)

您应该使用将要在VBFA中选择的字段排序表。一个简单的FOR ALL ENTESE可以提高性能。

另外,请考虑不要使用INTO CORRESPONDING FILE OF,因为这可能会导致系统花费时间来找出哪些列进入哪些列。

尝试仅声明您需要的字段,并按照正确的顺序选择这些字段。

SORT gt_vlpma ASCENDING BY vbeln matnr SELECT ... FROM vbfa INTO gt_ver FOR ALL ENTRIES IN gt_vlpma WHERE vbelv = gt_vlpma-vbelv AND ... AND matnr = gt_vlpma-matnr ... APPEND LINES OF gt_ver TO GT_VER1.

对ct_data做同样的事情。

答案 1 :(得分:0)

这是我的最终版本,从性能的角度来看,它也可以正常工作,请关闭这张票。

REPORT zco_product_sales.


*single entry***********************************************************

 TYPES: BEGIN OF ts_marc,
     werks TYPE marc-werks,
     matnr TYPE marc-matnr,
     mmsta TYPE marc-mmsta,
     kzkup TYPE marc-kzkup,
     stlnr TYPE mast-stlnr,
     stlty TYPE stpo-stlty,
     idnrk TYPE stpo-idnrk,
     erdat TYPE vbfa-erdat,
     rfmng TYPE vbfa-rfmng,
     meins TYPE vbfa-meins,
     rfwrt TYPE vbfa-rfwrt,
     waers TYPE vbfa-waers,
     vbelv TYPE vbfa-vbelv,
     plnnr TYPE mapl-plnnr,
     zkriz TYPE mapl-zkriz,
   END OF ts_marc.

 TYPES: BEGIN OF ts_t001w,
     werks TYPE t001w-werks,
   END OF ts_t001w.

 TYPES: BEGIN OF ts_mapl,
     werks TYPE mapl-werks,
     matnr TYPE mapl-matnr,
     plnnr TYPE mapl-plnnr,
     zkriz TYPE mapl-zkriz,
   END OF ts_mapl.

 DATA :gt_mapl  TYPE ts_mapl,
  gt_marc  TYPE ts_marc,
  gt_t001w TYPE ts_t001w,
  gt_marc2 TYPE TABLE OF ts_marc.

 DATA: go_alv         TYPE REF TO cl_salv_table,
  go_layout      TYPE REF TO cl_salv_layout,
  g_key          TYPE salv_s_layout_key,
  lo_aggrs       TYPE REF TO cl_salv_aggregations,
  lr_sort        TYPE REF TO cl_salv_sorts,
  lr_sort_column TYPE REF TO cl_salv_sort,
  go_columns     TYPE REF TO cl_salv_columns_table,
  go_column      TYPE REF TO cl_salv_column.


    *cumulate entry***********************************************

  TYPES: BEGIN OF ts_ver,
     werks TYPE marc-werks,
     matnr TYPE marc-matnr,
     mmsta TYPE marc-mmsta,
     kzkup TYPE marc-kzkup,
     idnrk TYPE stpo-idnrk,
     erdat TYPE vbfa-erdat,
     rfmng TYPE vbfa-rfmng,
     meins TYPE stpo-meins,
     rfwrt TYPE vbfa-rfwrt,
     waers TYPE vbfa-waers,
     vbelv TYPE vbfa-vbelv,
     plnnr TYPE mapl-plnnr,
     zkriz TYPE mapl-zkriz,
   END OF ts_ver.

  TYPES: BEGIN OF ts_alv,
     werks  TYPE marc-werks,
     matnr  TYPE marc-matnr,
     mmsta  TYPE marc-mmsta,
     kzkup  TYPE marc-kzkup,
     idnrk  TYPE stpo-idnrk,
     rfwrt  TYPE vbfa-rfwrt,
     waers  TYPE vbfa-waers,
     plnnr  TYPE mapl-plnnr,
     zkriz  TYPE mapl-zkriz,
     rfmng  TYPE vbfa-rfmng,
     meins  TYPE vbfa-meins,
     delta  TYPE vbfa-rfmng,
     delta1 TYPE vbfa-rfwrt,
   END OF ts_alv.

 TYPES: BEGIN OF ts_vlpma,
     werks TYPE marc-werks,
     matnr TYPE vlpma-matnr,
     vbeln TYPE vlpma-vbeln,
     rfmng TYPE vbfa-rfmng,
     rfwrt TYPE vbfa-rfwrt,
   END OF ts_vlpma.

DATA: gt_vlpma TYPE STANDARD TABLE OF ts_vlpma WITH DEFAULT KEY,
  gs_vlpma TYPE ts_vlpma.

DATA: gs_ver TYPE ts_ver,
  gt_ver TYPE STANDARD TABLE OF ts_ver,
  gt_alv TYPE STANDARD TABLE OF ts_alv.

DATA: s_text  TYPE scrtext_s,
  m_text  TYPE scrtext_m,
  l_text  TYPE scrtext_l,
  s_text1 TYPE scrtext_s,
  m_text1 TYPE scrtext_m,
  l_text1 TYPE scrtext_l.

 FIELD-SYMBOLS: <lfs_vlpma> TYPE ts_vlpma.
 FIELD-SYMBOLS: <lfs_ver> TYPE ts_ver.

*SELECTION-SCREEN BEGIN OF SCREEN 1100 AS SUBSCREEN.
 SELECTION-SCREEN BEGIN OF  BLOCK b1 WITH FRAME TITLE TEXT-001.
 SELECT-OPTIONS: so_werks FOR gs_ver-werks OBLIGATORY NO-EXTENSION NO INTERVALS 
 MEMORY ID wrk,
            so_matnr FOR gs_ver-matnr NO INTERVALS,
            so_erdat FOR gs_ver-erdat,
            so_mmsta FOR gs_ver-mmsta NO INTERVALS DEFAULT 'Z9' OPTION NE.

PARAMETERS: pa_chec1 RADIOBUTTON GROUP grp,
        pa_chec2 RADIOBUTTON GROUP grp.

SELECTION-SCREEN END OF BLOCK b1.

AT SELECTION-SCREEN.

SELECT werks FROM t001w INTO CORRESPONDING FIELDS OF gt_t001w
WHERE werks IN so_werks.

AUTHORITY-CHECK OBJECT 'M_MATE_WRK' ID 'WERKS' FIELD gt_t001w-werks
ID 'ACTVT' FIELD '03'.
IF sy-subrc <> 0.
  MESSAGE e120(m7) WITH gt_t001w-werks.
ENDIF.

ENDSELECT.

START-OF-SELECTION.

CASE 'X'.
 ****************************************************
  *single entry*****
 ****************************************************
WHEN pa_chec1.

  SELECT marc~werks ,marc~matnr,marc~mmsta, marc~kzkup, mast~stlnr, stpo~stlty, 
  stpo~idnrk, vbfa~erdat,
            vbfa~rfmng , vbfa~meins, vbfa~rfwrt , vbfa~waers, vbfa~vbelv , 
  mapl~plnnr, mapl~zkriz

           FROM marc AS marc INNER JOIN mast AS mast ON
           marc~werks = mast~werks AND
           marc~matnr = mast~matnr AND
           marc~kzkup = 'X' AND
           mast~stlal = '01'

           INNER JOIN stpo AS stpo ON
           mast~stlnr = stpo~stlnr AND
           stpo~kzkup = 'X' AND
           stpo~stlty = 'M'

           LEFT OUTER JOIN vbfa AS vbfa ON
           posnv < '900000' AND

           vbtyp_n = 'R' AND
           vbtyp_v = 'J' AND

           marc~matnr = vbfa~matnr AND
           vbfa~bwart = '601'

           INNER JOIN mapl AS mapl ON
           marc~werks = mapl~werks AND
           marc~matnr = mapl~matnr AND
           mapl~plnty = 'N' AND
           plnal = '02' AND
           loekz = ' '

           INTO @gt_marc

           WHERE marc~werks IN @so_werks
           AND marc~matnr IN @so_matnr
           AND vbfa~erdat IN @so_erdat
           AND marc~mmsta IN @so_mmsta.


    SELECT werks, matnr , plnnr, zkriz
    FROM mapl UP TO 1 ROWS INTO @gt_mapl
    WHERE
    werks EQ @gt_marc-werks AND
    plnnr EQ @gt_marc-plnnr AND
    mapl~plnty = 'N' AND
    plnal = '02' AND
    loekz = ' '.

      IF gt_mapl-zkriz EQ gt_marc-zkriz.
        gt_marc-rfmng = gt_marc-rfmng * -1.
        gt_marc-rfwrt = gt_marc-rfwrt * -1.
      ENDIF.

      APPEND gt_marc TO gt_marc2.

      CLEAR gt_mapl-zkriz.

 *sum with REDUCE function.
 *gt_marc-sum_rfmng = REDUCE rfmng( INIT x = 0 FOR ls IN gt_marc2
 *                                    WHERE ( werks = gt_marc-werks AND matnr = 
 gt_marc-matnr AND stlnr = gt_marc-stlnr )
 *                                      NEXT x = x + ls-rfmng ).
 *            MODIFY TABLE gt_marc2 FROM gt_marc.
 *            SORT BY gt_marc-matnr.
 *    WRITE: / gt_marc-werks, gt_marc-matnr , gt_marc-kzkup, gt_marc-stlnr, gt_marc- 
 *idnrk, gt_marc-erdat, gt_marc-rfmng, gt_marc-meins,
 * gt_marc-rfwrt, gt_marc-waers, gt_marc-vbelv, gt_marc-plnnr,gt_marc-zkriz, gt_marc- 
 *sum_rfmng COLOR 3.

    ENDSELECT.
  ENDSELECT.

  SORT gt_marc2 BY matnr vbelv.

  cl_salv_table=>factory(
   EXPORTING
     list_display   = abap_false
   IMPORTING
     r_salv_table   = go_alv
   CHANGING
     t_table        = gt_marc2  ).

  go_alv->get_functions( )->set_all( ).
  lo_aggrs = go_alv->get_aggregations( ).

  CALL METHOD go_alv->get_sorts "get sorts
    RECEIVING
      value = lr_sort.

  TRY.

      CALL METHOD lr_sort->add_sort "add column sort
        EXPORTING
          columnname = 'PLNNR' "sort column always keyfield
         *             POSITION   =
         *             SEQUENCE   = IF_SALV_C_SORT=>SORT_UP
         *             SUBTOTAL   = IF_SALV_C_BOOL_SAP=>FALSE 
         *             GROUP      = IF_SALV_C_SORT=>GROUP_NONE
         *             OBLIGATORY = IF_SALV_C_BOOL_SAP=>FALSE
        RECEIVING
          value      = lr_sort_column.

  ENDTRY.

  TRY.

      CALL METHOD lr_sort->add_sort "add column sort
        EXPORTING
          columnname = 'MATNR' "sort column always keyfield
  *             POSITION   =
  *             SEQUENCE   = IF_SALV_C_SORT=>SORT_UP
  *             SUBTOTAL   = IF_SALV_C_BOOL_SAP=>FALSE
  *             GROUP      = IF_SALV_C_SORT=>GROUP_NONE
  *             OBLIGATORY = IF_SALV_C_BOOL_SAP=>FALSE
        RECEIVING
          value      = lr_sort_column.

  ENDTRY.

  TRY.
      CALL METHOD lo_aggrs->add_aggregation "add aggregation
        EXPORTING
          columnname  = 'RFMNG' "aggregation column name
          aggregation = if_salv_c_aggregation=>total. "aggregation type

    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
  ENDTRY.

  TRY.
      CALL METHOD lo_aggrs->add_aggregation "add aggregation
        EXPORTING
          columnname  = 'WERKS' "aggregation column name
          aggregation = if_salv_c_aggregation=>total. "aggregation type

    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
   ENDTRY.


*   Bring the total line to top
  lo_aggrs->set_aggregation_before_items( ).

  TRY.
      CALL METHOD lr_sort_column->set_subtotal "add subtotal
        EXPORTING
          value = if_salv_c_bool_sap=>true.
    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
  ENDTRY.

  TRY.
      CALL METHOD lr_sort->add_sort
        EXPORTING
          columnname = 'RFMNG'
          subtotal   = if_salv_c_bool_sap=>true.

      lr_sort->set_compressed_subtotal( 'RFMNG' ).

    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
  ENDTRY.

  TRY.
      CALL METHOD lr_sort->add_sort
        EXPORTING
          columnname = 'MATNR'
          subtotal   = if_salv_c_bool_sap=>true.

      lr_sort->set_compressed_subtotal( 'MATNR' ).
    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
    CATCH cx_salv_data_error .                      "#EC NO_HANDLER

  ENDTRY.

 *hide columns from gt_marc2
  *    TRY.
  *        go_columns = go_alv->get_columns( ).
  *        go_column = go_columns->get_column( 'SUM_RFMNG' ).
  *        go_column->set_visible( abap_false ).

  *        go_columns = go_alv->get_columns( ).
  *        go_column = go_columns->get_column( 'SUM_RFWRT' ).
  *        go_column->set_visible( abap_false ).

 *    ENDTRY.

  go_layout = go_alv->get_layout( ).
  g_key-report = sy-repid.
  go_layout->set_key( g_key ).
  go_layout->set_save_restriction( if_salv_c_layout=>restrict_user_dependant ).
  go_layout->set_default( 'X' ).
  go_columns = go_alv->get_columns( ).
  go_columns->set_optimize( abap_true ).
  go_alv->display( ).


WHEN pa_chec2.

*******************************************************************************
*cumulate entry

  SELECT marc~werks ,marc~matnr, marc~mmsta, marc~kzkup, stpo~meins, stpo~idnrk, 
  mapl~plnnr, mapl~zkriz

        FROM marc AS marc INNER JOIN mast AS mast ON
             marc~werks = mast~werks AND
              marc~matnr = mast~matnr AND
               marc~kzkup = 'X' AND
                 mast~stlal = '01'

        INNER JOIN stpo AS stpo ON
          mast~stlnr = stpo~stlnr AND
           stpo~kzkup = 'X' AND
             stpo~stlty = 'M'

        INNER JOIN mapl AS mapl ON
         marc~werks = mapl~werks AND
           marc~matnr = mapl~matnr AND
             mapl~plnty = 'N' AND
              plnal = '02' AND
               loekz = ' '

  INTO CORRESPONDING FIELDS OF TABLE @gt_alv
        WHERE marc~werks IN @so_werks AND
               marc~matnr IN @so_matnr AND
                marc~mmsta IN @so_mmsta.

  IF sy-subrc = 0.

    SELECT marc~werks ,marc~matnr, vlpma~vbeln

        FROM marc AS marc

    LEFT OUTER JOIN vlpma AS vlpma ON
    marc~matnr = vlpma~matnr AND
     lfart = 'LF'
   **********************************************************************
    LEFT OUTER JOIN likp AS likp ON
     vlpma~vbeln = likp~vbeln AND
      likp~lfart = 'LF'
  **********************************************************************
    INTO CORRESPONDING FIELDS OF TABLE @gt_vlpma
          FOR ALL ENTRIES IN @gt_alv
    WHERE
     marc~werks = @gt_alv-werks AND
      marc~matnr = @gt_alv-matnr AND
       marc~mmsta = @gt_alv-mmsta AND
        likp~wadat IN @so_erdat.

    SORT gt_vlpma BY werks matnr vbeln.

    SELECT marc~mmsta, marc~kzkup, mapl~werks, mapl~zkriz, mapl~plnnr, vbfa~matnr,
        vbfa~rfmng, vbfa~erdat, vbfa~vbelv, vbfa~rfwrt, vbfa~meins, vbfa~waers

        FROM vbfa

    INNER JOIN marc AS marc ON
          marc~matnr = vbfa~matnr AND
           marc~kzkup = 'X'            "Indicator: Material can be co-product

    INNER JOIN mapl AS mapl ON
     marc~werks = mapl~werks AND
      vbfa~matnr = mapl~matnr AND
       mapl~plnty = 'N' AND
        plnal = '02' AND
         loekz = ' '

      INTO CORRESPONDING FIELDS OF TABLE @gt_ver
      FOR ALL ENTRIES IN @gt_vlpma

  WHERE
  vbelv = @gt_vlpma-vbeln AND
  posnv < '900000' AND
  vbtyp_n = 'R' AND
  vbtyp_v = 'J' AND
  vbfa~matnr = @gt_vlpma-matnr AND
  bwart = '601' AND
  erdat IN @so_erdat AND
  marc~werks IN @so_werks.

    SORT gt_ver BY werks matnr vbelv.

    "Move value and quantity from gt_ver to gt_vlpma.
    LOOP AT gt_vlpma ASSIGNING <lfs_vlpma>.
      IF <lfs_vlpma> IS ASSIGNED.
        READ TABLE gt_ver ASSIGNING <lfs_ver> WITH KEY werks = <lfs_vlpma>-werks
                                                        matnr = <lfs_vlpma>-matnr
                                                         vbelv = <lfs_vlpma>-vbeln  
        BINARY SEARCH.

        IF <lfs_ver> IS ASSIGNED.
          <lfs_vlpma>-rfmng = <lfs_ver>-rfmng.
          <lfs_vlpma>-rfwrt = <lfs_ver>-rfwrt.

          IF sy-subrc = 0.
            MODIFY TABLE gt_vlpma FROM <lfs_vlpma> TRANSPORTING rfmng rfwrt.

          ENDIF.

          UNASSIGN <lfs_ver>.

        ENDIF.
      ENDIF.
    ENDLOOP.
    "Calculate sum value (rfmng) and quantity (rfwrt).
    LOOP AT gt_vlpma INTO gs_vlpma.
      AT END OF matnr.
        SUM.

        READ TABLE gt_alv ASSIGNING FIELD-SYMBOL(<lfs_alv>) WITH KEY werks = 
          gs_vlpma-werks
                                                                      matnr = 
       gs_vlpma-matnr BINARY SEARCH.

        IF <lfs_alv> IS ASSIGNED.
          <lfs_alv>-rfmng = gs_vlpma-rfmng.
          <lfs_alv>-rfwrt = gs_vlpma-rfwrt.
          IF sy-subrc = 0.
            MODIFY TABLE gt_alv FROM <lfs_alv> TRANSPORTING rfmng rfwrt.
          ENDIF.
        ENDIF.
      ENDAT.

    ENDLOOP.

    SORT gt_alv BY werks matnr plnnr.
    DELETE ADJACENT DUPLICATES FROM gt_alv COMPARING werks matnr.
    " move currency from gt_ver to gt_alv.
    LOOP AT gt_alv INTO DATA(gs_alv).

      READ TABLE gt_ver INTO gs_ver WITH KEY werks = gs_alv-werks
                                                      matnr = gs_alv-matnr BINARY 
         SEARCH.
      IF sy-subrc = 0.

        gs_alv-waers =  gs_ver-waers.

        MODIFY gt_alv FROM gs_alv TRANSPORTING waers.

      ENDIF.

      LOOP AT gt_alv INTO DATA(gs_alv1).
        READ TABLE gt_alv INTO gs_alv WITH KEY werks = gs_alv-werks
                                                              matnr = gs_alv-matnr
                                                              plnnr = gs_alv-plnnr 
         BINARY SEARCH.

        READ TABLE gt_alv INTO gs_alv1 WITH KEY werks = gs_alv1-werks
                                                              matnr = gs_alv1-matnr
                                                              plnnr = gs_alv1-plnnr 
        BINARY SEARCH.

        IF ( gs_alv-plnnr EQ gs_alv1-plnnr AND gs_alv-zkriz NE gs_alv1-zkriz ).
          gs_alv-delta = gs_alv-rfmng - gs_alv1-rfmng.
          gs_alv-delta1 = gs_alv-rfwrt - gs_alv1-rfwrt.

          IF gs_alv-delta < 0 OR gs_alv-delta1 < 0.

            gs_alv-delta = 0.

            gs_alv-delta1 = 0.

          ELSE.
            MODIFY TABLE gt_alv FROM gs_alv TRANSPORTING delta delta1.
          ENDIF.
        ENDIF.

      ENDLOOP.
    ENDLOOP.
  ENDIF.
  cl_salv_table=>factory(
       EXPORTING
         list_display   = abap_false
       IMPORTING
         r_salv_table   = go_alv
       CHANGING
         t_table        = gt_alv  ).

  go_alv->get_functions( )->set_all( ).
  lo_aggrs = go_alv->get_aggregations( ).

  CALL METHOD go_alv->get_sorts "get sorts
    RECEIVING
      value = lr_sort.

  TRY.

      CALL METHOD lr_sort->add_sort "add column sort
        EXPORTING
          columnname = 'PLNNR' "sort column always keyfield
   *             POSITION   =
   *             SEQUENCE   = IF_SALV_C_SORT=>SORT_UP
   *             SUBTOTAL   = IF_SALV_C_BOOL_SAP=>FALSE
   *             GROUP      = IF_SALV_C_SORT=>GROUP_NONE
   *             OBLIGATORY = IF_SALV_C_BOOL_SAP=>FALSE
        RECEIVING
          value      = lr_sort_column.

  ENDTRY.

  TRY.
      CALL METHOD lo_aggrs->add_aggregation "add aggregation
        EXPORTING
          columnname  = 'RFWRT' "aggregation column name
          aggregation = if_salv_c_aggregation=>total. "aggregation type

    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
   ENDTRY.

   TRY.
      CALL METHOD lo_aggrs->add_aggregation "add aggregation
        EXPORTING
          columnname  = 'RFMNG' "aggregation column name
          aggregation = if_salv_c_aggregation=>total. "aggregation type

    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
   ENDTRY.

   TRY.
      CALL METHOD lo_aggrs->add_aggregation "add aggregation
        EXPORTING
          columnname  = 'WERKS' "aggregation column name
          aggregation = if_salv_c_aggregation=>total. "aggregation type

    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
   ENDTRY.

   TRY.
      CALL METHOD lo_aggrs->add_aggregation "add aggregation
        EXPORTING
          columnname  = 'DELTA' "aggregation column name
          aggregation = if_salv_c_aggregation=>total. "aggregation type

    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
  ENDTRY.

  TRY.
      CALL METHOD lo_aggrs->add_aggregation "add aggregation
        EXPORTING
          columnname  = 'DELTA1' "aggregation column name
          aggregation = if_salv_c_aggregation=>total. "aggregation type

    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
  ENDTRY.

  *Bring the total line to top
  lo_aggrs->set_aggregation_before_items( ).

  TRY.
      CALL METHOD lr_sort_column->set_subtotal "add subtotal
        EXPORTING
          value = if_salv_c_bool_sap=>true.
    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
  ENDTRY.

  TRY.
      CALL METHOD lr_sort->add_sort
        EXPORTING
          columnname = 'RFMNG'
          subtotal   = if_salv_c_bool_sap=>true.

      lr_sort->set_compressed_subtotal( 'RFMNG' ).

    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
   ENDTRY.

   TRY.
      CALL METHOD lr_sort->add_sort
        EXPORTING
          columnname = 'PLNNR'
          subtotal   = if_salv_c_bool_sap=>true.

      lr_sort->set_compressed_subtotal( 'PLNNR' ).

    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
    ENDTRY.

    TRY.
      CALL METHOD lr_sort->add_sort
        EXPORTING
          columnname = 'MATNR'
          subtotal   = if_salv_c_bool_sap=>true.

      lr_sort->set_compressed_subtotal( 'MATNR' ).
    CATCH cx_salv_not_found .                       "#EC NO_HANDLER
    CATCH cx_salv_existing .                        "#EC NO_HANDLER
    CATCH cx_salv_data_error .                      "#EC NO_HANDLER
  ENDTRY.

  go_layout = go_alv->get_layout( ).
  g_key-report = sy-repid.
  go_layout->set_key( g_key ).
  go_layout->set_default( 'X' ).
  go_layout->set_save_restriction( if_salv_c_layout=>restrict_user_dependant ).
  go_layout->set_default( 'X' ).
  go_columns = go_alv->get_columns( ).

  *add translation for Field Value =
  s_text = 'Delta Quantity'(101). " TEXT-103.
  m_text = 'Delta Quantity'(102). " TEXT-104.
  l_text = 'Delta Quantity'(103). " TEXT-105.

  s_text1 = 'Delta Value'(201).     "TEXT-203.
  m_text1 = 'Delta Value'(202).     "TEXT-204.
  l_text1 = 'Delta Value'(203).     "TEXT-205.

  TRY.
      go_column = go_columns->get_column( 'DELTA' ).
      go_column->set_short_text( s_text ).
      go_column->set_medium_text( m_text ).
      go_column->set_long_text( l_text ).

      go_column = go_columns->get_column( 'DELTA1' ).
      go_column->set_short_text( s_text1 ).
      go_column->set_medium_text( m_text1 ).
      go_column->set_long_text( l_text1 ).
  ENDTRY.
  go_columns->set_optimize( abap_true ).
  go_alv->display( ).


 WHEN OTHERS.

 ENDCASE.

答案 2 :(得分:-1)

为了快速进行改进,请在LOOP语句中将SELECT替换为SELECT ... FOR ALL ENTRIES

例如,代替

LOOP AT gt_vlpma INTO ls_vlpma.
  SELECT ... FROM vbfa
    INTO corresponding fields of TABLE gt_ver
    WHERE
      vbelv = ls_vlpma-vbeln and
      matnr = ls_vlpma-matnr AND
      " some other conditions
      erdat IN so_erdat.
  append lines of gt_ver to gt_ver1.
endloop.

尝试

SELECT ... FROM vbfa
  INTO corresponding fields of TABLE gt_ver
  FOR ALL ENTRIES IN gt_vlpma 
  WHERE
    vbelv = gt_vlpma-vbeln and
    matnr = gt_vlpma-matnr AND
    " some other conditions
    erdat IN so_erdat.
append lines of gt_ver to gt_ver1.

要获得更多改进,请用SELECT ... INTO TABLE代替。这需要大量重组代码,而我无法快速概述出代码的位置和精确度。

如果您在SAP HANA上运行,则为了进一步改进,请将整个代码放入ABAP管理的数据库过程(AMDP)中。您的代码基本上是几个复杂的JOIN的序列化。将其转换为数据库过程会将所有代码和结果集保留在数据库内,并且仅需要将最终结果传输到ABAP。

为最终改善,请尝试将整个程序建模为视图。该程序只需要一个平面表,并且您没有使用任何花哨的操作,因此应该可行。