ABAP/DEV/Динамические концепции

REPORT  zdynamic_alv MESSAGE-ID zdynamic_alv.
***********************************************************************
*---------------------------------------------------------------------*
*                Data Declaration
*---------------------------------------------------------------------*
*Type-Pools
TYPE-POOLS : rsds.
*Type Declaration
TYPES : ty_tabname(30) TYPE c,
        BEGIN OF ty_fieldinfo,
        text(60),
        END OF ty_fieldinfo,
        BEGIN OF ty_keyfields,
          fieldname TYPE fieldname,
        END OF ty_keyfields.
*Variable Declaration
DATA : v_tabname     TYPE help_info-tabname,
       v_fldnam      TYPE fieldname,
       v_lines       TYPE i,
       v_display     TYPE c,
       v_selfields   TYPE string,
       v_okcode      TYPE sy-ucomm,
       v_selid       TYPE rsdynsel-selid,
       v_actnum      TYPE sy-tfill,
       v_title       TYPE lvc_title.
* Reference Variable Declaration
DATA : ref_dyntab   TYPE REF TO data,
       ref_struct   TYPE REF TO cl_abap_structdescr,
       ref_alv      TYPE REF TO cl_salv_table,
       ref_func     TYPE REF TO cl_salv_functions,
       ref_display  TYPE REF TO cl_salv_display_settings.
*Field-Symbol Declaration
FIELD-SYMBOLS : <fs_wa> TYPE abap_compdescr,
               <fs_dyntab> TYPE STANDARD TABLE.
*Internal Table and Work Area Declaration
DATA : it_fldtab     TYPE STANDARD TABLE OF help_value,
       it_valuetab   TYPE STANDARD TABLE OF ty_tabname,
       it_dfies      TYPE STANDARD TABLE OF dfies,
       it_fieldinfo  TYPE STANDARD TABLE OF ty_fieldinfo,
       it_return     TYPE STANDARD TABLE OF ddshretval,
       it_dynpfields TYPE STANDARD TABLE OF dynpread,
       it_fcat       TYPE lvc_t_fcat,
       it_expr       TYPE rsds_texpr,
       it_where      TYPE rsds_twhere,
       it_seltab     TYPE STANDARD TABLE OF rsdstabs,
       it_selfields  TYPE STANDARD TABLE OF rsdsfields,
       it_keyfields  TYPE STANDARD TABLE OF ty_keyfields,
       it_wherecond   TYPE STANDARD TABLE OF rsdswhere,
       wa_wherecond  TYPE rsdswhere ,
       wa_keyfields  TYPE ty_keyfields,
       wa_seltab     TYPE rsdstabs,
       wa_selfields  TYPE rsdsfields,
       wa_where      TYPE rsds_where,
       wa_fcat       TYPE lvc_s_fcat,
       wa_dynpfields TYPE dynpread,
       wa_return     TYPE ddshretval,
       wa_fieldinfo  TYPE ty_fieldinfo,
       wa_dfies      TYPE dfies,
       wa_fldtab     TYPE help_value,
       wa_valuetab   TYPE ty_tabname.
*---------------------------------------------------------------------*
*                 Selection-Screen block1
*---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK block1 WITH FRAME TITLE text-000.
PARAMETERS : p_table TYPE tabname OBLIGATORY.       "Table Name
SELECTION-SCREEN END OF BLOCK block1.
*---------------------------------------------------------------------*
*                 Selection-Screen block2
*---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK block2 WITH FRAME TITLE text-002.
PARAMETERS : p_fnam1  TYPE fieldname,     "Field name from Given Table
             p_fnam2  TYPE fieldname,
             p_fnam3  TYPE fieldname,
             p_fnam4  TYPE fieldname,
             p_fnam5  TYPE fieldname,
             p_fnam6  TYPE fieldname,
             p_fnam7  TYPE fieldname,
             p_fnam8  TYPE fieldname,
             p_fnam9  TYPE fieldname,
             p_fnam10 TYPE fieldname.
SELECTION-SCREEN END OF BLOCK block2.
*---------------------------------------------------------------------*
*                 Selection-Screen block3
*---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK block3 WITH FRAME TITLE text-004.
PARAMETERS : p_max  TYPE i.                                               "Max Number of rows
SELECTION-SCREEN END OF BLOCK block3.
*---------------------------------------------------------------------*
*                At selection-Screen Output
*---------------------------------------------------------------------*
AT SELECTION-SCREEN OUTPUT.
  SET PF-STATUS  'PFSTAT1'.
  SET TITLEBAR    'TIT1'.
