To create BRF+ Elements programmatically using ABAP Refer Previous blog
BRF+ Object Creation using ABAP Z-Report
In this blog, we will learn how to create BRF+ Structures and Table type programmatically using ABAP. This provides a scalable way to automate the creation of data objects and integrate them into larger rule frameworks.
Structure Creation: The same application should be used to create the structure.
It is not necessary to build a structure if our result contains just one column. There is also no need to create a structure if the output for a single condition is a single row. If more than one column appears in our result, we should make a structure with all of those columns. Additionally, a structure must be shown if the output consists of multiple rows.
Table type Creation: In order to have multiple result rows based on a single condition in our decision table, we can create a table in the same application. Therefore, table creation is necessary in our case.
ABAP Program to Create Structure and Table type
Below is a sample ABAP program (ZDEMO_BRF_APP)
REPORT zdemo_brf_app.
DATA: lo_factory TYPE REF TO if_fdt_factory,
lo_application TYPE REF TO if_fdt_application,
lt_message TYPE if_fdt_types=>t_message,
lv_message TYPE string,
lv_boolean TYPE abap_bool,
lv_demo_appl_id TYPE if_fdt_types=>id,
lv_string TYPE string,
lo_element_1 TYPE REF TO if_fdt_element,
lo_element_2 TYPE REF TO if_fdt_element,
lo_element_3 TYPE REF TO if_fdt_element,
lo_table TYPE REF TO if_fdt_table,
lo_table_1 TYPE REF TO if_fdt_table,
lo_structure TYPE REF TO if_fdt_structure,
lv_element1_id TYPE if_fdt_types=>id,
lv_element2_id TYPE if_fdt_types=>id,
lv_element3_id TYPE if_fdt_types=>id,
lv_input_number_id TYPE if_fdt_types=>id,
lv_result_counter_id TYPE if_fdt_types=>id,
FIELD-SYMBOLS:
TYPE if_fdt_types=>s_message,
TYPE any.
PARAMETERS: pv_lcl TYPE abap_bool RADIOBUTTON GROUP r00 DEFAULT 'X',
pv_sys TYPE abap_bool RADIOBUTTON GROUP r00,
pv_mstr TYPE abap_bool RADIOBUTTON GROUP r00,
pv_name TYPE char30.
* p_ele_01 TYPE i DEFAULT 5,
* p_ele_02 TYPE i DEFAULT 4,
* p_ele_03 TYPE i DEFAULT 8,
* p_ele_04 TYPE i DEFAULT 3,
* p_ele_05 TYPE i DEFAULT 13,
* p_ele_06 TYPE i DEFAULT 2.
* pv_ele TYPE char20,
* pv_str TYPE char20,
* pv_tab TYPE char20.
IF pv_name IS NOT INITIAL AND pv_lcl IS NOT INITIAL OR pv_sys IS NOT INITIAL OR pv_mstr IS NOT INITIAL.
* get a reference to the instance of the factory
lo_factory = cl_fdt_factory=>if_fdt_factory~get_instance( ).
* =============================================================
* definition of the new application:
* get an initial application object from the factory
lo_application = lo_factory->get_application( ).
lo_application->if_fdt_transaction~enqueue( ).
* set values for the application, especially the name is important
* You need to have a unique name for each application, here we use the
* FDT Service class method to get the unique name.
lo_application->set_application_component( 'BC' ). "#EC NOTEXT
lo_application->set_software_component( 'SAP_BASIS' ). "#EC NOTEXT
lo_application->set_development_package( '$TMP' ). "#EC NOTEXT
*lo_application->if_fdt_admin_data~set_name( cl_fdt_services=>get_unique_name( ) ).
lo_application->if_fdt_admin_data~set_name( pv_name ).
* In FDT terms there are 3 different type of Applications, Local application,
* system pplication and MasterData Application. The following lines shows how you
* can create local Application, masterdata Application and system Application.
IF pv_lcl EQ abap_true.
lo_application->create_local_application( ).
ELSEIF pv_sys EQ abap_true.
lo_application->create_system_application( ).
ELSEIF pv_mstr EQ abap_true.
lo_application->create_masterdata_application( ).
ENDIF.
lo_application->if_fdt_transaction~activate(
IMPORTING et_message = lt_message
ev_activation_failed = lv_boolean ).
IF lv_boolean EQ abap_true.
* for some reason the activation failed -> individual handling needed
lo_application->if_fdt_transaction~dequeue( ).
ELSE.
lo_application->if_fdt_transaction~save( ).
lo_application->if_fdt_transaction~dequeue( ).
* usually it makes sense to store the id for later access to the application
lv_demo_appl_id = lo_application->mv_id.
ENDIF.
WRITE: 'The ID of the application created is: ', lv_demo_appl_id. "#EC NOTEXT
ELSE.
MESSAGE 'Provide all the required information' TYPE 'E'.
ENDIF.
*for creating Element,Structure,Table by Data Object
lo_factory = cl_fdt_factory=>if_fdt_factory~get_instance( lv_demo_appl_id ).
* =============================================================
* definition of a data object structure:
* get an initial data object structure from the factory
lo_structure ?= lo_factory->get_data_object(
iv_data_object_type = if_fdt_constants=>gc_data_object_type_structure ).
lo_structure->if_fdt_transaction~enqueue( ).
lo_structure->if_fdt_admin_data~set_name( 'STRUCTURE' ).
lo_structure->set_elements( lts_element ).
**********************************************************************************
* Alternately user can create a structure by using the service class method,
* CL_FDT_CONVENIENCE=>CREATE_STRUCTURE as follows.
* Cl_fdt_convenience=>create_structure( EXPORTING iv_name="DEMO_STRUCTURE_1"
* iv_application_id = if_fdt_constants=>gc_application_tmp
* it_element = lts_element
* iv_activate = ABAP_false
* IMPORTING
* eo_structure = lo_structure ).
***********************************************************************************
lo_structure->if_fdt_transaction~activate(
IMPORTING
et_message = lt_message
ev_activation_failed = lv_boolean ).
IF lv_boolean EQ abap_true.
LOOP AT lt_message ASSIGNING .
MESSAGE ID -msgid TYPE -msgty NUMBER -msgno
WITH -msgv1 -msgv2 -msgv3 -msgv4
INTO lv_message.
ENDLOOP.
WRITE : lv_message.
* for some reason the activation failed -> individual handling needed
lo_structure->if_fdt_transaction~dequeue( ).
ELSE.
lo_structure->if_fdt_transaction~save( ).
lo_structure->if_fdt_transaction~dequeue( ).
* usually it makes sense to store the id for later access to the application
lv_structure_id = lo_structure->mv_id.
ENDIF.
* WRITE: / lo_structure->mv_id .
lv_string = lo_structure->if_fdt_admin_data~to_string( iv_mode = if_fdt_constants=>gc_tostring_mode_complete ).
WRITE : / 'The result of to string method call Structure: ' , lv_string. "#EC NOTEXT
* =============================================================
* definition of a data object table:
* get an initial data object Table from the factory
lo_table ?= lo_factory->get_data_object(
iv_data_object_type = if_fdt_constants=>gc_data_object_type_table ).
lo_table->if_fdt_transaction~enqueue( ).
lo_table->if_fdt_admin_data~set_name( 'TABLE' ).
lo_table->set_structure( lv_structure_id ).
INSERT lo_table->mv_id INTO TABLE lts_context_id.
***********************************************************************
* Alternately user can create a Table by using the service class method,
* CL_FDT_CONVENIENCE=>CREATE_TABLE as follows.
* cl_fdt_convenience=>create_table( EXPORTING iv_name="DEMO_TABLE_1"
* iv_structure_name="DEMO_STRUCTURE_1"
* iv_application_id = if_fdt_constants=>gc_application_tmp
* it_element = its_element
* iv_activate = ABAP_false
* IMPORTING
* eo_table = lo_table ).
***********************************************************************
lo_table->if_fdt_transaction~activate(
IMPORTING
et_message = lt_message
ev_activation_failed = lv_boolean ).
IF lv_boolean EQ abap_true.
* for some reason the activation failed -> individual handling needed
lo_table->if_fdt_transaction~dequeue( ).
ELSE.
lo_table->if_fdt_transaction~save( ).
lo_table->if_fdt_transaction~dequeue( ).
* usually it makes sense to store the id for later access to the application
ENDIF.
* WRITE: / lo_table->mv_id .
lv_string = lo_table->if_fdt_admin_data~to_string( iv_mode = if_fdt_constants=>gc_tostring_mode_complete ).
WRITE : / 'The result of to_string method call Table: ' , lv_string. "#EC NOTEXT
* cl_fdt_convenience=>create_table( EXPORTING iv_application_id = if_fdt_constants=>gc_application_tmp
* iv_element_type = if_fdt_constants=>gc_data_object_type_table
* iv_activate = abap_false
* iv_name="RESULT_COUNTER"
* IMPORTING eo_element = lo_result_counter ).
*
* INSERT lo_result_counter->mv_id INTO TABLE lts_context_id.
*TYPES: BEGIN OF ty_element ,
* name TYPE if_fdt_types=>name,
* lv_element type if_fdt_types=>element_type,
* END OF ty_element.
*DATA: lt_element TYPE TABLE OF ty_element,
* lss_element TYPE ty_element.
* lss_element-name="SFLIGHT_TAB".
* lss_element-lv_element = if_fdt_constants=>gc_data_object_type_table.
* APPEND lss_element TO lt_element.
lo_table_1 ?= lo_factory->get_data_object(
iv_data_object_type = if_fdt_constants=>gc_data_object_type_table ).
lo_table_1->if_fdt_transaction~enqueue( ).
lo_table_1->if_fdt_admin_data~set_name( 'SFLIGHT_TAB' ).
lo_table_1->set_structure( lv_result_table_id ).
APPEND lo_table_1->mv_id TO lts_context_id.
lo_table_1->if_fdt_transaction~activate(
IMPORTING
et_message = lt_message
ev_activation_failed = lv_boolean ).
IF lv_boolean EQ abap_true.
* for some reason the activation failed -> individual handling needed
lo_table_1->if_fdt_transaction~dequeue( ).
ELSE.
lo_table_1->if_fdt_transaction~save( ).
lo_table_1->if_fdt_transaction~dequeue( ).
* usually it makes sense to store the id for later access to the application
ENDIF.
* WRITE: / lo_table->mv_id .
lv_string = lo_table_1->if_fdt_admin_data~to_string( iv_mode = if_fdt_constants=>gc_tostring_mode_complete ).
WRITE : / 'The result of to_string method call Table: ' , lv_string. "#EC NOTEXT
*
* cl_fdt_convenience=>create_table(
* EXPORTING
* iv_name="RESULT_TABLE" " Name
* iv_structure_name = lv_name
* iv_application_id = if_fdt_constants=>gc_application_tmp " Universal Unique Identifier
* it_element = lt_element " Elements
* iv_activate = abap_true " Activate changes?
* IMPORTING
** ev_table_id = " Universal Unique Identifier
* eo_table = lo_result_table " FDT: Data Object of Type Table
* ).
* CATCH cx_fdt_input. " FDT: Invalid Input
Execution & Output
When you execute the above ABAP report, the newly created Application , Structure and Table will immediately be reflected in the BRF+ Workbench (/nBRF+). You can navigate to the workbench to verify that the application ZDEMO_APP and its elements have been created successfully.
After running the program, you will see system-generated IDs for each element created. These IDs are crucial when referencing the elements in Structures, Rules, or Functions.
Conclusion
In the next part of this blog series, we will explore how to create DB Lookup, Loop, Formula, Rule, and Function in Subsequent blogs in detail.



