This is a quick introduction to some of the tables involved in the standard SAP authorization model and one
of the specific ones in the BI authorization model. For more details, please refer to SAP BI online documentation and to the presentation “An Expert Guide to New SAP BI Security Features” in
SDN, (you will need SDN access).
Example
This example is only for illustrative purposes. Bear in mind that when you are searching for specific authorizations, you need to consider both ranges and wild cards.
Suppose you want to know which uses are granted to access data in company code 1000. Start by looking at table RSECVAL “Authorization Value Status” in transaction SE16. Enter ‘0COMP_CODE’ in field TCTIOBJNM, ‘I’ in field TCTSIGN, ‘EQ’ in field TCTOPTION and ‘1000’ in field TCTLOW.
Figure 1 – Table RSECVAL, lookup authorization object based on Company Code
You will find one or several BI analysis authorization objects (field TCTAUTH). Suppose you got one record with TCTAUTH = ZCC_1000. Now to find the list of standard authorization objects that use the BI analysis authorization ZCC_1000, look at table UST12 “User master: Authorizations”. Enter ‘S_RS_AUTH’ in field OBJCT, ‘BIAUTH’ in FIELD, and ‘ZCC_1000’ in VON.
Figure 2 – Authorizations table UST12
in tables AGR_1250 and AGR_USERS, see picture below.
SAP, R/3, SAP NetWeaver, Duet, PartnerEdge, ByDesign, SAP Business ByDesign, and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and other countries
SAP BI Global report variable User Exit modularization
Summary
In an SAP BI Project, along with new reporting needs, new requirements for Global Report Variables of the type customer exit are generated. It is typical then for the respective user exit code to grow to a few thousand lines, resulting in code that is hard to manage, debug, and use in a multi-team environment.
Background
SAP BI is a Business Warehouse in which data models are created to support the extraction, transformation, load and reporting. When designing a report, some requirements have certain complexity that lead to the creation of custom exit code global report variables. For example, a user enters a month and the report requires an interval created for the ‘quarter to date’ of the entered month: the user entered May 2008, the report requires a variable that reflects the interval Apr-May 2008 (Q2-2008). This type of variable requires a ‘custom exit’ code. SAP has traditionally provided for custom code enhancements in the form of user exits and recently in the form of BADI (Business Add-In). Basically a user exit is an include in a function module that can be modified by the customer. The user exit FM for Global Report Variables EXIT_SAPLRRS0_001 tends to grow in a single piece of code and its maintenance become cumbersome.
Modularization
Modularization has advantages
.The code is easier to read. Instead of scrolling through pages and pages of code, just go to a specific form in a program
If the code modules are independent, the local use of variables reduces the interference between developers. Also, developers can be working on a specific module without interfering with each other. The standard approach based on multiple ‘case’ statements and ‘if’ statements for i_vnam makes it hard to ‘know’ if you are inserting the code in the right place.
The current approach goes through all the code to find the variable. A new approach could call the specific module directly.
Dynamic ‘PERFORM’ Command
The basis for this modularization approach is a dynamic ‘PERFORM’ command. Based on the variable, it performs a specific form in an ABAP/4 report with a name made of a standard preffix and the variable name, for example, ZBW_ZXRSRU01_<vnam>_REP. In a dynamic call for a PERFORM command, the ABAP/4 code will fail with a short dump if the report / form does not exist unless there is a ‘IF FOUND’ addition to the code line.
The approach is to ‘migrate’: start moving variables to the dynamic perform command step by step. A variable E_VAR_PROCESSED is set in the form to ‘tell’ that the calculation was made and no need to continue through the ‘old’ code. In case there is no form/report for the specific variable, it will continue through the old code. Define a custom executable ABAP/4 report in transaction SE38 and create one report per custom-exit global report variable. The form in the report will have exactly the same interface as the user exit function module plus a exporting parameter ‘E_VAR_PROCESSED’ as mentioned above:
(..)FORM zbw_zxrsru01_var_form
USING
i_vnam LIKE rszglobv-vnam
i_vartyp LIKE rszglobv-vartyp
i_iobjnm LIKE rszglobv-iobjnm
i_s_cob_pro TYPE rsd_s_cob_pro
i_s_rkb1d TYPE rsr_r_rkb1d
i_periv TYPE rro01_s_rkb1f-periv
i_t_var_range TYPE rrs0_t_var_range
i_step TYPE i
CHANGING
e_t_range TYPE rsr_t_rangesid
e_meeht LIKE rszglobv-meeht
e_mefac LIKE rszglobv-mefac
e_waers LIKE rszglobv-waers
e_whfac LIKE rszglobv-whfac
e_var_processed TYPE c
c_s_custome TYPE rro04_s_customer.(...)
(..)
FORM zbw_zxrsru01_var_form
USING
i_vnam LIKE rszglobv-vnam
i_vartyp LIKE rszglobv-vartyp
i_iobjnm LIKE rszglobv-iobjnm
i_s_cob_pro TYPE rsd_s_cob_pro
i_s_rkb1d TYPE rsr_r_rkb1d
i_periv TYPE rro01_s_rkb1f-periv
i_t_var_range TYPE rrs0_t_var_range
i_step TYPE i
CHANGING
e_t_range TYPE rsr_t_rangesid
e_meeht LIKE rszglobv-meeht
e_mefac LIKE rszglobv-mefac
e_waers LIKE rszglobv-waers
e_whfac LIKE rszglobv-whfac
e_var_processed TYPE c
c_s_custome TYPE rro04_s_customer.
(...)
In the form code below, the current month is calculated based on the system date (only for illustration purposes, there is a standard SAP exit variable for that).
TYPE-POOLS: rs, rsr, rro01, rrke, rrs0, sydes, rsbbs.*----------------------------------------------** Form ZBW_ZXRSRU01_VAR_FORM*----------------------------------------------** text*----------------------------------------------*FORM zbw_zxrsru01_var_form
USING
i_vnam LIKE rszglobv-vnam
i_vartyp LIKE rszglobv-vartyp
i_iobjnm LIKE rszglobv-iobjnm
i_s_cob_pro TYPE rsd_s_cob_pro
i_s_rkb1d TYPE rsr_s_rkb1d
i_periv TYPE rro01_s_rkb1f-periv
i_t_var_range TYPE rrs0_t_var_range
i_step TYPE i
CHANGING
e_t_range TYPE rsr_t_rangesid
e_meeht LIKE rszglobv-meeht
e_mefac LIKE rszglobv-mefac
e_waers LIKE rszglobv-waers
e_whfac LIKE rszglobv-whfac
e_var_processed TYPE c
c_s_customer TYPE rro04_s_customer.CONSTANTS:
c_eq(2)TYPE c VALUE'EQ',
c_i(1)TYPE c VALUE'I',
c_x(1)TYPE c VALUE'X',
c_1 TYPE i VALUE1.DATA:
lv_curr_date TYPE sy-datum,
lv_cur_month TYPE c LENGTH6,
s_range TYPE rsr_s_rangesid.IF i_step = c_1.
lv_curr_date = sy-datum.
lv_cur_month = lv_curr_date+4(2).CONCATENATE lv_curr_date+0(4) lv_cur_month INTO s_range-low.
s_range-opt = c_eq.
s_range-sign= c_i.APPEND s_range TO e_t_range.ENDIF.
e_var_processed = c_x.ENDFORM."ZBW_ZXRSRU01_VAR_FORM
TYPE-POOLS: rs, rsr, rro01, rrke, rrs0, sydes, rsbbs.
*----------------------------------------------*
* Form ZBW_ZXRSRU01_VAR_FORM
*----------------------------------------------*
* text
*----------------------------------------------*
FORM zbw_zxrsru01_var_form
USING
i_vnam LIKE rszglobv-vnam
i_vartyp LIKE rszglobv-vartyp
i_iobjnm LIKE rszglobv-iobjnm
i_s_cob_pro TYPE rsd_s_cob_pro
i_s_rkb1d TYPE rsr_s_rkb1d
i_periv TYPE rro01_s_rkb1f-periv
i_t_var_range TYPE rrs0_t_var_range
i_step TYPE i
CHANGING
e_t_range TYPE rsr_t_rangesid
e_meeht LIKE rszglobv-meeht
e_mefac LIKE rszglobv-mefac
e_waers LIKE rszglobv-waers
e_whfac LIKE rszglobv-whfac
e_var_processed TYPE c
c_s_customer TYPE rro04_s_customer.
CONSTANTS:
c_eq(2) TYPE c VALUE 'EQ',
c_i(1) TYPE c VALUE 'I',
c_x(1) TYPE c VALUE 'X',
c_1 TYPE i VALUE 1.
DATA:
lv_curr_date TYPE sy-datum,
lv_cur_month TYPE c LENGTH 6,
s_range TYPE rsr_s_rangesid.
IF i_step = c_1.
lv_curr_date = sy-datum.
lv_cur_month = lv_curr_date+4(2).
CONCATENATE lv_curr_date+0(4) lv_cur_month INTO s_range-low.
s_range-opt = c_eq.
s_range-sign = c_i.
APPEND s_range TO e_t_range.
ENDIF.
e_var_processed = c_x.
ENDFORM. "ZBW_ZXRSRU01_VAR_FORM
Code for the dynamic PERFORM command is attached after the code below, dynamic perform command, this code is inserted at the beginning of include zxrsru01
(...)
lv_form typestring,
lv_report typestring.*STEP = 3 - Called after all variable processing and gets called only once*and not per variable. Here you can validate the user entries.**This code won't execute for step 3 as there is no variable passedCLEAR lv_var_proc.IF i_step =3.IFNOT i_s_rkb1d-infocube ISINITIAL.CONCATENATE'ZBW_ZXRSRU01_' i_s_rkb1d-infocube '_REP'INTO lv_report.
lv_form ='ZBW_ZXRSRU01_VAR_FORM'.PERFORM(lv_form)IN PROGRAM(lv_report)USING
i_vnam
i_vartyp
i_iobjnm
i_s_cob_pro
i_s_rkb1d
i_periv
i_t_var_range
i_step
CHANGING
e_t_range
e_meeht
e_mefac
e_waers
e_whfac
lv_var_proc
c_s_customer
IF FOUND.ENDIF.ELSE.CONCATENATE'ZBW_ZXRSRU01_' i_vnam '_REP'INTO lv_report.
lv_form ='ZBW_ZXRSRU01_VAR_FORM'.PERFORM(lv_form)IN PROGRAM(lv_report)USING
i_vnam
i_vartyp
i_iobjnm
i_s_cob_pro
i_s_rkb1d
i_periv
i_t_var_range
i_step
CHANGING
e_t_range
e_meeht
e_mefac
e_waers
e_whfac
lv_var_proc
c_s_customer
IF FOUND.ENDIF.IFNOT lv_var_proc ISINITIAL.EXIT.ENDIF.(...)
(...)
lv_form type string,
lv_report type string.
*STEP = 3 - Called after all variable processing and gets called only once
*and not per variable. Here you can validate the user entries.
*
*This code won't execute for step 3 as there is no variable passed
CLEAR lv_var_proc.
IF i_step = 3.
IF NOT i_s_rkb1d-infocube IS INITIAL.
CONCATENATE 'ZBW_ZXRSRU01_' i_s_rkb1d-infocube '_REP' INTO lv_report.
lv_form = 'ZBW_ZXRSRU01_VAR_FORM'.
PERFORM (lv_form) IN PROGRAM (lv_report)
USING
i_vnam
i_vartyp
i_iobjnm
i_s_cob_pro
i_s_rkb1d
i_periv
i_t_var_range
i_step
CHANGING
e_t_range
e_meeht
e_mefac
e_waers
e_whfac
lv_var_proc
c_s_customer
IF FOUND.
ENDIF.
ELSE.
CONCATENATE 'ZBW_ZXRSRU01_' i_vnam '_REP' INTO lv_report.
lv_form = 'ZBW_ZXRSRU01_VAR_FORM'.
PERFORM (lv_form) IN PROGRAM (lv_report)
USING
i_vnam
i_vartyp
i_iobjnm
i_s_cob_pro
i_s_rkb1d
i_periv
i_t_var_range
i_step
CHANGING
e_t_range
e_meeht
e_mefac
e_waers
e_whfac
lv_var_proc
c_s_customer
IF FOUND.
ENDIF.
IF NOT lv_var_proc IS INITIAL.
EXIT.
ENDIF.
(...)
Useful Function Modules for Global Report Variables
Where used list
Function module RSZ_X_WHERE_USED_LIST_GET finds where a report element is used. To get where a global report variable is used, enter the value from table RSZGLOBV, field VARUNIID as the import parameter I_ELTUID in the function module. (field VNAM contains the ‘readable’ variable technical name).
The table E_T_WHERE_USED_LIST will contain the list of queries that use the variable.
Variable test
Function Module RRS_VAR_VALUES_EXIT_FILL executes a global report variable user exit. As some of the variables execute in a specific step (i_step) it may need some break points and data manipulation to have the variable executed.
Code for standard ‘SAP’ exit variables
Function Module RREX_VARIABLE_EXIT has the code for SAP exit global report variables. If the variable is not ‘solved’ in this part of the code, it may execute at the end of this FM code as a RSVAREXIT_<varname>. For example RSVAREXIT_0I_CUFQU executes the code for variable 0I_CUFQU ‘Current Quarter of Fiscal Year (SAP Exit)’, resulting in a fiscal period interval for the current fiscal quarter.
Refresher on I_STEP
The global report variable user exit EXIT_SAPLRRS0_001 has I_STEP as an input parameter. You normally develop the custom code for a specific step, as explained below. It is useful to know the function modules involved when debugging, to set an appropriate break-point.
I_STEP = 0. This step is not called during report execution but when a report variable is used in an InfoPackage
I_STEP = 1 – Called prior to processing of variable pop-up and for each “customer exit” variables. Can be used to fill variable with default values. Function module EXIT_SAPLRRS0_001 is called with I_STEP = 1 in function module RRS_VAR_VALUES_EXIT_BEFORE
I_STEP = 2 – Called after the processing of the variable pop-up. Only for those variables that are not
marked as “ready for input” or are set to “mandatory variable entry”. . Function module EXIT_SAPLRRS0_001 is called with I_STEP = 2 in function module RRS_VAR_VALUES_EXIT_AFTER
It is important to remember that if a variable is filled in STEP 1 it will not be processed on STEP 2.
I_STEP = 3 – Called after all variable processing and gets called only once and not per variable. Here you
can validate the user entries. Function module EXIT_SAPLRRS0_001 is called with I_STEP = 3 in function
module RRS_VAR_VALUES_EXIT_CHECK.
SAP, R/3, SAP NetWeaver, Duet, PartnerEdge, ByDesign, SAP Business ByDesign, and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and other countries.