ZFI_FBL3N – Sachkontenliste verdichtet

SAP leitet Daten von MM an FI weiter. Die Anzahl der Posten der Sachkontenliste kann sehr hoch sein. Eine Verdichtung in SAP ist möglich, hat aber viele schwerwiegende Nebeneffekte.

Fehlersuche erschwert

Materialbestandswertlisten unbrauchbar

Verlust der Information

Ursache ist, dass SAP nicht die Datenanzeige verdichtet, sondern die Datenbestände. Dadurch sind 1:1 Beziehungen nicht mehr vorhanden.

Alternativ kann die Datenanzeige verdichtet erfolgen. Da FBL3N sowieso schlecht performiert, ist dieses Programm ideal.

Absprungpunkte in die Belege, Anzeige der verdichteten Positionen und ein Gegenkonto zur Laufzeit berechnet sind weitere Features.

REPORT zfi_fbl3n.


*Programm Einzelpostensicht verdichtet
*xx
*05 HST20190812 Dipl.Ing.J.Stangl
* Gegenkonto
*04 2019-07-02 Dipl.Ing.J.Stangl
* Geschäftsjahr / Periode ergänzen
* Maximale Verdichtung ergänzt (ohne ZUONR, ohne BELNR)
*03 2019-07-01 Dipl.Ing.J.Stangl
* Verdichtet, unverdichtet ergänzt
* Anzahl der Zeilen ergänzt
* Anzahl der Positionen pro Beleg ergänzt
* Negatives Vorzeichen bei Betrag geändert
* Layout merken ergänzt
* Monat/Periode ergänzt
* Optimierung Where Clause
* Filter: Anzahl Positionen ergänzt
* Filter: Betrag ergänzt
* Filter: SHKZG ergänzt
*02 2019-06-17 Dipl.Ing.J.Stangl Änderungen für Verdichtung
*01 2019-06-01 Dipl.Ing.J.Stangl Erstversion

TABLES: bseg, bkpf, bsas, bsis.

SELECTION-SCREEN COMMENT 01(80) text-001.
SELECTION-SCREEN BEGIN OF BLOCK sach WITH FRAME TITLE text-011.
SELECT-OPTIONS so_hkont FOR bseg-hkont DEFAULT '8400'.
SELECT-OPTIONS so_bukrs FOR bseg-bukrs.
SELECTION-SCREEN SKIP.
SELECT-OPTIONS so_belnr FOR bseg-belnr. "DEFAULT '1900000'.
SELECTION-SCREEN END OF BLOCK sach.

SELECTION-SCREEN BEGIN OF BLOCK post WITH FRAME TITLE text-021.
SELECTION-SCREEN BEGIN OF BLOCK stat WITH FRAME TITLE text-022.

PARAMETERS:  p_offen  RADIOBUTTON GROUP b2.
PARAMETERS:  p_doffen LIKE bkpf-bldat DEFAULT sy-datum.
SELECTION-SCREEN SKIP.

PARAMETERS:  p_ausg  RADIOBUTTON GROUP b2.
SELECT-OPTIONS so_augdt FOR bseg-augdt DEFAULT sy-datum.
SELECTION-SCREEN SKIP.

PARAMETERS:  p_alle  RADIOBUTTON GROUP b2 DEFAULT 'X'.
SELECT-OPTIONS so_budat FOR bkpf-budat.
SELECT-OPTIONS so_bldat FOR bkpf-bldat.
SELECTION-SCREEN BEGIN OF LINE.
"selection-screen position .
SELECTION-SCREEN COMMENT (29) text-023 FOR FIELD p_gjahr.
PARAMETERS: p_gjahr LIKE bkpf-gjahr.
PARAMETERS: p_monat LIKE bkpf-monat.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK stat.

SELECTION-SCREEN END OF BLOCK post.

SELECTION-SCREEN BEGIN OF BLOCK anz WITH FRAME TITLE text-041.
PARAMETERS:  p_verd  RADIOBUTTON GROUP b3 DEFAULT 'X'.
PARAMETERS:  p_unver  RADIOBUTTON GROUP b3.
"PARAMETERS:  p_gegen  TYPE checkbox as listbox visible length 3 DEFAULT 'X' .
PARAMETERS:  p_gegen  TYPE xfeld DEFAULT 'X' .
SELECTION-SCREEN SKIP.
PARAMETERS:  p_maxv  TYPE xfeld DEFAULT ''.
SELECTION-SCREEN skip.
SELECTION-SCREEN BEGIN OF BLOCK anz2 WITH FRAME TITLE text-051.
SELECT-OPTIONS so_dmbtr FOR bsis-dmbtr.
DATA: lv_apos TYPE i.
SELECT-OPTIONS so_apos FOR lv_apos.
PARAMETERS: p_shkzg TYPE c DEFAULT 'B'.

