REPORT z_demo_alv_refresh_button_4.
*>*********************************************************************
* This report reads and displays data from table MARA,                *
* using the FM : REUSE_ALV_LIST_DISPLAY                               *
* Button  > : displays the next N records                             *
* Button  < : displays the previous N records                         *
* Button I< : displays the first page                                 *
* Button >I : displays the last page                                  *
* When the buttons Sort up, sort down, Filter, Delete Filter are      *
* pressed, N record are still displayed                               *
*---------------------------------------------------------------------*
* Author : Michel PIOUD                                               *
* Email :   HomePage : http://www.oocities.org/mpioud *
*>*********************************************************************

SELECTION-SCREEN :
 BEGIN OF LINE,COMMENT 10(20) v_1 FOR FIELD p_max.          "#EC NEEDED
PARAMETERS p_max(2) TYPE n DEFAULT '33' OBLIGATORY.
SELECTION-SCREEN END OF LINE.

TYPE-POOLS: slis, kkblo.               " ALV global types

CONSTANTS:
  c_first_page TYPE syucomm VALUE '&CRB',
  c_next_page  TYPE syucomm VALUE '&CRR',
  c_prev_page  TYPE syucomm VALUE '&CRL',
  c_last_page  TYPE syucomm VALUE '&CRE'.

DATA:
  BEGIN OF gt_mara OCCURS 0,           " Data displayed
    matnr LIKE mara-matnr,             " Material number
    ernam LIKE mara-ernam,             " Name of Person who Created
    ersda LIKE mara-ersda,             " Creation date
    brgew LIKE mara-brgew,             " Gross weight
  END OF gt_mara,

  gt_mara_ftr LIKE gt_mara OCCURS 0,   " Data filtered
  gt_mara_all LIKE gt_mara OCCURS 0.   " Data readfrom DB

*---------------------------------------------------------------------*
INITIALIZATION.

  v_1 = 'Lines per page'.

*---------------------------------------------------------------------*
START-OF-SELECTION.

  SELECT matnr ernam ersda brgew
    INTO TABLE gt_mara_all
    FROM mara.

  gt_mara_ftr[] = gt_mara_all[].

  PERFORM f_read_data USING c_first_page.

  PERFORM f_display_data.

*---------------------------------------------------------------------*
*       Form  f_read_data
*---------------------------------------------------------------------*
FORM f_read_data USING u_ucomm TYPE syucomm.

  STATICS :
    l_1   TYPE sytabix,
    l_2   TYPE sytabix.

  DATA l_max TYPE sytabix.             " Internal table size

  DESCRIBE TABLE gt_mara_ftr LINES l_max.

  CASE u_ucomm.
    WHEN c_first_page.                 " 1st page
      l_1 = 1.
    WHEN c_prev_page.                  " Previous page
      SUBTRACT p_max FROM l_1.
      IF l_1 < 1.
        l_1 = 1.
      ENDIF.
    WHEN c_next_page.                  " Next page
      IF l_1 IS INITIAL.
        l_1 = 1.
      ELSE.
        ADD p_max TO l_1.
      ENDIF.

      IF l_1 > l_max.
        l_1 = l_max.
      ENDIF.
    WHEN c_last_page.                  " Last page
      l_1 = l_max - p_max + 1.
      IF l_1 < 1.
        l_1 = 1.
      ENDIF.
  ENDCASE.

  l_2 = l_1 + p_max - 1.

  IF l_2 > l_max.
    l_2 = l_max.
  ENDIF.

  REFRESH gt_mara.
  IF l_max > 0.
    APPEND LINES OF gt_mara_ftr FROM l_1
                                  TO l_2
                                  TO gt_mara.
  ENDIF.

ENDFORM.                               " F_READ_DATA
*---------------------------------------------------------------------*
*      Form  f_display_data
*---------------------------------------------------------------------*
FORM f_display_data.

* Macro definition
  DEFINE m_fieldcat.
    add 1 to ls_fieldcat-col_pos.
    ls_fieldcat-fieldname = &1.
    ls_fieldcat-ref_tabname = 'MARA'.
    append ls_fieldcat to lt_fieldcat.
  END-OF-DEFINITION.

  DEFINE m_sort.
    add 1 to ls_sort-spos.
    ls_sort-fieldname = &1.
    ls_sort-up        = &2.
    append ls_sort to lt_sort.
  END-OF-DEFINITION.

  DEFINE m_event_exit.
    clear ls_event_exit.
    ls_event_exit-ucomm = &1.
    ls_event_exit-after = 'X'.
    append ls_event_exit to lt_event_exit.
  END-OF-DEFINITION.

  DATA :
    ls_layout     TYPE slis_layout_alv,
    ls_fieldcat   TYPE slis_fieldcat_alv,
    lt_fieldcat   TYPE slis_t_fieldcat_alv,
    lt_sort       TYPE slis_t_sortinfo_alv,
    ls_sort       TYPE slis_sortinfo_alv,
    lt_event_exit TYPE slis_t_event_exit,
    ls_event_exit TYPE slis_event_exit.

* Build Sort Table
  m_sort 'MATNR' 'X'.

* Build Field Catalog
  m_fieldcat 'MATNR'.
  m_fieldcat 'ERNAM'.
  m_fieldcat 'ERSDA'.
  m_fieldcat 'BRGEW'.

