Вы находитесь на странице: 1из 8

www.biportal.org

Implement Performing Virtual Key Figures in BW 7.3 and BO4

Contents

1. Reporting Scenario requiring VKF

1

2. Create a Key Figure (VKF) and add it to the infocube, multiprovider

2

3. Create Classic BAdi Implementation with appropriate parameters and code in the methods

3

4. Create a query with the VKF and debug it

6

5. Identify position(s) of parameters and update the ABAP code

6

6. Create a BO4 Webi /OLAP Analysis report based on the BEx query via BICS

7

7. Possible impact on other queries and performance

7

1. Reporting Scenario requiring VKF

First of all I do not advise using Virtual Key Figures (VKF) unless you really have to. The reason for that is twofold: they are difficult to maintain, and they may impact query performance dramatically.

However, there are certain reporting scenarios where it is impossible to deliver a proper BI reporting solution without a VKF. For example, we have a Credit Limit set as an attribute of 0Customer and it is periodically updated. We also want to display Credit Limit in the reports as a Key Figure in order to apply currency conversions, aggregations by maximum value, etc. Having KF as an attribute of an infoobject does not give us these capabilities. At the same time if we copy the Credit Limit to the transactional object (Infocube) we would have to fully refresh it every time as the Credit Limit values get updated for each customer. Full cube refresh is not a great option in case of big data volumes.

This scenario leads us to a solution where we have to introduce a VKF and populate it at the report run time based on the current Credit Limit values from the Customer master data.

Here is a link to the document describing this process step by step:

In this post I will show how the scenario described above has been implemented and tested using BO4 frontend tools, addressing possible performance risks.

1

www.biportal.org

2. Create a Key Figure (VKF) and add it to the infocube, multiprovider

a Key Figure (VKF) and add it to the infocube, multiprovider Add the VKF to the

Add the VKF to the infocube(s) and multiprovider(s) where it is going to be used. In the transformation to the cube the VKF does not have to be mapped.

The runtime scenario will look as follows:

used. In the transformation to the cube the VKF does not have to be mapped. The

2

www.biportal.org

3. Create Classic BAdi Implementation with appropriate parameters and code in the methods

In TC SE19 choose BAdi RSR_OLAP_BADI:

code in the methods In TC SE19 choose BAdi RSR_OLAP_BADI: You have to create your own

You have to create your own implementation based on it and link it to relevant infoprovider(s).

Go to the implementation class (in my case ZCL_IM_VAR_IMPL_AR):

to the implementation class (in my case ZCL_IM_VAR_IMPL_AR): In the Attributes tab you have to enter

In the Attributes tab you have to enter Input/ Output parameters as well as internal tables that you want to use at the run time.

3

www.biportal.org

www.biportal.org class ZCL_IM_VAR_IMPL_AR definition public final create public . public section . interfaces

class ZCL_IM_VAR_IMPL_AR definition public final create public .

public section.

interfaces IF_EX_RSR_OLAP_BADI . types:

begin of ty_cust,

CUSTOMER

TYPE /BI0/OICUSTOMER,

/BIC/CDM_LIMI1 TYPE /BIC/OICDM_LIMI1, /BIC/ZCUR TYPE /BIC/OIZCUR, end of ty_cust . data P_KYF_CDM_LIMVK type I . data P_CHA_0DEBITOR type I . data P_CHA_ZCUR type I . data:

T_CUST type HASHED TABLE OF ty_cust WITH UNIQUE KEY customer .

Here is the code for each method in the Implementation Class:

method IF_EX_RSR_OLAP_BADI~DEFINE. DATA: l_s_chanm TYPE rrke_s_chanm, l_kyfnm TYPE rsd_kyfnm. FIELD-SYMBOLS:

<l_s_chanm> TYPE rrke_s_chanm. CASE i_s_rkb1d-infocube. WHEN 'FIAR_M03' OR 'FIAR_C03'. l_s_chanm-chanm = '0DEBITOR'. l_s_chanm-mode = rrke_c_mode-read. APPEND l_s_chanm to c_t_chanm. l_s_chanm-chanm = 'ZCUR'. l_s_chanm-mode = rrke_c_mode-chng_w_sel. APPEND l_s_chanm to c_t_chanm. APPEND 'CDM_LIMVK' TO c_t_kyfnm. ENDCASE. endmethod.

4

www.biportal.org