SELECTION-SCREEN END OF BLOCK anz2.

SELECTION-SCREEN END OF BLOCK anz.


SELECTION-SCREEN BEGIN OF BLOCK list WITH FRAME TITLE text-031.
PARAMETERS: p_vari   TYPE slis_vari. "Layout Variante
SELECTION-SCREEN END OF BLOCK list.



TYPES: BEGIN OF ty_alv,
         zaehler   TYPE i,
         bemer(30) TYPE c,
         zuonr     TYPE bseg-zuonr,
         bukrs     TYPE bseg-bukrs,
         gjahr     TYPE bseg-gjahr,
         monat     TYPE bsis-monat,
         belnr     TYPE bseg-belnr,
         "buzei(3)     TYPE c,
         buzei     type bseg-buzei,
         bschl     TYPE bseg-bschl,
         shkzg     TYPE bseg-shkzg,
         mwskz     TYPE bseg-mwskz,
         dmbtr     TYPE bsis-dmbtr,
         wrbtr     TYPE bsis-wrbtr,
         pswsl     TYPE bsis-pswsl,
         waers     TYPE bsis-waers,
         augdt     TYPE bseg-augdt,
         budat     TYPE bkpf-budat,
         bldat     TYPE bkpf-bldat,
         blart     TYPE bkpf-blart,
         hkont     TYPE bseg-hkont,
         gkont     type gkont, "HST20190821
         gkart     type gkart, "HST20190821
         anzahl    TYPE i,
         ampel(4)  TYPE c,
       END OF ty_alv.
DATA: gt_alv TYPE STANDARD TABLE OF ty_alv,
      gs_alv TYPE ty_alv.



INITIALIZATION.

  perform init.

AT SELECTION-SCREEN OUTPUT.

  IF 1 = 0.
    LOOP AT SCREEN.
      IF screen-name = 'SO_BUKRS-LOW'.
        "IF screen-group1 = 'BUK'."5 mal vorhanden
        CLEAR so_bukrs[].
        GET PARAMETER ID 'BUK' FIELD so_bukrs-low.
        so_bukrs-sign = 'I'.
        so_bukrs-option = 'EQ'.
        APPEND so_bukrs.
        "screen-input = 0.
        "screen-invisible = abap_false.
        "screen-active = 0.
        MODIFY SCREEN.
      ENDIF.
    ENDLOOP.
  ENDIF.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_vari.
  PERFORM f4_alv_variant CHANGING p_vari.


AT SELECTION-SCREEN.


START-OF-SELECTION.
* Ausbaustufe
  "IF NOT p_offen IS INITIAL.
  "  cl_demo_output=>display( 'Ausbaumöglichkeit' ).
  "ENDIF.
  "IF NOT p_ausg IS INITIAL.
  "  cl_demo_output=>display( 'Ausbaumöglichkeit' ).
  "ENDIF.

  PERFORM collect_alv.
  PERFORM show_alv.

*----------------------------------------------------------------------*
*       CLASS cl_event_handler DEFINITION
*----------------------------------------------------------------------*

CLASS cl_event_handler DEFINITION.

  PUBLIC SECTION.

    CLASS-METHODS on_before_salv_function         " BEFORE_SALV_FUNCTION
      FOR EVENT if_salv_events_functions~before_salv_function
                  OF cl_salv_events_table
      IMPORTING e_salv_function.

    CLASS-METHODS on_after_salv_function          " AFTER_SALV_FUNCTION
      FOR EVENT if_salv_events_functions~before_salv_function
                  OF cl_salv_events_table
      IMPORTING e_salv_function.

    CLASS-METHODS on_added_function               " ADDED_FUNCTION
      FOR EVENT if_salv_events_functions~added_function
                  OF cl_salv_events_table
      IMPORTING e_salv_function.

    CLASS-METHODS on_top_of_page                  " TOP_OF_PAGE
      FOR EVENT if_salv_events_list~top_of_page
                  OF cl_salv_events_table
      IMPORTING r_top_of_page
                  page
                  table_index.

    CLASS-METHODS on_end_of_page                  " END_OF_PAGE
      FOR EVENT if_salv_events_list~end_of_page
                  OF cl_salv_events_table
      IMPORTING r_end_of_page
                  page.

    CLASS-METHODS on_double_click                 " DOUBLE_CLICK
      FOR EVENT if_salv_events_actions_table~double_click
                  OF cl_salv_events_table
      IMPORTING row
                  column.

    CLASS-METHODS on_link_click                   " LINK_CLICK
      FOR EVENT if_salv_events_actions_table~link_click
                  OF cl_salv_events_table
      IMPORTING row
                  column.
ENDCLASS.                    "cl_event_handler DEFINITION

