Tuesday, May 12, 2026

Sample program on how to read a decision table dynamically

 Decision tables are easier to maintain by customer and they can be used as a replacement for TVARVC. Here is a sample program below which can be used to create a method in a utility class to read a decision table.


*&---------------------------------------------------------------------*
*& Report ZGB_DEC
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zgb_dec.

DATAlo_factory         TYPE REF TO          if_fdt_factory.
DATAlt_table_data        TYPE                 if_fdt_decision_table=>ts_table_data.
DATAlo_decision_table TYPE REF TO          cl_fdt_decision_table,
      lo_dec_table      TYPE REF TO          if_fdt_decision_table.


PARAMETERS:
pa_app type FDT_NAME DEFAULT 'ZGB_BRF_TEST01',
pa_dec type FDT_NAME DEFAULT 'DECISION1'.



* Get Application GUID
CALL METHOD cacsbr_cl_icm_fdt_helper=>get_fdt_guid
  EXPORTING
    io_factory  lo_factory
    id_obj_name pa_app "'ZGB_BRF_TEST01' " Application Name
    id_obj_type 'AP'
  IMPORTING
    et_obj_ids  DATA(lt_fdt_ids).

READ TABLE lt_fdt_ids INDEX INTO DATA(ls_fdt.
DATA(lv_appl_id)  =  ls_fdt-id.

* Generic factory instance
lo_factory cl_fdt_factory=>if_fdt_factory~get_instancelv_appl_id ).

CLEAR lt_fdt_ids.
* Get Decision Table GUID
CALL METHOD cacsbr_cl_icm_fdt_helper=>get_fdt_guid
  EXPORTING
    io_factory  lo_factory
    id_obj_name pa_dec "'DECISION1'   " Decision Table Name
    id_obj_type 'EX'
  IMPORTING
    et_obj_ids  lt_fdt_ids.

READ TABLE lt_fdt_ids INDEX INTO ls_fdt .
DATA(lv_decision_tab_guid)  =  ls_fdt-id.

* Get Expression
lo_dec_table ?= lo_factory->get_expressioniv_id lv_decision_tab_guid ).

* Get BRF Columns
lo_dec_table->get_columnsIMPORTING ets_column DATA(lt_column).

* Get BRF Rows
lo_dec_table->get_rowsIMPORTING ets_row_data DATA(lt_rowdata).

* Get the expression using decision table guid
lo_decision_table ?= lo_factory->get_expressioniv_id lv_decision_tab_guid ).

* Get the decision table data based on above expression guid
lo_decision_table->if_fdt_decision_table~get_table_data(
  IMPORTING
    ets_data     lt_table_data
).



DATA:
  lo_element          TYPE REF TO          cl_fdt_element,
  ls_fdt_dec_tab_stru TYPE cacs_s_fdt_dec_tab_struc,
  lt_dec_tab_struct   TYPE cacs_tt_fdt_dec_tab_struc,

  ls_ddic_info        TYPE dd04v,
  ls_fcat_dec_tab     TYPE lvc_s_fcat,
  lt_fcat_dec_tab     TYPE lvc_t_fcat,
  lt_dyn_out          TYPE REF TO data,
  lv_tab_name         TYPE ddobjname.

FIELD-SYMBOLS:
               <fs_data> TYPE REF TO data.

LOOP AT lt_column INTO DATA(ls_column).
  CALL METHOD cl_fdt_services=>get_texts_for_id
    EXPORTING
      iv_id        ls_column-object_id
      iv_timestamp ''
    IMPORTING
      ev_name      DATA(lv_column_name).

  lo_element ?= lo_factory->get_data_object(  iv_id  ls_column-object_id
      iv_data_object_type if_fdt_constants=>gc_data_object_type_element ).
  CALL METHOD lo_element->if_fdt_data_object~get_ddic_binding
    RECEIVING
      rv_ddic_typename DATA(lv_tabname).
  IF lv_tabname IS INITIAL.
    lv_tabname 'CHAR255'.
  ENDIF.

  MOVE ls_column-col_no         TO ls_fdt_dec_tab_stru-column_num.
  MOVE lv_column_name           TO ls_fdt_dec_tab_stru-column_name.
  MOVE lv_tabname               TO ls_fdt_dec_tab_stru-col_data_type.
  MOVE ls_column-is_optional    TO ls_fdt_dec_tab_stru-is_optional.
  MOVE ls_column-input_required TO ls_fdt_dec_tab_stru-is_required.
  MOVE ls_column-is_result      TO ls_fdt_dec_tab_stru-is_result.
  MOVE ls_column-ui_mode        TO ls_fdt_dec_tab_stru-is_ui_mode.
  APPEND ls_fdt_dec_tab_stru    TO  lt_dec_tab_struct.
