Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
wilbert_sison2
Active Participant
1,763
If for any reason, you have a fairly detailed segmentation of BP types and activities in MDG, there's a chance you have had to copy over BRF+ workflows.

Now, this is not a terribly difficult thing to do as the Import/Export functionality in BRF+ is a great feature. However minor changes can be a headache and I was getting tired of clicking the Import/Export button every time that happens.

Below is a little code I used to quickly copy over data the workflow BRF+ decision tables from one Change Request Workflow into another.

It's obviously rough. The error management could be improved, but it's good enough for occasional adjustment activity.

Helper Class 

This is the local class I used as a helper.
CLASS lcl_brf DEFINITION.
PUBLIC SECTION.
METHODS get_reference_decision_tab
IMPORTING iv_crtype TYPE string
RAISING zcx_mdg.
METHODS get_decision_tab_object
IMPORTING iv_name TYPE string
RETURNING VALUE(ro_object) TYPE REF TO cl_fdt_decision_table
RAISING zcx_mdg.
METHODS get_decision_tab_data
IMPORTING iv_name TYPE string
RETURNING VALUE(rt_decision_tab) TYPE if_fdt_Decision_table=>ts_table_data
RAISING zcx_mdg.
METHODS copy_to
IMPORTING iv_crtype TYPE string
RAISING zcx_mdg.
METHODS copy_decision_table
IMPORTING iv_name TYPE string
it_decision_tab TYPE if_fdt_Decision_table=>ts_table_data
RAISING zcx_mdg.

METHODS constructor.

PRIVATE SECTION.
DATA mo_brf_query TYPE REF TO if_fdt_query.
DATA mo_brf_factory TYPE REF TO if_fdt_factory.
DATA mt_user_agent TYPE if_fdt_decision_table=>ts_table_data.
DATA mt_non_user_agent TYPE if_fdt_decision_table=>ts_table_data.
DATA mt_single_value TYPE if_fdt_decision_table=>ts_table_data.
ENDCLASS.

CLASS lcl_brf IMPLEMENTATION.
METHOD constructor.
mo_brf_factory ?= cl_fdt_factory=>if_fdt_factory~get_instance( ).
mo_brf_query ?= mo_brf_factory->get_query( ).
ENDMETHOD.
METHOD get_decision_tab_data.
DATA : o_decision_table TYPE REF TO cl_fdt_decision_table.
mo_brf_query->get_ids(
EXPORTING
iv_name = CONV #( iv_name )
iv_object_type = if_fdt_constants=>gc_object_type_expression
IMPORTING
ets_object_id = DATA(app_ids) ).
o_decision_table ?= mo_brf_factory->get_expression( app_ids[ 1 ] ) .
o_decision_table->if_fdt_decision_table~get_table_data( IMPORTING ets_data = rt_decision_tab ).
ENDMETHOD.
METHOD get_reference_decision_tab.
DATA : o_ref_decision_table TYPE REF TO cl_fdt_decision_table.
mt_user_agent = get_decision_tab_data( |DT_USER_AGT_GRP_{ iv_crtype }| ).
mt_non_user_agent = get_decision_tab_data( |DT_NON_USER_AGT_GRP_{ iv_crtype }| ).
mt_single_value = get_decision_tab_data( |DT_SINGLE_VAL_{ iv_crtype }| ).
ENDMETHOD.
METHOD get_decision_tab_object.
mo_brf_query->get_ids(
EXPORTING
iv_name = CONV #( iv_name )
iv_object_type = if_fdt_constants=>gc_object_type_expression
IMPORTING
ets_object_id = DATA(app_ids) ).
ro_object ?= mo_brf_factory->get_expression( app_ids[ 1 ] ) .
ENDMETHOD.
METHOD copy_decision_table.


DATA : o_decision_table TYPE REF TO cl_fdt_decision_table.
TRY.
o_decision_table = get_decision_tab_object( iv_name ).
o_decision_table->if_fdt_transaction~enqueue( ).
o_decision_table->if_fdt_decision_table~set_table_data( EXPORTING its_data = it_decision_tab ).
o_decision_table->if_fdt_transaction~activate(
EXPORTING iv_deep = abap_true
IMPORTING et_message = DATA(messages)
ev_activation_failed = DATA(lv_actv_failed) ).
if lv_actv_failed = abap_true.
MESSAGE e000(zmdg) WITH 'Error updating' iv_name INTO zcl_messages=>sv_message_text.
RAISE EXCEPTION TYPE zcx_mdg
EXPORTING
mo_messages = NEW zcl_messages( )->set_system_message( ).
endif.

o_decision_table->if_fdt_transaction~save( ).
o_decision_table->if_fdt_transaction~dequeue( ).
CATCH cx_fdt.
MESSAGE e000(zmdg) WITH 'Error updating' iv_name INTO zcl_messages=>sv_message_text.
RAISE EXCEPTION TYPE zcx_mdg
EXPORTING
mo_messages = NEW zcl_messages( )->set_system_message( ).
ENDTRY.
ENDMETHOD.
METHOD copy_to.

copy_decision_table( iv_name = |DT_USER_AGT_GRP_{ iv_crtype }|
it_decision_tab = mt_user_agent ).

copy_decision_table( iv_name = |DT_NON_USER_AGT_GRP_{ iv_crtype }|
it_decision_tab = mt_non_user_agent ).

copy_decision_table( iv_name = |DT_SINGLE_VAL_{ iv_crtype }|
it_decision_tab = mt_single_value ).

ENDMETHOD.
ENDCLASS.

Execution

Below is a sample code for using the class above.
START-OF-SELECTION.
TRY.
DATA(o_brf) = NEW lcl_brf( ).

o_brf->get_reference_decision_tab( 'ZCR1' ).
o_brf->copy_to( 'ZCR2' ).
o_brf->copy_to( 'ZCR3' ).
CATCH /gerp/cx_mdg INTO DATA(o_error).
o_error->mo_messages->show_as_log( ).
ENDTRY.

 

With that utility, I can update one workflow and then use the utility to copy to all the others.

This approach can be used in decision tables outside of MDG, but note that (1) the structure has to be the same and (2)  you have to identify the application name is those situations as the Decision Table Name is not unique.

 

 
2 Comments
DominikTylczyn
Active Contributor
Nice one. Maybe it could be incorporated in standard. Have you considered proposing that to SAP with SAP Customer Influence program?
wilbert_sison2
Active Participant
0 Kudos
Hi Dominik,

Thank you for the kind words. The call for the last Customer Influence program was closed in October 2022. Will try on the next round and if it's useful, hopefully it gets the votes.

Cheers,
Wilbert
Labels in this area