*----------------------------------------------------------------------*
*       CLASS cl_event_handler IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS cl_event_handler IMPLEMENTATION.

  METHOD on_before_salv_function.
    "BREAK-POINT.
  ENDMETHOD.                    "on_before_salv_function

  METHOD on_after_salv_function.
    "BREAK-POINT.
  ENDMETHOD.                    "on_after_salv_function

  METHOD on_added_function.
    "BREAK-POINT.
  ENDMETHOD.                    "on_added_function

  METHOD on_top_of_page.
    "BREAK-POINT.
  ENDMETHOD.                    "on_top_of_page

  METHOD on_end_of_page.
    "BREAK-POINT.
  ENDMETHOD.                    "on_end_of_page

  METHOD on_double_click.
    PERFORM display_invoice TABLES gt_alv USING row column.
  ENDMETHOD.                    "on_double_click

  METHOD on_link_click.
    PERFORM action TABLES gt_alv USING row column.
  ENDMETHOD.                    "on_link_click
ENDCLASS.                    "cl_event_handler IMPLEMENTATION

*&---------------------------------------------------------------------*
*&      FORM init
*&---------------------------------------------------------------------*
*  Init of Screen Values for first run
*----------------------------------------------------------------------*
form init.
  DATA: lv_jahr(4), lv_tag(4) TYPE c.
  lv_jahr = sy-datum(4).
  lv_jahr = lv_jahr - 1. " - 5.
  lv_tag = sy-datum+6(2).
  lv_tag = '01'.

  CLEAR so_budat[].
  CONCATENATE lv_jahr sy-datum+4(2) lv_tag INTO so_budat-low.
  MOVE sy-datum TO so_budat-high.
  move '20180101' to so_budat-low.
  move '20181231' to so_budat-high.
  so_budat-sign = 'I'.
  so_budat-option = 'BT'.
  APPEND so_budat.
  MODIFY SCREEN.

  CLEAR so_augdt[].
  CONCATENATE lv_jahr sy-datum+4(2) lv_tag INTO so_augdt-low.
  MOVE sy-datum TO so_augdt-high.
  so_augdt-sign = 'I'.
  so_augdt-option = 'BT'.
  APPEND so_augdt.
  MODIFY SCREEN.

  CLEAR so_bukrs[].
  GET PARAMETER ID 'BUK' FIELD so_bukrs-low.
  so_bukrs-sign = 'I'.
  so_bukrs-option = 'EQ'.
  APPEND so_bukrs.
  MODIFY SCREEN.

*  CLEAR so_hkont[].
*  GET PARAMETER ID 'SAK' FIELD so_hkont-low.
*  IF so_hkont-low IS NOT INITIAL.
*    so_hkont-sign = 'I'.
*    so_hkont-option = 'EQ'.
*    APPEND so_hkont.
*    MODIFY SCREEN.
*  ENDIF.
endform.        "init


*&---------------------------------------------------------------------*
*&      FORM f4_alv_variant
*&---------------------------------------------------------------------*
*  Show available Variants for alv
*----------------------------------------------------------------------*



FORM f4_alv_variant  CHANGING lv_variant LIKE p_vari.
  DATA: variant  TYPE disvariant.
  DATA: lv_exit  TYPE c.

  variant-report = sy-repid.
  "variant-handle = '0001'.
  variant-username = sy-uname.
  CALL FUNCTION 'REUSE_ALV_VARIANT_F4'
    EXPORTING
      is_variant    = variant
      i_save        = 'A'
    IMPORTING
      es_variant    = variant
      e_exit        = lv_exit
    EXCEPTIONS
      not_found     = 1
      program_error = 2
      OTHERS        = 3.

  IF sy-subrc NE 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ELSE.
    IF lv_exit EQ space.
      lv_variant = variant-variant.
    ENDIF.
  ENDIF.


ENDFORM.                    " f4_alv_variant


*&---------------------------------------------------------------------*
*&      FORM call_transaction
*&---------------------------------------------------------------------*
*  Call standard transactions with authority check and progress indicator
*----------------------------------------------------------------------*
FORM call_transaction USING trx TYPE tcode.
  DATA: lv_message TYPE string.
  CONCATENATE 'Opening transaction' trx '...' INTO lv_message SEPARATED BY space. "#EC NOTEXT
  CALL FUNCTION 'AUTHORITY_CHECK_TCODE'
    EXPORTING
      tcode  = trx
    EXCEPTIONS
      ok     = 0
      not_ok = 1
      OTHERS = 2.
  IF sy-subrc NE 0.
    MESSAGE e172(00) WITH trx.
  ELSE.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        text = lv_message.
    CALL TRANSACTION trx AND SKIP FIRST SCREEN.
  ENDIF.
ENDFORM.  "call transaction