*---------------------------------------------------------------------*
*                F4 Help for Table name
*---------------------------------------------------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_table.
  PERFORM f4help_table_name.
*---------------------------------------------------------------------*
*                F4 Help for Field names
*---------------------------------------------------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fnam1.
  PERFORM f4help_fieldname.
*---------------------------------------------------------------------*
*                At Selection-Screen
*---------------------------------------------------------------------*
AT SELECTION-SCREEN.
  CLEAR : v_okcode.
  v_okcode = sy-ucomm.
  CASE v_okcode.
    WHEN 'SLOP'.        "Menu Item to display select options for given table key fields
      PERFORM get_selet_options.
    WHEN 'DISP'.          " Menu Item  to display ALV
      PERFORM display_alv.
    WHEN 'BACK'.
      LEAVE PROGRAM.
    WHEN 'CLR'.         " Menu item To clear all selections
      CLEAR : p_table,
              p_fnam1,
              p_fnam2,
              p_fnam3,
              p_fnam4,
              p_fnam5,
              p_fnam6,
              p_fnam7,
              p_fnam8,
              p_fnam9,
              p_fnam10,
              p_max,
              wa_where.
      REFRESH : it_where.
  ENDCASE.
*---------------------------------------------------------------------*
*                At Selection-Screen On Exit Command
*---------------------------------------------------------------------*
AT SELECTION-SCREEN ON EXIT-COMMAND.
  CLEAR : v_okcode.
  v_okcode = sy-ucomm.
  CASE v_okcode.
    WHEN 'TOP'  OR
         'EXIT'.
      LEAVE PROGRAM.
  ENDCASE.
*&---------------------------------------------------------------------&*
*&                 Subroutines                                                        &*
*&---------------------------------------------------------------------&*
*&---------------------------------------------------------------------*
*&      Form  f4help_table_name
*&---------------------------------------------------------------------*
FORM f4help_table_name .
  CLEAR   : v_tabname,
            v_fldnam,
            v_display.
  CLEAR   : it_valuetab,
            it_fldtab,
            wa_valuetab,
            wa_fldtab.

  REFRESH : it_valuetab,
             it_fldtab.
  v_tabname = 'DD02L'.
  v_fldnam  = 'TABNAME'.
  v_display = ' '.
*Fill fieldtab
  wa_fldtab-tabname    = 'DD02L'.
  wa_fldtab-fieldname  = 'TABNAME'.
  wa_fldtab-selectflag = 'X'.
  APPEND wa_fldtab TO it_fldtab.
*Fill Value Table
  SELECT tabname
    FROM dd02l
    INTO TABLE it_valuetab
   WHERE tabclass  = 'TRANSP' AND
         applclass = 'VA'     OR
         applclass = 'ME'     OR
         applclass = 'FB'.
*Call F4 Function
  CALL FUNCTION 'F4TOOL_F4FUNCTION_BRIDGE'
    EXPORTING
      tabname        = v_tabname
      fieldname      = v_fldnam
      display_only   = v_display
      window_title   = text-001
    IMPORTING
      selected_value = p_table
    TABLES
      value_tab      = it_valuetab
      fields_tab     = it_fldtab.

ENDFORM.                    " f4help_table_name

*&---------------------------------------------------------------------*
*&      Form  f4help_fieldname
*&---------------------------------------------------------------------*
FORM f4help_fieldname .
  CLEAR   : wa_fldtab,
            it_fldtab,
            v_tabname,
            v_fldnam.
  REFRESH : it_fldtab,
            it_fieldinfo.
  v_tabname = 'DD03T'.
  v_fldnam  = 'FIELDNAME'.
*Getting Field Info
  CALL FUNCTION 'DDIF_FIELDINFO_GET'
    EXPORTING
      tabname        = p_table
      langu          = sy-langu
    TABLES
      dfies_tab      = it_dfies
    EXCEPTIONS
      not_found      = 1
      internal_error = 2.