ENDLOOP.


** table creation
LOOP AT lt_dec_tab_struct INTO DATA(ls_dec_tab_struct).
  lv_tab_name ls_dec_tab_struct-col_data_type.
  CALL FUNCTION 'DDIF_DTEL_GET'
    EXPORTING
      name     lv_tab_name
      state    'A'
      langu    sy-langu
    IMPORTING
      dd04v_wa ls_ddic_info.

  ls_fcat_dec_tab-fieldname ls_dec_tab_struct-column_name.
  ls_fcat_dec_tab-col_pos   ls_dec_tab_struct-column_num.
  ls_fcat_dec_tab-tabname   ls_dec_tab_struct-col_data_type.
  ls_fcat_dec_tab-outputlen ls_ddic_info-leng.
  APPEND ls_fcat_dec_tab TO lt_fcat_dec_tab.
ENDLOOP.

ASSIGN lt_dyn_out TO <fs_data>"Dynamic table out type ref to DATA

* Create Dynamic Table
CALL METHOD cl_alv_table_create=>create_dynamic_table
  EXPORTING
    it_fieldcatalog           lt_fcat_dec_tab
  IMPORTING
    ep_table                  <fs_data>
  EXCEPTIONS
    generate_subpool_dir_full 1
    OTHERS                    2.
IF sy-subrc <> 0.
  RETURN.
ENDIF.

TYPESBEGIN OF ts_result_data,
         row_no    TYPE int4,
         col_no    TYPE int4,
         value     TYPE string,
         is_result TYPE abap_bool,
       END OF ts_result_data ,

       BEGIN OF ts_dt_column,
         col_name  TYPE string,
         col_type  TYPE string,
         col_no    TYPE int4,
         object_id TYPE if_fdt_types=>id,
       END OF ts_dt_column .

DATA lt_rule_res_data TYPE TABLE OF ts_result_data,
       ls_rule_res_data TYPE ts_result_data,
       lv_value         TYPE string,
       lt_range         TYPE if_fdt_range=>ts_range,
       ls_range         LIKE LINE OF lt_range,
       lv_result_type   TYPE LENGTH 1,
       lv_comp_count    TYPE i,
       ls_timepoint     TYPE if_fdt_types=>element_timepoint,
       ls_dyn_line      TYPE REF TO data,
       lv_rown_count    TYPE i.
*            lt_fcat_dec_tab   TYPE lvc_t_fcat.

FIELD-SYMBOLS:
  <fs_result>       TYPE data,
  <fs_dyntable>     TYPE table,
  <fs_struct_tab>   TYPE any,
  <fs_dataa>        TYPE any,
*                 <fs_data> TYPE REF TO data.
  <fs_fcat_dec_tab> TYPE lvc_s_fcat.

*  Get the values inside the table  from BRF plus
LOOP AT lt_table_data INTO DATA(ls_table_data).
  CLEARls_rule_res_data,lv_value.
  IF ls_table_data-r_value IS NOT INITIAL.
    ASSIGN ls_table_data-r_value->TO <fs_result>.
*       Not a date field. Hence get the value directly.
    lv_value <fs_result>.

    UNASSIGN <fs_result>.
  ELSEIF ls_table_data-ts_range IS NOT INITIAL.
    lt_range ls_table_data-ts_range.
    READ TABLE lt_range INTO ls_range INDEX 1.
    IF  sy-subrc  0.
      ASSIGN ls_range-r_low_value->TO <fs_result>.
      IF <fs_result> IS ASSIGNED .
        DESCRIBE FIELD <fs_result> TYPE lv_result_type COMPONENTS lv_comp_count.
        IF lv_result_type 'u'" Flat Structure