*&---------------------------------------------------------------------*
*&      FORM action
*&---------------------------------------------------------------------*
*  Call standard transactions with authority check and progress indicator
*----------------------------------------------------------------------*
FORM action TABLES gt_alv USING row TYPE salv_de_row column TYPE salv_de_column.
  if column eq 'GKONT'.
    PERFORM display_gkont TABLES gt_alv USING row column.
  else.
    PERFORM display_invoice TABLES gt_alv USING row column.
  endif.
endform.
*&---------------------------------------------------------------------*
*&      FORM display_gkont
*&---------------------------------------------------------------------*
*  Call standard transactions with authority check and progress indicator
*----------------------------------------------------------------------*

FORM display_gkont TABLES gt_alv USING row TYPE salv_de_row column TYPE salv_de_column.
  TRY.
      gs_alv  = gt_alv[ row ].
      if gs_alv-gkart = 'D'.
        SET PARAMETER ID: 'KUN' FIELD gs_alv-gkont.
        SET PARAMETER ID: 'BUK' FIELD gs_alv-bukrs.
        PERFORM call_transaction USING 'FD03'.
      elseif gs_alv-gkart = 'K'.
        SET PARAMETER ID: 'LIF' FIELD gs_alv-gkont.
        SET PARAMETER ID: 'BUK' FIELD gs_alv-bukrs.
        PERFORM call_transaction USING 'FK03'.
      elseif gs_alv-gkart = 'S'.
        SET PARAMETER ID: 'BLN' FIELD gs_alv-belnr.
        SET PARAMETER ID: 'GJR' FIELD gs_alv-gjahr.
        PERFORM call_transaction USING 'FB03'.
      endif.
    CATCH cx_sy_itab_line_not_found.
      BREAK-POINT.
      "Error message goes here
  ENDTRY.
ENDFORM.                "display_invoice
*&---------------------------------------------------------------------*
*&      FORM display_invoice
*&---------------------------------------------------------------------*
*  Call standard transactions with authority check and progress indicator
*----------------------------------------------------------------------*

FORM display_invoice TABLES gt_alv USING row TYPE salv_de_row column TYPE salv_de_column.
  TRY.
      gs_alv  = gt_alv[ row ].


    CATCH cx_sy_itab_line_not_found.
      BREAK-POINT.
      "Error message goes here
  ENDTRY.
  SET PARAMETER ID: 'BLN' FIELD gs_alv-belnr.
  SET PARAMETER ID: 'GJR' FIELD gs_alv-gjahr.
  PERFORM call_transaction USING 'FB03'.
  "BREAK-POINT.

ENDFORM.                "display_invoice


*&---------------------------------------------------------------------*
*&      Form  COLLECT_ALV
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
FORM collect_alv.
  DATA:
    where_clause TYPE string.

  CONCATENATE  ' ' 'a~budat IN @so_budat AND a~bldat IN @so_bldat' INTO where_clause SEPARATED BY space.
