Uploaded by rothwilliamsa

SAP BPC -- BADI -- ALLOCATION -- How to use with 4 dimensions called ACTIVITY

advertisement
o
We have 4 dimensions called ACTIVITY,NSC,MODELS and MPS . For these 4
dimensions we would have any number of parents and last would be child which
is base member. There is historic data already present in the EXPENSE_PLANNING
cube which has 13 dimensions including the above 4. I need to calculate the
percentages of the data which is present in the EXPENSE_PLANNING cube for the
above 4 dimensions and allocate the same percentages in the present data for
the 4 dimensions. The follozing above given code is only allocating the data
based on averages but i need to write a logic first to calculate the percentages
of the historic data and then use the percentages in the above code for the 4
dimensions.
Kindly revert if you need more information.
o
I have already implemented the code given in the second link . That particular
code is for disaggregating data for 1 dimension but my requirement is for the
disaggregation of 4 dimensions. I have already modified the code for 4
dimensions but there is a problem at the first dimension the data is getting splitted
averagely but at the second dimension the data is not getting splitted correctly.
Please find the code below and let me know what is that i need to change to get
the data splitted correctly for all the 4 dimensions. The sequence given in the
code is the actual sequence in which the data needs to be splitted.
1. ACTIVITY 2. NSC 3. MODELS and 4 . MPS
CODE :
method IF_UJR_WB_PRE_PROCESS~PRE_PROCESS.
DATA: ls_entity TYPE ujr_s_dim_handler,
lt_entity_members TYPE uja_t_dim_member, " dimension members of Entity
lo_entity TYPE REF TO if_uja_dim_data, " Object Reference to Dimension
lt_hier_info TYPE uja_t_hier, " Hierachies Infos
ls_hier_info TYPE uja_s_hier,
lt_hier_name TYPE uja_t_hier_name, " Hierachies name list
lt_attr_list TYPE uja_t_attr, " Attributes Infos
ls_attr_list TYPE uja_s_attr,
lt_attr_name TYPE uja_t_attr_name, " Attributes name list
lf_non_base TYPE uj_flg, " 'X'=non base member; ' '=base member
lt_entity_mbr TYPE uja_t_dim_member, " childen entity members
l_num_base TYPE i, " number of children entity members
lr_data TYPE REF TO data.* lr_data5 TYPE REF TO data.
FIELD-SYMBOLS: <ls_dim_obj> TYPE ujr_s_dim_handler,
<ls_record> TYPE ANY,
<l_entity> TYPE uj_dim_member, " Entity member of current records
<lt_entity_mbr> TYPE HASHED TABLE, " All entity members
<ls_entity_mbr> TYPE ANY,
<lf_calc> TYPE uj_flg, " 'Y'=non base member
<lf_storedcalc> TYPE ANY, " 'Y'=non base member
<l_base_mbr> TYPE uj_dim_member,
<l_keyfigure> TYPE ANY. " Keyfigure* <l_temp1> TYPE STANDARD TABLE.
" Find the Entity dimension by its type
LOOP AT it_dim_obj ASSIGNING <ls_dim_obj> WHERE dimension = 'ACTIVITY'.
lo_entity ?= <ls_dim_obj>-dim_obj.
ls_entity = <ls_dim_obj>.
ENDLOOP.
" Get hierachy (PARENTH1, PARENTH2 ...)
lo_entity->get_hier_list( IMPORTING et_hier_info = lt_hier_info ).
LOOP AT lt_hier_info INTO ls_hier_info.
APPEND ls_hier_info-hier_name TO lt_hier_name.
ENDLOOP.
" Get necessary attributes (CALC and STORED_CALC)
lo_entity->get_attr_list( IMPORTING et_attr_list = lt_attr_list ).
LOOP AT lt_attr_list INTO ls_attr_list
WHERE attribute_name = ujr0_c_attr_calc OR attribute_name =
ujr0_c_attr_storedcalc.
APPEND ls_attr_list-attribute_name TO lt_attr_name.
ENDLOOP.
" Get Members
CALL METHOD lo_entity->read_mbr_data
EXPORTING
if_ret_hashtab = abap_true
it_attr_list = lt_attr_name " columns:attributes name list
it_hier_list = lt_hier_name " columns:hieracies name list
IMPORTING
er_data = lr_data.
ASSIGN lr_data->* TO <lt_entity_mbr>.
" preparation: create data structure and assign fields
CREATE DATA lr_data LIKE LINE OF ct_array.
ASSIGN lr_data->* TO <ls_record>.* CREATE DATA lr_data5 LIKE LINE OF ct_array.*
ASSIGN lr_data5->* TO <l_temp1>.
ASSIGN COMPONENT ls_entity-dimension OF STRUCTURE <ls_record> TO <l_entity>.
ASSIGN COMPONENT ujr0_c_keyfigure OF STRUCTURE <ls_record> TO
<l_keyfigure>.
LOOP AT ct_array INTO <ls_record>.* APPEND <ls_record> TO <l_temp1>.
READ TABLE <lt_entity_mbr>
WITH TABLE KEY (ujr0_c_member_id) = <l_entity>
ASSIGNING <ls_entity_mbr>.
IF sy-subrc = 0.
" lf_non_base = <lf_calc>=Y OR <lf_storedcalc>=Y.
ASSIGN COMPONENT ujr0_c_attr_calc OF STRUCTURE <ls_entity_mbr> TO <lf_calc>.
lf_non_base = <lf_calc>.
ASSIGN COMPONENT ujr0_c_attr_storedcalc OF STRUCTURE <ls_entity_mbr> TO
<lf_storedcalc>.
IF sy-subrc = 0 AND <lf_storedcalc> = ujr0_cs_calc-calculated_member.
lf_non_base = ujr0_cs_calc-calculated_member.
ENDIF.
" Disaggregate non base member
IF lf_non_base = ujr0_cs_calc-calculated_member.
" A more precise version is to retrieve only accessible member of IS_USER
CALL METHOD lo_entity->get_children_mbr
EXPORTING
i_parent_mbr = <l_entity> " Parent
i_level = -99 " -99 = All children in any level; -1 = direct child
if_only_base_mbr = abap_true " Only base member
IMPORTING
et_member = lt_entity_mbr.
" Re-calculate the keyfigure, divide by N = number of base members
" Usually it doesn't matter with IF_CALC_DELTA = false,
" if the operation is linear mathematical.
DESCRIBE TABLE lt_entity_mbr LINES l_num_base.
" Avoid divide by zero
IF l_num_base > 0.
<l_keyfigure> = <l_keyfigure> / l_num_base.
" Copy N times with new base members
LOOP AT lt_entity_mbr ASSIGNING <l_base_mbr>.
<l_entity> = <l_base_mbr>.
" When IF_CALC_DELTA = true, appending means the latest records take effects,
" previous records with same dimension member will be overwritten.
" The newly appended records will also be looped and processed.
APPEND <ls_record> TO ct_array.
ENDLOOP.
ENDIF. " divide by zero
"Remove the old one
DELETE ct_array.
ENDIF.
ENDIF.
ENDLOOP.
DATA: ls_entity2 TYPE ujr_s_dim_handler,
lt_entity_members2 TYPE uja_t_dim_member, " dimension members of Entity
lo_entity2 TYPE REF TO if_uja_dim_data, " Object Reference to Dimension
lt_hier_info2 TYPE uja_t_hier, " Hierachies Infos
ls_hier_info2 TYPE uja_s_hier,
lt_hier_name2 TYPE uja_t_hier_name, " Hierachies name list
lt_attr_list2 TYPE uja_t_attr, " Attributes Infos
ls_attr_list2 TYPE uja_s_attr,
lt_attr_name2 TYPE uja_t_attr_name, " Attributes name list
lf_non_base2 TYPE uj_flg, " 'X'=non base member; ' '=base member
lt_entity_mbr2 TYPE uja_t_dim_member, " childen entity members
l_num_base2 TYPE i, " number of children entity members
lr_data2 TYPE REF TO data.
FIELD-SYMBOLS: <ls_dim_obj2> TYPE ujr_s_dim_handler,
<ls_record2> TYPE ANY,
<l_entity2> TYPE uj_dim_member, " Entity member of current records
<lt_entity_mbr2> TYPE HASHED TABLE, " All entity members
<ls_entity_mbr2> TYPE ANY,
<lf_calc2> TYPE uj_flg, " 'Y'=non base member
<lf_storedcalc2> TYPE ANY, " 'Y'=non base member
<l_base_mbr2> TYPE uj_dim_member,
<l_keyfigure2> TYPE ANY. " Keyfigure
" Find the Entity dimension by its type
LOOP AT it_dim_obj ASSIGNING <ls_dim_obj2> WHERE dimension = 'NSC'.
lo_entity2 ?= <ls_dim_obj2>-dim_obj.
ls_entity2 = <ls_dim_obj2>.
ENDLOOP.
" Get hierachy (PARENTH1, PARENTH2 ...)
lo_entity2->get_hier_list( IMPORTING et_hier_info = lt_hier_info2 ).
LOOP AT lt_hier_info2 INTO ls_hier_info2.
APPEND ls_hier_info2-hier_name TO lt_hier_name2.
ENDLOOP.
" Get necessary attributes (CALC and STORED_CALC)
lo_entity2->get_attr_list( IMPORTING et_attr_list = lt_attr_list2 ).
LOOP AT lt_attr_list2 INTO ls_attr_list2
WHERE attribute_name = ujr0_c_attr_calc OR attribute_name =
ujr0_c_attr_storedcalc.
APPEND ls_attr_list2-attribute_name TO lt_attr_name2.
ENDLOOP.
" Get Members
CALL METHOD lo_entity2->read_mbr_data
EXPORTING
if_ret_hashtab = abap_true
it_attr_list = lt_attr_name2 " columns:attributes name list
it_hier_list = lt_hier_name2 " columns:hieracies name list
IMPORTING
er_data = lr_data2.
ASSIGN lr_data2->* TO <lt_entity_mbr2>.
" preparation: create data structure and assign fields
CREATE DATA lr_data2 LIKE LINE OF ct_array.
ASSIGN lr_data2->* TO <ls_record2>.
ASSIGN COMPONENT ls_entity2-dimension OF STRUCTURE <ls_record2> TO
<l_entity2>.
ASSIGN COMPONENT ujr0_c_keyfigure OF STRUCTURE <ls_record2> TO
<l_keyfigure2>.
LOOP AT ct_array INTO <ls_record2>.
READ TABLE <lt_entity_mbr2>
WITH TABLE KEY (ujr0_c_member_id) = <l_entity2>
ASSIGNING <ls_entity_mbr2>.
IF sy-subrc = 0.
" lf_non_base2 = <lf_calc2>=Y OR <lf_storedcalc2>=Y.
ASSIGN COMPONENT ujr0_c_attr_calc OF STRUCTURE <ls_entity_mbr2> TO
<lf_calc2>.
lf_non_base2 = <lf_calc2>.
ASSIGN COMPONENT ujr0_c_attr_storedcalc OF STRUCTURE <ls_entity_mbr2> TO
<lf_storedcalc2>.
IF sy-subrc = 0 AND <lf_storedcalc2> = ujr0_cs_calc-calculated_member.
lf_non_base2 = ujr0_cs_calc-calculated_member.
ENDIF.
" Disaggregate non base member
IF lf_non_base2 = ujr0_cs_calc-calculated_member.
" A more precise version is to retrieve only accessible member of IS_USER
CALL METHOD lo_entity2->get_children_mbr
EXPORTING
i_parent_mbr = <l_entity2> " Parent
i_level = -99 " -99 = All children in any level; -1 = direct child
if_only_base_mbr = abap_true " Only base member
IMPORTING
et_member = lt_entity_mbr2.
" Re-calculate the keyfigure, divide by N = number of base members
" Usually it doesn't matter with IF_CALC_DELTA = false,
" if the operation is linear mathematical.
DESCRIBE TABLE lt_entity_mbr2 LINES l_num_base2.
" Avoid divide by zero
IF l_num_base2 > 0.
<l_keyfigure2> = <l_keyfigure2> / l_num_base2.
" Copy N times with new base members
LOOP AT lt_entity_mbr2 ASSIGNING <l_base_mbr2>.
<l_entity2> = <l_base_mbr2>.
" When IF_CALC_DELTA = true, appending means the latest records take effects,
" previous records with same dimension member will be overwritten.
" The newly appended records will also be looped and processed.
APPEND <ls_record2> TO ct_array.
ENDLOOP.
ENDIF. " divide by zero
" Remove the old one
DELETE ct_array.
ENDIF.
ENDIF.
ENDLOOP.
DATA: ls_entity3 TYPE ujr_s_dim_handler,
lt_entity_members3 TYPE uja_t_dim_member, " dimension members of Entity
lo_entity3 TYPE REF TO if_uja_dim_data, " Object Reference to Dimension
lt_hier_info3 TYPE uja_t_hier, " Hierachies Infos
ls_hier_info3 TYPE uja_s_hier,
lt_hier_name3 TYPE uja_t_hier_name, " Hierachies name list
lt_attr_list3 TYPE uja_t_attr, " Attributes Infos
ls_attr_list3 TYPE uja_s_attr,
lt_attr_name3 TYPE uja_t_attr_name, " Attributes name list
lf_non_base3 TYPE uj_flg, " 'X'=non base member; ' '=base member
lt_entity_mbr3 TYPE uja_t_dim_member, " childen entity members
l_num_base3 TYPE i, " number of children entity members
lr_data3 TYPE REF TO data.
FIELD-SYMBOLS: <ls_dim_obj3> TYPE ujr_s_dim_handler,
<ls_record3> TYPE ANY,
<l_entity3> TYPE uj_dim_member, " Entity member of current records
<lt_entity_mbr3> TYPE HASHED TABLE, " All entity members
<ls_entity_mbr3> TYPE ANY,
<lf_calc3> TYPE uj_flg, " 'Y'=non base member
<lf_storedcalc3> TYPE ANY, " 'Y'=non base member
<l_base_mbr3> TYPE uj_dim_member,
<l_keyfigure3> TYPE ANY. " Keyfigure
" Find the Entity dimension by its type
LOOP AT it_dim_obj ASSIGNING <ls_dim_obj3> WHERE dimension = 'MODELS'.
lo_entity3 ?= <ls_dim_obj3>-dim_obj.
ls_entity3 = <ls_dim_obj3>.
ENDLOOP.
" Get hierachy (PARENTH1, PARENTH2 ...)
lo_entity3->get_hier_list( IMPORTING et_hier_info = lt_hier_info3 ).
LOOP AT lt_hier_info3 INTO ls_hier_info3.
APPEND ls_hier_info3-hier_name TO lt_hier_name3.
ENDLOOP.
" Get necessary attributes (CALC and STORED_CALC)
lo_entity3->get_attr_list( IMPORTING et_attr_list = lt_attr_list3 ).
LOOP AT lt_attr_list3 INTO ls_attr_list3
WHERE attribute_name = ujr0_c_attr_calc OR attribute_name =
ujr0_c_attr_storedcalc.
APPEND ls_attr_list3-attribute_name TO lt_attr_name3.
ENDLOOP.
" Get Members
CALL METHOD lo_entity3->read_mbr_data
EXPORTING
if_ret_hashtab = abap_true
it_attr_list = lt_attr_name3 " columns:attributes name list
it_hier_list = lt_hier_name3 " columns:hieracies name list
IMPORTING
er_data = lr_data3.
ASSIGN lr_data3->* TO <lt_entity_mbr3>.
" preparation: create data structure and assign fields
CREATE DATA lr_data3 LIKE LINE OF ct_array.
ASSIGN lr_data3->* TO <ls_record3>.
ASSIGN COMPONENT ls_entity3-dimension OF STRUCTURE <ls_record3> TO
<l_entity3>.
ASSIGN COMPONENT ujr0_c_keyfigure OF STRUCTURE <ls_record3> TO
<l_keyfigure3>.
LOOP AT ct_array INTO <ls_record3>.
READ TABLE <lt_entity_mbr3>
WITH TABLE KEY (ujr0_c_member_id) = <l_entity3>
ASSIGNING <ls_entity_mbr3>.
IF sy-subrc = 0.
" lf_non_base2 = <lf_calc2>=Y OR <lf_storedcalc2>=Y.
ASSIGN COMPONENT ujr0_c_attr_calc OF STRUCTURE <ls_entity_mbr3> TO
<lf_calc3>.
lf_non_base3 = <lf_calc3>.
ASSIGN COMPONENT ujr0_c_attr_storedcalc OF STRUCTURE <ls_entity_mbr3> TO
<lf_storedcalc3>.
IF sy-subrc = 0 AND <lf_storedcalc3> = ujr0_cs_calc-calculated_member.
lf_non_base3 = ujr0_cs_calc-calculated_member.
ENDIF.
" Disaggregate non base member
IF lf_non_base3 = ujr0_cs_calc-calculated_member.
" A more precise version is to retrieve only accessible member of IS_USER
CALL METHOD lo_entity3->get_children_mbr
EXPORTING
i_parent_mbr = <l_entity3> " Parent
i_level = -99 " -99 = All children in any level; -1 = direct child
if_only_base_mbr = abap_true " Only base member
IMPORTING
et_member = lt_entity_mbr3.
" Re-calculate the keyfigure, divide by N = number of base members
" Usually it doesn't matter with IF_CALC_DELTA = false,
" if the operation is linear mathematical.
DESCRIBE TABLE lt_entity_mbr3 LINES l_num_base3.
" Avoid divide by zero
IF l_num_base3 > 0.
<l_keyfigure3> = <l_keyfigure3> / l_num_base3.
" Copy N times with new base members
LOOP AT lt_entity_mbr3 ASSIGNING <l_base_mbr3>.
<l_entity3> = <l_base_mbr3>.
" When IF_CALC_DELTA = true, appending means the latest records take effects,
" previous records with same dimension member will be overwritten.
" The newly appended records will also be looped and processed.
APPEND <ls_record3> TO ct_array.
ENDLOOP.
ENDIF. " divide by zero
" Remove the old one
DELETE ct_array.
ENDIF.
ENDIF.
ENDLOOP.
DATA: ls_entity4 TYPE ujr_s_dim_handler,
lt_entity_members4 TYPE uja_t_dim_member, " dimension members of Entity
lo_entity4 TYPE REF TO if_uja_dim_data, " Object Reference to Dimension
lt_hier_info4 TYPE uja_t_hier, " Hierachies Infos
ls_hier_info4 TYPE uja_s_hier,
lt_hier_name4 TYPE uja_t_hier_name, " Hierachies name list
lt_attr_list4 TYPE uja_t_attr, " Attributes Infos
ls_attr_list4 TYPE uja_s_attr,
lt_attr_name4 TYPE uja_t_attr_name, " Attributes name list
lf_non_base4 TYPE uj_flg, " 'X'=non base member; ' '=base member
lt_entity_mbr4 TYPE uja_t_dim_member, " childen entity members
l_num_base4 TYPE i, " number of children entity members
lr_data4 TYPE REF TO data.
FIELD-SYMBOLS: <ls_dim_obj4> TYPE ujr_s_dim_handler,
<ls_record4> TYPE ANY,
<l_entity4> TYPE uj_dim_member, " Entity member of current records
<lt_entity_mbr4> TYPE HASHED TABLE, " All entity members
<ls_entity_mbr4> TYPE ANY,
<lf_calc4> TYPE uj_flg, " 'Y'=non base member
<lf_storedcalc4> TYPE ANY, " 'Y'=non base member
<l_base_mbr4> TYPE uj_dim_member,
<l_keyfigure4> TYPE ANY. " Keyfigure
" Find the Entity dimension by its type
LOOP AT it_dim_obj ASSIGNING <ls_dim_obj4> WHERE dimension = 'MPS'.
lo_entity4 ?= <ls_dim_obj4>-dim_obj.
ls_entity4 = <ls_dim_obj4>.
ENDLOOP.
" Get hierachy (PARENTH1, PARENTH2 ...)
lo_entity4->get_hier_list( IMPORTING et_hier_info = lt_hier_info4 ).
LOOP AT lt_hier_info4 INTO ls_hier_info4.
APPEND ls_hier_info4-hier_name TO lt_hier_name4.
ENDLOOP.
" Get necessary attributes (CALC and STORED_CALC)
lo_entity4->get_attr_list( IMPORTING et_attr_list = lt_attr_list4 ).
LOOP AT lt_attr_list4 INTO ls_attr_list4
WHERE attribute_name = ujr0_c_attr_calc OR attribute_name =
ujr0_c_attr_storedcalc.
APPEND ls_attr_list4-attribute_name TO lt_attr_name4.
ENDLOOP.
" Get Members
CALL METHOD lo_entity4->read_mbr_data
EXPORTING
if_ret_hashtab = abap_true
it_attr_list = lt_attr_name4 " columns:attributes name list
it_hier_list = lt_hier_name4 " columns:hieracies name list
IMPORTING
er_data = lr_data4.
ASSIGN lr_data4->* TO <lt_entity_mbr4>.
" preparation: create data structure and assign fields
CREATE DATA lr_data4 LIKE LINE OF ct_array.
ASSIGN lr_data4->* TO <ls_record4>.
ASSIGN COMPONENT ls_entity4-dimension OF STRUCTURE <ls_record4> TO
<l_entity4>.
ASSIGN COMPONENT ujr0_c_keyfigure OF STRUCTURE <ls_record4> TO
<l_keyfigure4>.
LOOP AT ct_array INTO <ls_record4>.
READ TABLE <lt_entity_mbr4>
WITH TABLE KEY (ujr0_c_member_id) = <l_entity4>
ASSIGNING <ls_entity_mbr4>.
IF sy-subrc = 0.
" lf_non_base2 = <lf_calc2>=Y OR <lf_storedcalc2>=Y.
ASSIGN COMPONENT ujr0_c_attr_calc OF STRUCTURE <ls_entity_mbr4> TO
<lf_calc4>.
lf_non_base4 = <lf_calc4>.
ASSIGN COMPONENT ujr0_c_attr_storedcalc OF STRUCTURE <ls_entity_mbr4> TO
<lf_storedcalc4>.
IF sy-subrc = 0 AND <lf_storedcalc4> = ujr0_cs_calc-calculated_member.
lf_non_base4 = ujr0_cs_calc-calculated_member.
ENDIF.
" Disaggregate non base member
IF lf_non_base4 = ujr0_cs_calc-calculated_member.
" A more precise version is to retrieve only accessible member of IS_USER
CALL METHOD lo_entity4->get_children_mbr
EXPORTING
i_parent_mbr = <l_entity4> " Parent
i_level = -99 " -99 = All children in any level; -1 = direct child
if_only_base_mbr = abap_true " Only base member
IMPORTING
et_member = lt_entity_mbr4.
" Re-calculate the keyfigure, divide by N = number of base members
" Usually it doesn't matter with IF_CALC_DELTA = false,
" if the operation is linear mathematical.
DESCRIBE TABLE lt_entity_mbr4 LINES l_num_base4.
" Avoid divide by zero
IF l_num_base4 > 0.
<l_keyfigure4> = <l_keyfigure4> / l_num_base4.
" Copy N times with new base members
LOOP AT lt_entity_mbr4 ASSIGNING <l_base_mbr4>.
<l_entity4> = <l_base_mbr4>.
" When IF_CALC_DELTA = true, appending means the latest records take effects,
" previous records with same dimension member will be overwritten.
" The newly appended records will also be looped and processed.
APPEND <ls_record4> TO ct_array.
ENDLOOP.
ENDIF. " divide by zero
" Remove the old one
DELETE ct_array.
ENDIF.
ENDIF.
ENDLOOP.
endmethod.
Download