*         If the result is a flat struc, then it should be a time point (date field)
          ls_timepoint <fs_result>.
          lv_value ls_timepoint-date.
        ELSE.
*         Not a date field. Hence get the value directly.
          lv_value <fs_result>.
        ENDIF.
        UNASSIGN <fs_result>.
      ELSE.
*         No Data in respective field
        lv_value ''.
      ENDIF.
    ENDIF.
  ENDIF.
  ls_rule_res_data-col_no ls_table_data-col_no.
  ls_rule_res_data-row_no ls_table_data-row_no.
  ls_rule_res_data-value lv_value.

  CLEAR  ls_column.
  READ TABLE lt_column INTO ls_column WITH KEY col_no ls_table_data-col_no.
  ls_rule_res_data-is_result ls_column-is_result.
  APPEND ls_rule_res_data TO lt_rule_res_data.
  CLEAR ls_rule_res_data.
ENDLOOP.

SORT lt_rule_res_data BY row_no ASCENDING col_no ASCENDING.
CLEARls_rule_res_data.

DESCRIBE TABLE lt_column LINES DATA(lv_count_col).
DESCRIBE TABLE lt_rule_res_data LINES DATA(lv_rows_count).
READ TABLE lt_rule_res_data INDEX lv_rows_count INTO ls_rule_res_data.
DATA(lv_row_cnt_decls_rule_res_data-row_no.

*----------------------------------------------------------------------------------
* Fill the dynamic table with values
ASSIGN <fs_data>->TO <fs_dyntable>.

* Create dynamic work area and assign to Field Symbol
CREATE DATA ls_dyn_line LIKE LINE OF <fs_dyntable>.
ASSIGN ls_dyn_line->TO <fs_struct_tab>.
UNASSIGN <fs_dataa>.

lv_rown_count 0.

WHILE lv_rown_count < lv_row_cnt_dec.
  lv_rown_count lv_rown_count + 1.
  READ TABLE lt_rule_res_data WITH KEY row_no lv_rown_count TRANSPORTING NO FIELDS BINARY SEARCH.
  IF sy-subrc <> 0.
    CONTINUE.
  ENDIF.
  DATA(lv_tabixsy-tabix.

  LOOP AT lt_rule_res_data FROM lv_tabix INTO ls_rule_res_data.
    IF ls_rule_res_data-row_no <> lv_rown_count.
      EXIT.
    ENDIF.

    READ TABLE lt_fcat_dec_tab ASSIGNING <fs_fcat_dec_tab> WITH KEY col_pos ls_rule_res_data-col_no.
    DATA(lv_field=     <fs_fcat_dec_tab>-fieldname.
    ASSIGN COMPONENT lv_field OF STRUCTURE <fs_struct_tab> TO <fs_dataa>.
    <fs_dataa> ls_rule_res_data-value.

  ENDLOOP.
  APPEND <fs_struct_tab> TO <fs_dyntable>.

  IF <fs_dataa> IS ASSIGNED.
    UNASSIGN <fs_dataa>.
  ENDIF.
ENDWHILE.

*BREAK 24131954.
IF NOT lt_table_data IS INITIAL.

ENDIF.

* display data in alv format

    DATAlr_alv          TYPE REF TO cl_salv_table.
    TRY.
        CALL METHOD cl_salv_table=>factory
          EXPORTING
            list_display if_salv_c_bool_sap=>false
          IMPORTING
            r_salv_table lr_alv
          CHANGING
            t_table      <fs_dyntable>.
        ##NO_HANDLER.
      CATCH cx_salv_msg .
    ENDTRY.
    CALL METHOD lr_alv->display.

No comments:

Post a Comment

Search SAPMV45A includes for Constants and Statics

 This report can find CONSTANTS and STATICS in SAPMV45A Z-includes. We know that Constants and Statics consume global variables so identifyi...