PROGRAM
*&---------------------------------------------------------------------*
*& Report yab_dynamic_select
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT yab_dynamic_select.
TYPES: BEGIN OF ty_s_clause,
line TYPE char72,
END OF ty_s_clause.
CLASS lcl_handler_events DEFINITION.
PUBLIC SECTION.
METHODS: on_user_command FOR EVENT added_function OF cl_salv_events
IMPORTING e_salv_function.
ENDCLASS.
DATA: wa_fields TYPE dfies,
wa_fields_display TYPE rsdsfields,
it_list TYPE vrm_values,
wa_list TYPE vrm_value,
lv_er TYPE sy-subrc,
wa_pfkey TYPE rsdspfkey,
it_table_main TYPE REF TO data,
it_trange TYPE rsds_trange,
lv_table TYPE dfies-tabname,
wa_condtab TYPE hrcond,
it_condtab TYPE STANDARD TABLE OF hrcond,
it_field_display TYPE STANDARD TABLE OF rsdsfields,
it_where_clause TYPE STANDARD TABLE OF ty_s_clause,
it_fields TYPE STANDARD TABLE OF dfies,
lv_selid TYPE dynselid,
lc_status TYPE sypfkey VALUE 'Y_STATUS',
it_range TYPE rsds_trange,
t_rows TYPE salv_t_row,
it_column TYPE salv_t_column,
l_row TYPE i,
lo_table TYPE REF TO cl_salv_table,
it_table_del TYPE REF TO data,
lo_column TYPE REF TO cl_salv_columns,
lo_selections TYPE REF TO cl_salv_selections,
lo_coloumns TYPE REF TO cl_salv_columns,
lo_layout TYPE REF TO cl_salv_layout,
lo_lcl_events TYPE REF TO lcl_handler_events,
lo_events TYPE REF TO cl_salv_events_table,
it_table_copy TYPE REF TO data.
FIELD-SYMBOLS:<fs_main_table> TYPE ANY TABLE,
<fs_table_copy> TYPE INDEX TABLE,
<fs_table_del> TYPE INDEX TABLE.
SELECTION-SCREEN : BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
PARAMETERS:p_table TYPE tabname OBLIGATORY.
SELECTION-SCREEN:END OF BLOCK b1.
SELECTION-SCREEN:BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002.
PARAMETERS : p_fields TYPE dfies-fieldname AS LISTBOX VISIBLE LENGTH 20 USER-
COMMAND uc.
SELECTION-SCREEN:END OF BLOCK b2.
CLASS lcl_handler_events IMPLEMENTATION.
METHOD on_user_command.
PERFORM handler_user_command USING e_salv_function <fs_main_table>.
ENDMETHOD.
ENDCLASS.
AT SELECTION-SCREEN ON p_table.
IF p_table IS NOT INITIAL.
*Bring fields name of the table enter in the P_table Parameter in P_fields
parameter
CALL FUNCTION 'DDIF_FIELDINFO_GET'
EXPORTING
tabname = p_table " Name of the Table (of the Type) for
which Information is Req
TABLES
dfies_tab = it_fields " Field List if Necessary
EXCEPTIONS
not_found = 1
internal_error = 2.
IF sy-subrc = 0.
DATA :lv_num TYPE char3 VALUE '1'.
IF it_list IS INITIAL.
LOOP AT it_fields INTO DATA(wa_fields).
wa_list-key = lv_num.
wa_list-text = wa_fields-fieldname.
APPEND wa_list TO it_list.
lv_num = lv_num + 1.
CONDENSE lv_num.
ENDLOOP.
CLEAR lv_num.
ENDIF.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
id = 'P_FIELDS' " Name of Value Set
values = it_list
EXCEPTIONS
id_illegal_name = 1.
IF sy-subrc <> 0.
MESSAGE |function moduel 'VRM_SET_VALUES' failed with error with sy-
subrc = { sy-subrc }| TYPE 'S' DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ENDIF.
ELSE.
MESSAGE |function moduel 'DDIF_FIELDINFO_GET' failed with error with
sy-subrc = { sy-subrc }| TYPE 'S' DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ENDIF. " IF sy-subrc = 0.
ENDIF. "IF p_table IS NOT INITIAL.
AT SELECTION-SCREEN ON p_fields.
IF p_fields IS NOT INITIAL.
CLEAR it_field_display.
DATA(wa_get_fields) = VALUE #( it_list[ key = p_fields ] OPTIONAL ).
IF wa_get_fields IS NOT INITIAL.
DATA(wa_fields) = VALUE #( it_fields[ fieldname = wa_get_fields-text ]
OPTIONAL ).
IF wa_fields IS NOT INITIAL.
wa_fields_display-tablename = wa_fields-tabname.
wa_fields_display-fieldname = wa_fields-fieldname.
wa_fields_display-type = wa_fields-inttype.
APPEND wa_fields_display TO it_field_display.
ENDIF.
ENDIF.
ENDIF.
IF it_field_display IS NOT INITIAL.
* POP-up window for the selected fields
IF sy-ucomm <> 'ONLI'.
CALL FUNCTION 'FREE_SELECTIONS_INIT'
EXPORTING
kind = 'F' " Type of field list
IMPORTING
selection_id = lv_selid " Identification for
FREE_SELECTIONS_DIALOG
TABLES
fields_tab = it_field_display
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 = 0.
CALL FUNCTION 'FREE_SELECTIONS_DIALOG'
EXPORTING
selection_id = lv_selid " The SELID returned by
FREE_SELECTIONS_INIT
title = 'Enter Value' " Selection screen title
as_window = 'X'
pfkey = wa_pfkey " Individual GUI status (status +
program).
tree_visible = ''
IMPORTING
field_ranges = it_trange " Selections in form of RANGES
tables
TABLES
fields_tab = it_field_display " Returns selected fields
EXCEPTIONS
internal_error = 1
no_action = 2
selid_not_found = 3
illegal_status = 4.
IF sy-subrc = 0.
ELSE.
MESSAGE |function mosule ''FREE_SELECTIONS_DIALOG' failed with
sy-subrc = { sy-subrc } | TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
ENDIF. " IF sy-subrc = 0
ENDIF. " IF sy-ucomm <> 'ONLI'.
ENDIF. "IF it_field_display IS NOT INITIAL.
START-OF-SELECTION.
IF p_table IS INITIAL.
MESSAGE |table fields cannot be black| TYPE 'S' DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ELSE.
*Check if user enter valid table name in P_table parameter
CALL FUNCTION 'DD_EXIST_TABLE'
EXPORTING
tabname = p_table " Table name
status = 'A' " A: Exists actively, M: any N: revised
* ntab = SPACE
IMPORTING
subrc = lv_er " 0: exists, 4: does not exist
EXCEPTIONS
wrong_status = 1.
IF sy-subrc <> 0.
MESSAGE |Function Module failed with sy-subrc = { sy-subrc }| TYPE 'I'
DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ENDIF.
IF lv_er <> 0.
MESSAGE |{ p_table } is not a valid table| TYPE 'I' DISPLAY LIKE 'E'.
ENDIF.
IF it_trange IS INITIAL.
MESSAGE |FIELDS IS NOT SELECTED| TYPE 'I' DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ENDIF.
*create dynamic structure of target table
DATA(lo_struct_desc) = cl_abap_structdescr=>describe_by_name( p_name =
p_table ).
*create table description object
TRY.
DATA(lo_table_desc) = cl_abap_tabledescr=>create(
p_line_type = CAST #(
lo_struct_desc )
p_table_kind =
cl_abap_tabledescr=>tablekind_std
p_unique = abap_false
).
CATCH cx_sy_table_creation INTO DATA(lv_mgs). "
MESSAGE lv_mgs->get_text( ) TYPE 'E'.
ENDTRY.
CREATE DATA it_table_main TYPE HANDLE lo_table_desc.
ASSIGN it_table_main->* TO <fs_main_table>.
ENDIF. " IF p_table IS INITIAL.
wa_list = VALUE #( it_list[ key = p_fields ] OPTIONAL ).
LOOP AT it_trange INTO DATA(wa_trange).
LOOP AT wa_trange-frange_t INTO DATA(wa_rsdselopt).
LOOP AT wa_rsdselopt-selopt_t INTO DATA(wa_sel_opt).
wa_condtab-field = wa_list-text.
wa_condtab-opera = wa_sel_opt-option.
wa_condtab-low = wa_sel_opt-low.
wa_condtab-high = wa_sel_opt-high.
APPEND wa_condtab TO it_condtab.
ENDLOOP.
ENDLOOP.
ENDLOOP.
IF wa_sel_opt IS NOT INITIAL.
CALL FUNCTION 'RH_DYNAMIC_WHERE_BUILD'
EXPORTING
dbtable = lv_table " Database Table
TABLES
condtab = it_condtab " Condition Table
where_clause = it_where_clause " Where Clause
EXCEPTIONS
empty_condtab = 1
no_db_field = 2
unknown_db = 3
wrong_condition = 4.
IF sy-subrc <> 0.
* MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
* WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
MESSAGE |function module 'RH_DYNAMIC_WHERE_BUILD' failed with sy-subrc
{ sy-subrc }| TYPE 'I' DISPLAY LIKE 'E'.
ENDIF.
ENDIF.
PERFORM get_data.
FORM get_data.
SELECT *
FROM (p_table)
INTO TABLE <fs_main_table>
WHERE (it_where_clause).
IF sy-subrc <> 0.
MESSAGE |no data found in { p_table } for selected parameter| TYPE 'I'
DISPLAY LIKE 'E'.
LEAVE LIST-PROCESSING.
ENDIF.
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = lo_table " Basis Class Simple ALV Tables
CHANGING
t_table = <fs_main_table>
).
CATCH cx_salv_msg INTO DATA(lv_mgs). "
MESSAGE lv_mgs->get_longtext( ) TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
lo_table->set_screen_status(
EXPORTING
report = sy-repid " ABAP Program: Current Master Program
pfstatus = lc_status " Screens, Current GUI Status
set_functions = lo_table->c_functions_all " ALV: Data Element for
Constants
).
lo_column = lo_table->get_columns( ).
lo_column->set_optimize(
* value = IF_SALV_C_BOOL_SAP~TRUE
).
lo_selections = lo_table->get_selections( ).
lo_selections->set_selection_mode(
value = IF_SALV_C_SELECTION_MODE=>cell
).
t_rows = lo_selections->get_selected_rows( ).
lo_table->get_functions( )->set_all(
value = if_salv_c_bool_sap=>true
).
lo_layout = lo_table->get_layout( ).
lo_table->get_display_settings( )->set_striped_pattern( value = abap_true
).
lo_events = lo_table->get_event( ).
CREATE OBJECT lo_lcl_events.
SET HANDLER lo_lcl_events->on_user_command FOR lo_events.
lo_selections = lo_table->get_selections( ).
lo_selections->set_selected_columns( it_column ).
lo_table->display( ).
ENDFORM.
FORM handler_user_command USING i_ucomm TYPE salv_de_function
fs_orginal_table TYPE ANY TABLE.
lo_selections = lo_table->get_selections( ).
t_rows = lo_selections->get_selected_rows( ).
DATA(lo_stru_del) = cl_abap_structdescr=>describe_by_name( p_name = p_table
).
"create table describtion object
TRY.
DATA(lo_table_del) = cl_abap_tabledescr=>create(
p_line_type = CAST #( lo_stru_del )
p_table_kind =
cl_abap_tabledescr=>tablekind_std
p_unique = abap_false
).
CATCH cx_sy_table_creation INTO DATA(lv_mgs). "
MESSAGE lv_mgs->get_text( ) TYPE 'E'.
ENDTRY.
CREATE DATA it_table_del TYPE HANDLE lo_table_del.
CREATE DATA it_table_copy TYPE HANDLE lo_table_del.
ASSIGN it_table_del->* TO <fs_table_copy>.
ASSIGN it_table_del->* TO <fs_table_del>.
ASSIGN fs_orginal_table TO <fs_table_copy>.
FIELD-SYMBOLS : <wa_copy> TYPE any.
DATA:lv_answer TYPE char1.
CASE i_ucomm.
WHEN '&DEL'.
LOOP AT t_rows INTO l_row.
READ TABLE <fs_table_copy> ASSIGNING <wa_copy> INDEX l_row.
APPEND <wa_copy> TO <fs_table_del>.
ENDLOOP.
DESCRIBE TABLE <fs_table_del> LINES DATA(lv_lines).
IF lv_lines > 0.
"data is selected for the ALV list to delete and then show the
confirmation message
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
titlebar = |Delete Records| " Title of dialog box
text_question = |Do you want to delete { lv_lines }
entries from { p_table }| " Question text in dialog box
text_button_1 = |Yes| " Text on the first pushbutton
text_button_2 = |No| " Icon on first pushbutton
default_button = '1' " Cursor position
display_cancel_button = '' " Button for displaying cancel
pushbutton
IMPORTING
answer = lv_answer " Return values: '1', '2', 'A'
EXCEPTIONS
text_not_found = 1.
IF sy-subrc = 0.
IF lv_answer = '1'.
DELETE (p_table) FROM TABLE <fs_table_del>.
MESSAGE |{ lv_lines } entries deleted from { p_table } table
successfully| TYPE 'S'.
PERFORM get_data.
IF sy-ucomm = '&F03'.
CLEAR p_fields.
SET SCREEN 0.
ENDIF.
ENDIF.
ENDIF.
ENDIF." IF lv_lines > 0.
ENDCASE.
ENDFORM.
*&---------------------------------------------------------------------*
SELECTION SCREEN
OUTPUT
MENU PAINTER