*Selektion der Daten
  IF p_alle EQ abap_true.
    IF p_gjahr IS NOT INITIAL AND p_monat IS NOT INITIAL.
      CONCATENATE ' ' 'a~gjahr eq @p_gjahr and a~monat eq @p_monat' INTO where_clause SEPARATED BY space.
    ELSE.
      CONCATENATE ' ' 'a~budat IN @so_budat AND a~bldat IN @so_bldat' INTO where_clause SEPARATED BY space.
    ENDIF.
  ENDIF.
  IF p_ausg EQ abap_true.
    CONCATENATE ' ' 'a~augdt IN @so_augdt' INTO where_clause SEPARATED BY space.
  ENDIF.
  IF p_offen EQ abap_true.
    CONCATENATE ' ' '( a~augdt GT @p_doffen or a~augdt EQ ' '''00000000'' ) ' INTO where_clause SEPARATED BY space.
  ENDIF.

* Verdichtet*****************************************************************
  IF p_verd EQ abap_true.
    IF p_maxv EQ abap_true. "Ohne Belnr ohne Zuonr
      SELECT
        '@0A@' AS ampel,
        ' ' AS bemer,
        SUM( CASE WHEN a~shkzg = 'S' THEN a~dmbtr  ELSE - a~dmbtr END ) AS dmbtr,
        a~pswsl,
        SUM( CASE WHEN a~shkzg = 'S' THEN a~wrbtr  ELSE - a~wrbtr END ) AS wrbtr,
          a~waers,
          a~bukrs, a~gjahr, a~monat,
          a~shkzg, a~hkont,
          a~blart, a~budat, a~bldat,
          a~augdt, a~bschl, a~mwskz,
            COUNT(*) AS anzahl
        FROM bsis AS a "UP TO 10 ROWS
        APPENDING CORRESPONDING FIELDS OF TABLE @gt_alv
        WHERE
        (where_clause)
        AND a~hkont IN @so_hkont
        AND a~belnr IN @so_belnr
        GROUP BY
        a~bukrs, a~gjahr, a~monat,
        a~pswsl,a~waers,
        a~shkzg, a~hkont,
        a~blart, a~budat, a~bldat,
        a~augdt, a~bschl, a~mwskz
        ORDER BY
        a~bukrs, a~gjahr, budat
       .
      SELECT
        "1 as zaehler,
        '@08@' AS ampel,
        ' ' AS bemer,
        SUM( CASE WHEN a~shkzg = 'S' THEN a~dmbtr  ELSE - a~dmbtr END ) AS dmbtr,
        a~pswsl,
        SUM( CASE WHEN a~shkzg = 'S' THEN a~wrbtr  ELSE - a~wrbtr END ) AS wrbtr,
          a~waers,
          a~bukrs, a~gjahr, a~monat,
          a~shkzg, a~hkont,
          a~blart, a~budat, a~bldat,
          a~augdt, a~bschl, a~mwskz,
                  COUNT(*) AS anzahl
        FROM bsas AS a
        "INNER   JOIN bkpf AS b ON a~gjahr = b~gjahr AND a~bukrs = b~bukrs AND a~belnr = b~belnr
        APPENDING CORRESPONDING FIELDS OF TABLE @gt_alv
        WHERE (where_clause)
        AND a~hkont IN @so_hkont
        AND a~belnr IN @so_belnr
        GROUP BY
        a~bukrs, a~gjahr, a~monat,
        a~pswsl,a~waers,
        a~shkzg, a~hkont,
        a~blart, a~budat, a~bldat,
        a~augdt, a~bschl, a~mwskz
        ORDER BY
        a~bukrs, a~gjahr, budat
       .
    else. "Mit Belnr mit Zuonr
      SELECT
        "1 as zaehler,
        '@0A@' AS ampel,
        ' ' AS bemer,
        SUM( CASE       WHEN a~shkzg = 'S' THEN a~dmbtr  ELSE - a~dmbtr END ) AS dmbtr,
        a~pswsl,
        SUM( CASE       WHEN a~shkzg = 'S' THEN a~wrbtr  ELSE - a~wrbtr END ) AS wrbtr,
          a~waers,
          a~bukrs, a~gjahr, a~monat,
          a~belnr,
        min( a~buzei ) as buzei,
          "( CASE WHEN @p_gegen ne 'X'  THEN ' ' ELSE a~buzei END ) AS buzei,
          a~zuonr,
          a~shkzg, a~hkont,
          a~blart, a~budat, a~bldat,
          a~augdt, a~bschl, a~mwskz,
            COUNT(*) AS anzahl
        FROM bsis AS a "UP TO 10 ROWS
        "INNER   JOIN bkpf AS b ON a~gjahr = b~gjahr AND a~bukrs = b~bukrs AND a~belnr = b~belnr
        APPENDING CORRESPONDING FIELDS OF TABLE @gt_alv
        WHERE
        (where_clause)
        AND a~hkont IN @so_hkont
        AND a~belnr IN @so_belnr
        GROUP BY
        a~bukrs, a~gjahr, a~monat,
        belnr,
        "a~buzei,
        a~pswsl,a~waers,
        zuonr,
        a~shkzg, a~hkont,
        a~blart, a~budat, a~bldat,
        a~augdt, a~bschl, a~mwskz
        ORDER BY
        a~bukrs, a~gjahr, belnr
       .
      SELECT
        "1 as zaehler,
        '@08@' AS ampel,
        ' ' AS bemer,
        SUM( CASE WHEN a~shkzg = 'S' THEN a~dmbtr  ELSE - a~dmbtr END ) AS dmbtr,
        a~pswsl,
        SUM( CASE WHEN a~shkzg = 'S' THEN a~wrbtr  ELSE - a~wrbtr END ) AS wrbtr,
          a~waers,
          a~bukrs, a~gjahr, a~monat,
           a~belnr,
        min( a~buzei ) as buzei,
          "( CASE WHEN @p_gegen ne 'X'  THEN ' ' ELSE a~buzei END ) AS buzei,
          a~zuonr,
                    a~shkzg, a~hkont,
          a~blart, a~budat, a~bldat,
          a~augdt, a~bschl, a~mwskz,
                  COUNT(*) AS anzahl
        FROM bsas AS a
        "INNER   JOIN bkpf AS b ON a~gjahr = b~gjahr AND a~bukrs = b~bukrs AND a~belnr = b~belnr
        APPENDING CORRESPONDING FIELDS OF TABLE @gt_alv
        WHERE (where_clause)
        AND a~hkont IN @so_hkont
        AND a~belnr IN @so_belnr
        GROUP BY
        a~bukrs, a~gjahr, a~monat,
        belnr,
        "a~buzei,
        a~pswsl,a~waers,
        zuonr,
        a~shkzg, a~hkont,
        a~blart, a~budat, a~bldat,
        a~augdt, a~bschl, a~mwskz
        ORDER BY
        a~bukrs, a~gjahr, belnr
       .    ENDIF.
  ENDIF.
* Unverdichtet***************************************************************
    IF p_unver = abap_true. "Unverdichtet ohne Group by entspricht FBL3N
    SELECT
        "1 as zaehler,
        '@0A@' AS ampel,
        ' ' AS bemer,
        ( CASE       WHEN a~shkzg = 'S' THEN a~dmbtr  ELSE - a~dmbtr END ) AS dmbtr,
        a~pswsl,
        ( CASE       WHEN a~shkzg = 'S' THEN a~wrbtr  ELSE - a~wrbtr END ) AS wrbtr,
          a~waers,
          a~bukrs, a~gjahr, a~monat,
          ( CASE WHEN @p_maxv = 'X'  THEN ' ' ELSE a~belnr END ) AS belnr,
          "( CASE WHEN @p_maxv = 'X'  THEN ' ' ELSE a~buzei END ) AS buzei,
          a~buzei,
          ( CASE WHEN @p_maxv = 'X'  THEN ' ' ELSE a~zuonr END ) AS zuonr,
          a~shkzg, a~hkont,
          a~blart, a~budat, a~bldat,
          a~augdt, a~bschl, a~mwskz
        FROM bsis AS a "UP TO 10 ROWS
        "INNER   JOIN bkpf AS b ON a~gjahr = b~gjahr AND a~bukrs = b~bukrs AND a~belnr = b~belnr
        APPENDING CORRESPONDING FIELDS OF TABLE @gt_alv
        WHERE
        (where_clause)
        AND a~hkont IN @so_hkont
        AND a~belnr IN @so_belnr
        ORDER BY
        a~bukrs, a~gjahr, a~belnr
       .
    SELECT
      "1 as zaehler,
      '@08@' AS ampel,
      ' ' AS bemer,
      ( CASE WHEN a~shkzg = 'S' THEN a~dmbtr  ELSE - a~dmbtr END ) AS dmbtr,
      a~pswsl,
      ( CASE WHEN a~shkzg = 'S' THEN a~wrbtr  ELSE - a~wrbtr END ) AS wrbtr,
        a~waers,
        a~bukrs, a~gjahr, a~monat,
        ( CASE WHEN @p_maxv = 'X'  THEN ' ' ELSE a~belnr END ) AS belnr,
        "( CASE WHEN @p_maxv = 'X'  THEN ' ' ELSE a~buzei END ) AS buzei,
        a~buzei,
        ( CASE WHEN @p_maxv = 'X'  THEN ' ' ELSE a~zuonr END ) AS zuonr,
        a~shkzg, a~hkont,
        a~blart, a~budat, a~bldat,
        a~augdt, a~bschl, a~mwskz
      FROM bsas AS a
      "INNER   JOIN bkpf AS b ON a~gjahr = b~gjahr AND a~bukrs = b~bukrs AND a~belnr = b~belnr
      APPENDING CORRESPONDING FIELDS OF TABLE @gt_alv
      WHERE (where_clause)
      AND a~hkont IN @so_hkont
      AND a~belnr IN @so_belnr
      ORDER BY
      a~bukrs, a~gjahr, a~belnr
     .

  ENDIF.

  if p_gegen eq 'X' and p_maxv ne 'X'.
    LOOP AT gt_alv ASSIGNING FIELD-SYMBOL(<gs_alv>).

            CALL FUNCTION 'GET_GKONT'
          EXPORTING
            belnr           = <gs_alv>-belnr
            bukrs           = <gs_alv>-bukrs
            buzei           = <gs_alv>-buzei
            gjahr           = <gs_alv>-gjahr
            gknkz           = '3'
          IMPORTING
            gkont           = <gs_alv>-gkont
            koart           = <gs_alv>-gkart
          EXCEPTIONS
            belnr_not_found = 1
            buzei_not_found = 2
            gknkz_not_found = 3
            OTHERS          = 4.
          if sy-subrc ne 0.
                MESSAGE e534(0u) WITH 'Beleg ' 'nicht ' 'gefunden ' '.'.
          endif.
    ENDLOOP.
  endif.



ENDFORM.             "collect_alv

*&---------------------------------------------------------------------*
*&      Form  SHOW_ALV
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
* Show of alv
*----------------------------------------------------------------------*
FORM show_alv.

  "Initialisierung
  DATA: gr_salv TYPE REF TO cl_salv_table,
        gr_layout TYPE REF TO cl_salv_layout,
        ls_key    TYPE salv_s_layout_key.
  DATA: lr_functions TYPE REF TO cl_salv_functions_list,
        lo_events    TYPE REF TO cl_salv_events_table.

  DATA: lr_aggs TYPE REF TO cl_salv_aggregations.
  data: lr_exc  type ref to CX_SALV_ACCESS_ERROR.

* ALV aufbauen,
* gr_salv zeigt danach auf das Objekt,
* gt_alv ist die Tabelle, die als Info mitgegeben wird, wo die Daten zukünftig gespeichert werden.
  TRY.
      CALL METHOD cl_salv_table=>factory
        IMPORTING
          r_salv_table = gr_salv
        CHANGING
          t_table      = gt_alv.

      lo_events = gr_salv->get_event( ).

      SET HANDLER cl_event_handler=>on_before_salv_function FOR lo_events.
      SET HANDLER cl_event_handler=>on_after_salv_function FOR lo_events.
      SET HANDLER cl_event_handler=>on_added_function FOR lo_events.
      SET HANDLER cl_event_handler=>on_top_of_page FOR lo_events.
      SET HANDLER cl_event_handler=>on_end_of_page FOR lo_events.
      SET HANDLER cl_event_handler=>on_double_click FOR lo_events.
      SET HANDLER cl_event_handler=>on_link_click FOR lo_events.
    CATCH cx_salv_msg .

  ENDTRY.

  "Die Keydaten werden gefüllt
  ls_key-report = sy-repid.
  "gr_layout zeigt auf das Layout des ALV
  gr_layout  = gr_salv->get_layout( ).
  "Layout erhält Keydaten: Program Name
  gr_layout->set_key( ls_key ).
  "Layout Speichern erlaubt (3 Werte möglich) User can save
  "CHECK sy-slset IS NOT INITIAL.
  gr_layout->set_save_restriction( cl_salv_layout=>restrict_none ).
* Layout auf Kundenspezifisches Layout einstellen
*  IF sy-slset = 'CUS&Z_PPMDT_01'.
*    gr_layout->set_initial_layout( value = '/Z_PPMDT_TEL' ).
*  ENDIF.
  gr_layout->set_initial_layout( value = p_vari ).
  "lr_functions zeigt auf die Funktionen des ALV
  lr_functions = gr_salv->get_functions( ).
  "lr_functions einschalten
  "  lr_functions->set_default( ).      "minimal
  lr_functions->set_all( abap_true ). "Standard

* Feldkatalog ändern
  DATA: lr_columns TYPE REF TO cl_salv_columns_table,
        lr_column  TYPE REF TO cl_salv_column_table.

  lr_columns = gr_salv->get_columns( ).
* lr_columns->set_optimize( abap_true ).

  TRY.

      "MESSAGE i001(00) WITH 'Dies ist ein Test'.
      "Aggregation einstellen Summe
      lr_aggs = gr_salv->get_aggregations( ).
      lr_aggs->set_aggregation_before_items( abap_false ).
      lr_aggs->add_aggregation( 'DMBTR' ).


      lr_column ?= lr_columns->get_column( 'AMPEL' ).
      lr_column->set_short_text( 'Status').
      lr_column->set_medium_text( 'Status').
      lr_column->set_long_text( 'Aktueller Status').
      lr_column->set_icon( abap_true ).

      lr_column ?= lr_columns->get_column( 'BEMER' ).
      lr_column->set_short_text( 'Bemerk.').
      lr_column->set_medium_text( 'Bemerkung').
      lr_column->set_long_text( 'Bemerkung').
      lr_column->set_visible('').
      "lr_column->set_output_length( '1' ).

      lr_column ?= lr_columns->get_column( 'GJAHR' ).
      "lr_column->set_visible('').

      lr_column ?= lr_columns->get_column( 'BUKRS' ).
      "lr_column->set_visible('').

      "lr_column ?= lr_columns->GET_COUNT_COLUMN( ).

      lr_column ?= lr_columns->get_column( 'BLART' ).
      lr_column->set_output_length( '3' ).

      lr_columns->set_count_column( 'ZAEHLER').
      lr_column ?= lr_columns->get_column( 'ZAEHLER' ).
      lr_column->set_output_length( '3' ).
      "lr_columns->get_count_column

      lr_column ?= lr_columns->get_column( 'ANZAHL' ).
      lr_column->set_output_length( '3' ).
      IF p_verd EQ abap_true.
        lr_column->set_visible( abap_true ).
      ENDIF.
      IF p_unver EQ abap_true.
        lr_column->set_visible('').
      ENDIF.

      lr_column ?= lr_columns->get_column( 'BUZEI' ).
      IF p_gegen EQ 'X'.
        lr_column->set_visible( abap_false ).
      else.
        lr_column->set_visible( abap_true ).
      ENDIF.

      lr_column ?= lr_columns->get_column( 'GKONT' ).
      IF p_gegen EQ 'X'.
        lr_column->set_visible( abap_true ).
        lr_column->set_cell_type( if_salv_c_cell_type=>hotspot ).
      else.
        lr_column->set_visible( abap_false ).
      ENDIF.

      lr_column ?= lr_columns->get_column( 'GKART' ).
      lr_column->set_visible( abap_false ).


      lr_column ?= lr_columns->get_column( 'HKONT' ).
      lr_column->set_output_length( '6' ).

      lr_columns->set_column_position( columnname = 'MWSKZ' position = 1 ).
      lr_columns->set_column_position( columnname = 'SHKZG' position = 1 ).
      lr_columns->set_column_position( columnname = 'BSCHL' position = 1 ).
      lr_columns->set_column_position( columnname = 'WAERS' position = 1 ).
      lr_columns->set_column_position( columnname = 'WRBTR' position = 1 ).
      lr_columns->set_column_position( columnname = 'PSWSL' position = 1 ).
      lr_columns->set_column_position( columnname = 'DMBTR' position = 1 ).
      lr_columns->set_column_position( columnname = 'BLDAT' position = 1 ).
      lr_columns->set_column_position( columnname = 'BUDAT' position = 1 ).
      lr_columns->set_column_position( columnname = 'ZUONR' position = 1 ).
      lr_columns->set_column_position( columnname = 'BELNR' position = 1 ).
      lr_columns->set_column_position( columnname = 'MONAT' position = 1 ).
      lr_columns->set_column_position( columnname = 'GJAHR' position = 1 ).
      lr_columns->set_column_position( columnname = 'BUKRS' position = 1 ).
      lr_columns->set_column_position( columnname = 'HKONT' position = 1 ).
      lr_columns->set_column_position( columnname = 'AMPEL' position = 1 ).


      lr_column ?= lr_columns->get_column( 'BELNR' ).
      lr_column->set_cell_type( if_salv_c_cell_type=>hotspot ).


    CATCH cx_salv_existing INTO lr_exc.
            data l_text1(100) type c.
            l_text1 = lr_exc->get_text( ).
            MESSAGE i000(00) WITH l_text1.
            LEAVE LIST-PROCESSING.
    CATCH cx_salv_not_found.
      "cl_demo_output=>display('Error' ).
    CATCH cx_salv_data_error.
      cl_demo_output=>display('Error' ).

  ENDTRY.


  "Filter setzen
  DATA:
    lr_filters TYPE REF TO cl_salv_filters,
    lr_filter  TYPE REF TO cl_salv_filter,
    lv_low     TYPE salv_de_selopt_high,
    lv_high    TYPE salv_de_selopt_low,
    lv_sign    TYPE salv_de_selopt_sign,
    lv_option  TYPE salv_de_selopt_option.
  TRY.

      lr_filters = gr_salv->get_filters( ).
      "Filter Soll Haben Kennzeichen
      IF p_shkzg = 'S' OR p_shkzg = 'H'.
        lv_low = p_shkzg.
        lr_filter = lr_filters->add_filter(
          columnname = 'SHKZG'
          low        = lv_low ).
      ENDIF.
      "Filter Anzahl der Zeilen in der Verdichtung
      IF so_apos IS NOT INITIAL.
        lv_low = so_apos-low.
        lv_high = so_apos-high.
        lv_sign = so_apos-sign.
        lv_option = so_apos-option.
        lr_filter = lr_filters->add_filter(
          columnname = 'ANZAHL'
          sign       = lv_sign
          option     = lv_option
          low        = lv_low
          high       = lv_high ).
      ENDIF.
      "Filter Betrag von bis Einschränkung
      IF so_dmbtr IS NOT INITIAL.
        lv_low = so_dmbtr-low.
        lv_high = so_dmbtr-high.
        lv_sign = so_dmbtr-sign.
        lv_option = so_dmbtr-option.
        lr_filter = lr_filters->add_filter(
          columnname = 'DMBTR'
          sign       = lv_sign
          option     = lv_option
          low        = lv_low
          high       = lv_high ).
        lv_low = - so_dmbtr-high.
        lv_high =  - so_dmbtr-low.
        lv_sign = so_dmbtr-sign.
        lv_option = so_dmbtr-option.
        lr_filter->add_selopt(
          sign       = lv_sign
          option     = lv_option
          low        = lv_low
          high       = lv_high ).
      ENDIF.
      "lr_filter = lr_filters->get_filter( 'SHKZG' ).
      "lr_filter->add_selopt( low = 'S' ).
    CATCH cx_salv_not_found cx_salv_data_error cx_salv_existing. "#EC NO_HANDLER
      cl_demo_output=>display('Error' ).
  ENDTRY.



* Ausgabe
  gr_salv->display( ).
ENDFORM.              "show_alv