*Fill Value table
  LOOP AT it_dfies INTO wa_dfies.
    wa_fieldinfo-text = wa_dfies-fieldname.
    APPEND wa_fieldinfo TO it_fieldinfo.
    CLEAR wa_fieldinfo.
    wa_fieldinfo-text = wa_dfies-fieldtext.
    APPEND wa_fieldinfo TO it_fieldinfo.
    CLEAR wa_fieldinfo.
  ENDLOOP.
  CLEAR   : it_dfies,
            wa_dfies.
  REFRESH : it_dfies.
*Fill field Table
  wa_dfies-tabname    = 'DD03T'.
  wa_dfies-fieldname  = 'FIELDNAME'.
  wa_dfies-keyflag = 'X'.
  APPEND wa_dfies TO it_dfies.
  CLEAR wa_dfies.
  wa_dfies-tabname    = 'DD03T'.
  wa_dfies-fieldname  = 'DDTEXT'.
  wa_dfies-keyflag    = ' '.
  APPEND wa_dfies TO it_dfies.
  CLEAR wa_dfies.
*Call F4 function
  CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
    EXPORTING
      retfield        = v_fldnam
      dynpprog        = sy-repid
      dynpnr          = sy-dynnr
*     dynprofield     = 'P_FNAM1'    "This should not be passed.DOnno reason.because of this getting problem in display.
      window_title    = text-003
      value_org       = 'C'
      multiple_choice = 'X'
    TABLES
      value_tab       = it_fieldinfo
      field_tab       = it_dfies
      return_tab      = it_return
    EXCEPTIONS
      parameter_error = 1
      no_values_found = 2.
  IF sy-subrc EQ 0.
    IF NOT it_return[] IS INITIAL.
      DESCRIBE TABLE it_return LINES v_lines.
      IF v_lines GE 11.
        MESSAGE i000 WITH 'No Authorization To select more than 10 fields'.
      ELSE.
        LOOP AT it_return INTO wa_return.
          CASE sy-tabix.
            WHEN '1'.
              wa_dynpfields-fieldname  = 'P_FNAM1'.
              wa_dynpfields-fieldvalue = wa_return-fieldval.
              APPEND wa_dynpfields TO it_dynpfields.
            WHEN '2'.
              wa_dynpfields-fieldname  = 'P_FNAM2'.
              wa_dynpfields-fieldvalue = wa_return-fieldval.
              APPEND wa_dynpfields TO it_dynpfields.
            WHEN '3'.
              wa_dynpfields-fieldname  = 'P_FNAM3'.
              wa_dynpfields-fieldvalue = wa_return-fieldval.
              APPEND wa_dynpfields TO it_dynpfields.
            WHEN '4'.
              wa_dynpfields-fieldname  = 'P_FNAM4'.
              wa_dynpfields-fieldvalue = wa_return-fieldval.
              APPEND wa_dynpfields TO it_dynpfields.
            WHEN '5'.
              wa_dynpfields-fieldname  = 'P_FNAM5'.
              wa_dynpfields-fieldvalue = wa_return-fieldval.
              APPEND wa_dynpfields TO it_dynpfields.
            WHEN '6'.
              wa_dynpfields-fieldname  = 'P_FNAM6'.
              wa_dynpfields-fieldvalue = wa_return-fieldval.
              APPEND wa_dynpfields TO it_dynpfields.
            WHEN '7'.
              wa_dynpfields-fieldname  = 'P_FNAM7'.
              wa_dynpfields-fieldvalue = wa_return-fieldval.
              APPEND wa_dynpfields TO it_dynpfields.
            WHEN '8'.
              wa_dynpfields-fieldname  = 'P_FNAM8'.
              wa_dynpfields-fieldvalue = wa_return-fieldval.
              APPEND wa_dynpfields TO it_dynpfields.
            WHEN '9'.
              wa_dynpfields-fieldname  = 'P_FNAM9'.
              wa_dynpfields-fieldvalue = wa_return-fieldval.
              APPEND wa_dynpfields TO it_dynpfields.
            WHEN '10'.
              wa_dynpfields-fieldname  = 'P_FNAM10'.
              wa_dynpfields-fieldvalue = wa_return-fieldval.
              APPEND wa_dynpfields TO it_dynpfields.
          ENDCASE.
        ENDLOOP.