* Build Event Exit Table
  m_event_exit c_first_page.           " 1st page
  m_event_exit c_prev_page.            " Previous page
  m_event_exit c_next_page.            " Next page
  m_event_exit c_last_page.            " Last page
  m_event_exit '&OUP'.                 " Sort up
  m_event_exit '&ODN'.                 " Sort Down
  m_event_exit '&ILT'.                 " Filter
  m_event_exit '&ILD'.                 " Delete Filter

  ls_layout-zebra = 'X'.

  CALL FUNCTION 'REUSE_ALV_LIST_DISPLAY'
       EXPORTING
            i_callback_program      = sy-cprog
            i_callback_user_command = 'USER_COMMAND'
            is_layout               = ls_layout
            it_fieldcat             = lt_fieldcat
            it_sort                 = lt_sort
            it_event_exit           = lt_event_exit
       TABLES
            t_outtab                = gt_mara.

ENDFORM.                               " F_DISPLAY_DATA
*---------------------------------------------------------------------*
*       FORM USER_COMMAND                                             *
*---------------------------------------------------------------------*
FORM user_command USING u_ucomm     TYPE syucomm
                        us_selfield TYPE slis_selfield.     "#EC CALLED

  CASE u_ucomm.
    WHEN c_first_page OR c_next_page OR
    c_prev_page OR c_last_page.        " Page F, P, N, L
      PERFORM f_read_data USING u_ucomm.             " Update gt_mara
      us_selfield-refresh = 'X'.
    WHEN '&OUP' OR '&ODN'.             " Sort
      PERFORM f_sort_big_table.
      PERFORM f_read_data USING c_first_page.
      us_selfield-refresh = 'X'.
    WHEN '&ILT'.                       " Filter
      PERFORM f_filter_data.
      PERFORM f_read_data USING c_first_page.
      us_selfield-refresh = 'X'.
    WHEN '&ILD'.                       " Delete filter
      gt_mara_ftr[] = gt_mara_all[].
      PERFORM f_read_data USING c_first_page.
      us_selfield-refresh = 'X'.
  ENDCASE.

ENDFORM.                               " USER_COMMAND
*---------------------------------------------------------------------*
*       Form  F_SORT_BIG_TABLE
*---------------------------------------------------------------------*
FORM f_sort_big_table.

  DATA:
    lt_sort_kkblo TYPE kkblo_t_sortinfo,
    lt_sort_slis  TYPE slis_t_sortinfo_alv.

* Read current ALV list information
  CALL FUNCTION 'REUSE_ALV_LIST_LAYOUT_INFO_GET'
       IMPORTING
            et_sort       = lt_sort_slis
       EXCEPTIONS
            no_infos      = 1
            program_error = 2
            OTHERS        = 3.

  IF sy-subrc NE 0.
    EXIT.
  ENDIF.

  CHECK NOT lt_sort_slis[] IS INITIAL.

* Format SLIS --> KKBLO
  CALL FUNCTION 'REUSE_ALV_TRANSFER_DATA'
       EXPORTING
            it_sort = lt_sort_slis
       IMPORTING
            et_sort = lt_sort_kkblo.

* The big tables must be sorted like the small one
  PERFORM fb_outtab_sort(saplkkbl) TABLES gt_mara_ftr
                                          lt_sort_kkblo
                                    USING 'X'
                                          'X'.

  PERFORM fb_outtab_sort(saplkkbl) TABLES gt_mara_all
                                          lt_sort_kkblo
                                    USING 'X'
                                          'X'.

ENDFORM.                               " F_SORT_BIG_TABLE
*---------------------------------------------------------------------*
*      Form  f_filter_data
*---------------------------------------------------------------------*
FORM f_filter_data.

  DATA:
    lt_filter_lvc   TYPE lvc_t_filt        WITH HEADER LINE,
    lt_filter_index TYPE lvc_t_fidx        WITH HEADER LINE,
    lt_filter_slis  TYPE slis_t_filter_alv WITH HEADER LINE.

* Read current ALV list information
  CALL FUNCTION 'REUSE_ALV_LIST_LAYOUT_INFO_GET'
       IMPORTING
            et_filter     = lt_filter_slis[]
       EXCEPTIONS
            no_infos      = 1
            program_error = 2
            OTHERS        = 3.

  IF sy-subrc NE 0.
    EXIT.
  ENDIF.

* Dirty Code
  LOOP AT lt_filter_slis.
    CLEAR lt_filter_lvc.
    MOVE-CORRESPONDING lt_filter_slis TO lt_filter_lvc.
    MOVE lt_filter_slis-or            TO lt_filter_lvc-sign.
    MOVE lt_filter_slis-order         TO lt_filter_lvc-option.
    MOVE lt_filter_slis-valut_int+13  TO lt_filter_lvc-low.
    MOVE lt_filter_slis+433           TO lt_filter_lvc-high.
    CLEAR lt_filter_lvc-valuf.
    CLEAR lt_filter_lvc-valut.
    CLEAR lt_filter_lvc-or.
    APPEND lt_filter_lvc.
  ENDLOOP.

* Find data to filter
  CALL FUNCTION 'LVC_FILTER_APPLY'
       EXPORTING
            it_filter       = lt_filter_lvc[]
       IMPORTING
            et_filter_index = lt_filter_index[]
       TABLES
            it_data         = gt_mara_all.

  gt_mara_ftr[] = gt_mara_all[].

  SORT lt_filter_index DESCENDING.
  LOOP AT lt_filter_index.
    DELETE gt_mara_ftr INDEX lt_filter_index.
  ENDLOOP.

ENDFORM.                               " F_FILTER_DATA
******** END OF PROGRAM Z_DEMO_ALV_REFRESH_BUTTON_4 *******************