method IF_EX_RSR_OLAP_BADI~INITIALIZE. CASE i_s_rkb1d-COMPID. " different offset for each query WHEN 'FIAR_QUERY1'. IF t_cust IS INITIAL. SELECT CUSTOMER /BIC/CDM_LIMI1 /BIC/ZCUR FROM /BI0/PCUSTOMER INTO TABLE t_cust WHERE OBJVERS = 'A' AND /BIC/CDM_LIMI1 NE 0. ENDIF. p_kyf_CDM_LIMVK = 36. p_cha_0DEBITOR = 21. P_CHA_AZCS1100 = 30. WHEN ' FIAR_QUERY2'. IF t_cust IS INITIAL. SELECT CUSTOMER /BIC/CDM_LIMI1 /BIC/ZCUR FROM /BI0/PCUSTOMER INTO TABLE t_cust WHERE OBJVERS = 'A' AND /BIC/CDM_LIMI1 NE 0. ENDIF. p_kyf_CDM_LIMVK = 38. p_cha_0DEBITOR = 22. P_CHA_AZCS1100 = 32. ENDCASE. endmethod.

method IF_EX_RSR_OLAP_BADI~COMPUTE. FIELD-SYMBOLS <fs_CDM_LIMVK> TYPE ANY. FIELD-SYMBOLS <fs_0DEBITOR> TYPE ANY. FIELD-SYMBOLS <fs_ZCUR> TYPE ANY. FIELD-SYMBOLS <cust> TYPE ty_cust.

CASE i_s_rkb1d-COMPID. " Calculate only for queries with VKF WHEN 'FIAR_QUERY1' OR ' FIAR_QUERY2'.

ASSIGN COMPONENT p_kyf_CDM_LIMVK OF STRUCTURE c_s_data TO <fs_CDM_LIMVK

>.

ASSIGN COMPONENT P_CHA_0DEBITOR OF STRUCTURE c_s_data TO <fs_0DEBITOR>. ASSIGN COMPONENT P_CHA_ZCUR OF STRUCTURE c_s_data TO <fs_ZCUR>.

READ TABLE t_cust ASSIGNING <cust> WITH TABLE KEY CUSTOMER = <fs_0DEBITOR>. IF sy-subrc = 0. <fs_CDM_LIMVK> = <cust>-/BIC/CDM_LIMI1. <fs_ZCUR> = <cust>-/BIC/ZCUR. ELSE. <fs_CDM_LIMVK> = 0. ENDIF. ENDCASE. endmethod.

5

www.biportal.org

4. Create a query with the VKF and debug it

Query structure has to be defined prior to debugging as object positions change when query structure changes.

In the COMPUTE method you should analyze C_S_DATA object for your query:

method you should analyze C_S_DATA object for your query: 5. Identify position(s) of parameters and update

5. Identify position(s) of parameters and update the ABAP code

All Input and output parameters have to be identified in the C_S_DATA structure either by name or by value. This process has to be carried out for each query separately.

Sequentual numbers of relevant components have to be updated in the INITIALIZE method:

p_kyf_CDM_LIMVK = 38. p_cha_0DEBITOR = 22. P_CHA_AZCS1100 = 32.

6

www.biportal.org

6. Create a BO4 Webi /OLAP Analysis report based on the BEx query via BICS

One of the purposes of the VKF in this case is to be able to perform currency conversion on master data attributes (Credit Limit). When running the report please specify the target currency in the prompt:

the report please specify the target currency in the prompt: After execution all Key Figures in

After execution all Key Figures in the report have been converted to the target currency from the prompt. During report execution Credit Limit VKF is been read from 0Customer master data attributes:

VKF is been read from 0Customer master data attributes: It has been verified that VKFs work

It has been verified that VKFs work correctly with all BO4 tools (BO Analysis, Webi, OLAP Analysis, etc.)

7. Possible impact on other queries and performance

It is extremely important to make sure the code used in the VKF calculation is optimized and is properly placed. In the case above we read master data to the internal table only once at the query launch in the INITIALIZE method:

IF t_cust IS INITIAL. SELECT CUSTOMER /BIC/CDM_LIMI1 /BIC/ZCUR

7

www.biportal.org

FROM /BI0/PCUSTOMER INTO TABLE t_cust WHERE OBJVERS = 'A' AND /BIC/CDM_LIMI1 NE 0. ENDIF.

Please note, we use a HASHED internal table with a Unique key for attribute lookups. The lookup is done for every line from the cube used in the report calculation, therefore it is critical to have this code done the most optimal way. We have to READ data using WITH TABLE KEY for best performance results:

READ TABLE t_cust ASSIGNING <cust> WITH TABLE KEY CUSTOMER = <fs_0DEBITOR>.

We also have to make sure we read master data tables only in those queries where the VKF is used. Therefore, we have to do query name checks in the INITIALIZE method:

CASE i_s_rkb1d-COMPID. " different offset for each query WHEN 'FIAR_QUERY1'.

Similar check needs to be done in the COMPUTE method:

CASE i_s_rkb1d-COMPID. " Calculate only for queries with VKF WHEN 'FIAR_QUERY1' OR ' FIAR_QUERY2'.

If we do not check for query names the code will be executed for all queries based on the infoproviders mentioned in the BAdi parameters. This will badly impact performance of all these queries and may corrupt results.

8