*Updating Screen Fields
        CALL FUNCTION 'DYNP_VALUES_UPDATE'
          EXPORTING
            dyname               = sy-cprog
            dynumb               = sy-dynnr
          TABLES
            dynpfields           = it_dynpfields
          EXCEPTIONS
            invalid_abapworkarea = 1
            invalid_dynprofield  = 2
            invalid_dynproname   = 3
            invalid_dynpronummer = 4
            invalid_request      = 5
            no_fielddescription  = 6
            undefind_error       = 7.
      ENDIF.
    ENDIF.
  ELSE.
    MESSAGE i000 WITH 'Please select atleast one field'.
  ENDIF.
ENDFORM.                    " f4help_fieldname*&---------------------------------------------------------------------*
*&      Form  create_dynamic_inttab
*&-------------------------------------------------------------------*
FORM create_dynamic_inttab .
  CLEAR   : wa_fcat.
  REFRESH : it_fcat.
*Get structure
  ref_struct ?= cl_abap_typedescr=>describe_by_name( p_table ).
*Build Field catlog
  LOOP AT ref_struct->components ASSIGNING <fs_wa>.
    IF <fs_wa>-name = p_fnam1 OR
       <fs_wa>-name = p_fnam2 OR
       <fs_wa>-name = p_fnam3  OR
       <fs_wa>-name = p_fnam4 OR
       <fs_wa>-name = p_fnam5 OR
       <fs_wa>-name = p_fnam6 OR
       <fs_wa>-name = p_fnam7 OR
       <fs_wa>-name = p_fnam8 OR
       <fs_wa>-name = p_fnam9 OR
       <fs_wa>-name = p_fnam10.
      wa_fcat-ref_table = p_table.
      wa_fcat-fieldname = <fs_wa>-name .
      wa_fcat-datatype  = <fs_wa>-type_kind.
      wa_fcat-decimals  = <fs_wa>-decimals.
      wa_fcat-col_opt   = ' '.              "Optimizaion is kept always
      APPEND wa_fcat TO it_fcat.
    ENDIF.
  ENDLOOP.
*Create Dynamic Internal Table
  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      it_fieldcatalog           = it_fcat
    IMPORTING
      ep_table                  = ref_dyntab
    EXCEPTIONS
      generate_subpool_dir_full = 1
      OTHERS                    = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
               WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ELSE.
    ASSIGN ref_dyntab->* TO <fs_dyntab>.
  ENDIF.
ENDFORM.                    " create_dynamic_inttab
*&---------------------------------------------------------------------*
*&      Form  get_data
*&---------------------------------------------------------------------*
FORM get_data .
  CONCATENATE p_fnam1 p_fnam2 p_fnam3 p_fnam4 p_fnam5 p_fnam6 p_fnam7 p_fnam8 p_fnam9 p_fnam10
        INTO  v_selfields
 SEPARATED BY space.
*Dynamic Select
  IF wa_where-where_tab IS INITIAL.
    SELECT (v_selfields)
      FROM (p_table)
      INTO TABLE <fs_dyntab>
     UP TO p_max ROWS.
  ELSE.
    SELECT (v_selfields)
      FROM (p_table)
      INTO TABLE <fs_dyntab>
     UP TO p_max ROWS
     WHERE (wa_where-where_tab).
  ENDIF.
ENDFORM.                    " get_data
*&---------------------------------------------------------------------*
*&      Form  display_alv
*&---------------------------------------------------------------------*
FORM display_alv .
*Validation for Fields
  IF p_fnam1 IS INITIAL AND
     p_fnam1 IS INITIAL AND
     p_fnam1 IS INITIAL AND
     p_fnam1 IS INITIAL AND
     p_fnam1 IS INITIAL AND
     p_fnam1 IS INITIAL AND
     p_fnam1 IS INITIAL AND
     p_fnam1 IS INITIAL AND
     p_fnam1 IS INITIAL AND
     p_fnam1 IS INITIAL .
    MESSAGE i000 WITH 'Please enter Atleast one field'.
  ELSE.
    PERFORM create_dynamic_inttab.
    PERFORM get_data.
*Main Method To generate ALV
    TRY.
        CALL METHOD cl_salv_table=>factory
          IMPORTING
            r_salv_table = ref_alv
          CHANGING
            t_table      = <fs_dyntab>.
      CATCH cx_salv_msg .
    ENDTRY.
