Reading BRF+ Decision Table into ABAP

The below snippet helps you to read BRF+ decision tables into ABAP, where only I EQ LOW range or direct value assignment is specified in a particular BRF+ table cell (everything other is ignored).

To get the BRF+ table content into ABAP:

  • obtain the BRF+ table GUID from the BRF+ Workbench and pass it as i_id
  • define a structure/table type in DDIC or a type locally in ABAP, which has the identical component names (and possibly the same types) as the BRF+ table columns to use as e_table parameter

This solution focuses on developer conviniency:

  • column order is arbitrary
  • you can have more and less columns in your internal table

Definition

    CLASS-METHODS read_decision_table
      IMPORTING
        !i_id    TYPE if_fdt_types=>id
      EXPORTING
        !e_table TYPE STANDARD TABLE .

Implementation

METHOD read_decision_table.
    DATA:
      time_now  TYPE  if_fdt_types=>timestamp.

    GET TIME STAMP FIELD time_now.

    cl_fdt_factory=>get_instance_generic(
      EXPORTING
        iv_id = i_id
      IMPORTING
        eo_instance = DATA(dt_generic_ref)
    ).

    DATA(decision_table) = CAST if_fdt_decision_table( dt_generic_ref ).

    decision_table->get_columns(
      EXPORTING
        iv_timestamp = time_now
      IMPORTING
        ets_column   = DATA(columns)
    ).

    DATA(col_count) = lines( columns ).

    decision_table->get_rows(
      EXPORTING
        iv_timestamp = time_now
      IMPORTING
        ets_row_data =  DATA(table_rows)
    ).

    LOOP AT table_rows ASSIGNING FIELD-SYMBOL(<row>).
      APPEND INITIAL LINE TO e_table ASSIGNING FIELD-SYMBOL(<result_row>).

      LOOP AT columns INTO DATA(column).
        cl_fdt_maintenance=>get_admin_data_details(
          EXPORTING
            iv_id     = column-object_id
          IMPORTING
            ev_name   = DATA(col_name)
        ).

        TRY.
            DATA(cell) = <row>-ts_cell_data[ column-col_no ].
          CATCH cx_sy_itab_line_not_found.
            CONTINUE.
        ENDTRY.

        IF cell-r_value IS BOUND.
          DATA(value_ref) = cell-r_value.
          ASSIGN value_ref->* TO FIELD-SYMBOL(<value>).
          IF <value> IS ASSIGNED.
            ASSIGN COMPONENT col_name OF STRUCTURE <result_row> TO FIELD-SYMBOL(<result_value>).
            IF <result_value> IS ASSIGNED.
              <result_value> = <value>.
              UNASSIGN <result_value>.
            ENDIF.
            UNASSIGN <value>.
          ENDIF.

        ELSEIF cell-ts_range IS NOT INITIAL.
          value_ref = cell-ts_range[ 1 ]-r_low_value.
          ASSIGN value_ref->* TO <value>.
          IF <value> IS ASSIGNED.
            ASSIGN COMPONENT col_name OF STRUCTURE <result_row> TO <result_value>.
            IF <result_value> IS ASSIGNED.
              <result_value> = <value>.
              UNASSIGN <result_value>.
            ENDIF.
            UNASSIGN <value>.
          ENDIF.
        ENDIF.
      ENDLOOP.
    ENDLOOP.

  ENDMETHOD.

To create that snippet, great help was the article by Jocelyn Dart https://archive.sap.com/documents/docs/DOC-62221.