*Activate ALV Generic Functions
    PERFORM set_alv_functions.
*Display Settings
    PERFORM set_display_settings.
*Display ALV
    CALL METHOD ref_alv->display.
  ENDIF.
ENDFORM.                    " display_alv*&---------------------------------------------------------------------*
*      Form  GET_SELET_OPTIONS
*&---------------------------------------------------------------------*
FORM get_selet_options .
*Fill Fieldtab and Table Tab
  PERFORM fill_selectiontabs.
*Initialization of Selection Screen
  CALL FUNCTION 'FREE_SELECTIONS_INIT'
    EXPORTING
      kind                     = 'T'
    IMPORTING
      selection_id             = v_selid
      where_clauses            = it_where
      expressions              = it_expr
      number_of_active_fields  = v_actnum
    TABLES
      tables_tab               = it_seltab
      fields_tab               = it_selfields
    EXCEPTIONS
      fields_incomplete        = 1
      fields_no_join           = 2
      field_not_found          = 3
      no_tables                = 4
      table_not_found          = 5
      expression_not_supported = 6
      incorrect_expression     = 7
      illegal_kind             = 8
      area_not_found           = 9
      inconsistent_area        = 10
      kind_f_no_fields_left    = 11
      kind_f_no_fields         = 12
      too_many_fields          = 13
      dup_field                = 14
      field_no_type            = 15
      field_ill_type           = 16
      dup_event_field          = 17
      node_not_in_ldb          = 18
      area_no_field            = 19.
  IF sy-subrc EQ 0.
    CALL FUNCTION 'FREE_SELECTIONS_DIALOG'
      EXPORTING
        selection_id            = v_selid
        title                   = ' '
        as_window               = 'X'
        tree_visible            = ' '
        as_subscreen            = ' '
      IMPORTING
        where_clauses           = it_where
        expressions             = it_expr
        number_of_active_fields = v_actnum
      TABLES
        fields_tab              = it_selfields
      EXCEPTIONS
        internal_error          = 1
        no_action               = 2
        selid_not_found         = 3
        illegal_status          = 4.
    IF sy-subrc EQ 0.
      READ TABLE it_where INTO wa_where WITH KEY tablename = p_table.
    ENDIF.
  ENDIF.
ENDFORM.                    " GET_SELET_OPTIONS
*&---------------------------------------------------------------------*
*&      Form  fill_selectiontabs
*&---------------------------------------------------------------------*

FORM fill_selectiontabs .
  CLEAR   : wa_seltab,
            wa_selfields.
  REFRESH : it_seltab,
            it_selfields.
*Fill Tabletab
  wa_seltab-prim_tab = p_table.
  APPEND wa_seltab TO it_seltab.
*Fill fields Tab
  SELECT fieldname
    FROM dd03l
    INTO TABLE it_keyfields
   WHERE tabname   = p_table AND
         keyflag   = 'X'     AND                       "To select only key fields
         fieldname NE 'MANDT'.
  LOOP AT it_keyfields INTO wa_keyfields.
    wa_selfields-tablename = p_table.
    wa_selfields-fieldname = wa_keyfields-fieldname.
    APPEND wa_selfields TO it_selfields.
  ENDLOOP.
ENDFORM.                    " fill_selectiontabs
*&---------------------------------------------------------------------*
*&      Form  set_alv_functions
*&---------------------------------------------------------------------*
FORM set_alv_functions .

*reate refrence for cl_salv_functions
  CALL METHOD ref_alv->get_functions
    RECEIVING
      value = ref_func.
*Activate All ALV generic Functions
  ref_func->set_all( abap_true ).
ENDFORM.                    " set_alv_functions
*&---------------------------------------------------------------------*
*      Form  set_display_settings
*&---------------------------------------------------------------------*
FORM set_display_settings .
*Get Dynamic Title depends on Table selected
  SELECT SINGLE ddtext
    FROM dd02t
    INTO v_title
   WHERE tabname     = p_table AND
         ddlanguage  = sy-langu.
  CONCATENATE v_title ':' 'Display Mode' INTO v_title SEPARATED BY space.
*Create reference for cl_salv_display_settings
  ref_display  = ref_alv->get_display_settings( ).
*Set Title Bar(List Header)
  ref_display->set_list_header( v_title ).
ENDFORM.                    " set_display_settings