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: 
uladzislau_pralat
Contributor


Latest BW releases offer better options for coding Customer Exit Variables by means of using:

  • RSROA_VARIABLES_EXIT_BADI BADI instead of RSR00001 exit to structuring code better (since BW 7.31);

  • New ABAP features to write short and robust code (since ABAP 7.40 and some features since ABAP 7.02).


 

I created a simple BW Query based on SFLIGHT data model to demonstrate renewed ABAP in action. The Query displays number passengers per airline who traveled certain distance ranges specified on selection screen.

 

If Distance Ranges are not in a sequence, then Customer Exit issues an error message:



So what Customer Exit is doing:

  • Sets Default Values for Characteristic Distance Range Variables;

  • Sets Text Distance Range Text Variables based on user input;

  • Validates Distance Characteristic Range Variables.


I coded all above in RSROA_VARIABLES_EXIT_BADI BADI implementation (trx. SE19 enhancement spot RSROA_VARIABLES_EXIT). It is possible to have multiple BADI implementations and isolate coding for a set of variables that logically belong to each other.



BADI implementations are isolated by means of Filter Values





BADI implementation will be executed for DISTANCE InfoObject Variables (Combination 1) as well as for Texts Variables (Combination 2) and at the time of Variables Validation (Combination 3).

Note: if you need to code formulas in the BADI implementation Filter Val. will be following:

Value 1 =  1FORMULA,  Filter  = IOBJNM

 

Actual coding is done in IF_RSROA_VARIABLES_EXIT_BADI~PROCESS method of ZCL_RSROA_VAR_EXIT_DISTANCE class



 

Below is IF_RSROA_VARIABLES_EXIT_BADI~PROCESS method code in ABAP 7.40 syntax:

 

METHOD if_rsroa_variables_exit_badi~process.

CASE i_step.
WHEN 1.       "Before Selection
CASE i_vnam.
WHEN 'DIST_1'.
c_t_range
= VALUE #( ( sign = 'I' opt = 'EQ' low = '00600' ) ).
WHEN 'DIST_2'.
c_t_range
= VALUE #( ( sign = 'I' opt = 'EQ' low = '01000' ) ).
WHEN 'DIST_3'.
c_t_range
= VALUE #( ( sign = 'I' opt = 'EQ' low = '05000' ) ).
WHEN 'DIST_4'.
c_t_range
= VALUE #( ( sign = 'I' opt = 'EQ' low = '09000' ) ).
ENDCASE.
WHEN 2.    "After selection screen
CASE i_vnam.
WHEN 'DIST_1H_TXT'
OR 'DIST_2H_TXT'
OR 'DIST_3H_TXT'
OR 'DIST_4H_TXT'.
c_t_range
= VALUE #( ( low  = replace( val = |{ i_t_var_range[ vnam = substring( val = |{ i_vnam }| off = 0 len = 6 ) ]-low }| regex = '^0+' with = '' occ = 1 ) ) ).
WHEN 'DIST_2L_TXT'
OR 'DIST_3L_TXT'
OR 'DIST_4L_TXT'
OR 'DIST_5L_TXT'.
c_t_range
= VALUE #( ( low = replace( val = |{ i_t_var_range[ vnam = i_vnam+0(5) && |{ i_vnam+5(1) - 1 }| ]-low + 1 }| regex = '^0+' with = '' occ = 1 ) ) ).
ENDCASE.
WHEN 3.    "Validation
TRY.
DO 3 TIMES.
IF i_t_var_range[ vnam = 'DIST_' && |{ sy-index }| ]-low > i_t_var_range[ vnam = 'DIST_' && |{ sy-index + 1 }| ]-low.
DATA(w_message) = |Range| && |{ sy-index }| && | is greater then Range | && |{ sy-index + 1 }|.
CALL FUNCTION 'RRMS_MESSAGE_HANDLING'
EXPORTING
i_class 
= 'OO'
i_type  
= 'E'
i_number
= '000'
i_msgv1 
= w_message.
RAISE EXCEPTION TYPE cx_rs_error.
ENDIF.
ENDDO.
CATCH cx_sy_itab_line_not_found INTO DATA(itab_line_not_found).
ENDTRY.
ENDCASE.

ENDMETHOD.

 

In step 1 (before selection screen) BADI sets initial values for Distance Characteristic Variables.

In step 2 (after selection screen) BADI reads Distance Characteristic Variables and populates Distance Text Variables.

In step 3 (validation) BADI validates Distance Characteristic Variables entered on selection screen.

The code is short, well structured and easy to understand. Imagine dumping code for all other BW variables in the system into the same BADI, then it would become unreadable and unmanageable.

 

The same logic implemented in RSR00001 customer exit using ABAP 7.0 syntax would look like this:
DATA: wa_range TYPE rsr_s_rangesid.
DATA: wa_var_range TYPE rrrangeexit.
DATA: w_vnam TYPE rszglobv-vnam.
DATA: w_dist_1 TYPE rschavl.
DATA: w_dist_2 TYPE rschavl.
DATA: w_message TYPE string.
DATA: wa_var_range_1 LIKE rrrangeexit.
DATA: wa_var_range_2 LIKE rrrangeexit.

CASE i_step.
WHEN 1.       "Before Selection
CASE i_vnam.
WHEN 'DIST_1'.
wa_range
-sign = 'I'.
wa_range
-opt  = 'EQ'.
wa_range
-low  = '00600'.
APPEND wa_range TO e_t_range.
WHEN 'DIST_2'.
wa_range
-sign = 'I'.
wa_range
-opt  = 'EQ'.
wa_range
-low  = '01000'.
APPEND wa_range TO e_t_range.
WHEN 'DIST_3'.
wa_range
-sign = 'I'.
wa_range
-opt  = 'EQ'.
wa_range
-low  = '05000'.
APPEND wa_range TO e_t_range.
WHEN 'DIST_4'.
wa_range
-sign = 'I'.
wa_range
-opt  = 'EQ'.
wa_range
-low  = '09000'.
APPEND wa_range TO e_t_range.
ENDCASE.
WHEN 2.    "After selection screen
CASE i_vnam.
WHEN 'DIST_1H_TXT'
OR 'DIST_2H_TXT'
OR 'DIST_3H_TXT'
OR 'DIST_4H_TXT'.
READ TABLE i_t_var_range INTO wa_var_range WITH KEY vnam = i_vnam+0(6).
SHIFT wa_var_range-low LEFT DELETING LEADING '0'.
wa_range
-low = wa_var_range-low.
APPEND wa_range TO e_t_range.
WHEN 'DIST_2L_TXT'
OR 'DIST_3L_TXT'
OR 'DIST_4L_TXT'
OR 'DIST_5L_TXT'.
w_vnam
= i_vnam.
w_vnam+5
(1) = w_vnam+5(1) - 1.
READ TABLE i_t_var_range INTO wa_var_range WITH KEY vnam = w_vnam+0(6).
wa_var_range
-low+0(5) = wa_var_range-low+0(5) + 1.
SHIFT wa_var_range-low LEFT DELETING LEADING SPACE.
wa_range
-low = wa_var_range-low.
APPEND wa_range TO e_t_range.
ENDCASE.
WHEN 3.    "Validation
DO 3 TIMES.
w_vnam
= sy-index.
SHIFT w_vnam LEFT DELETING LEADING SPACE.
CONCATENATE 'Range' w_vnam INTO w_message SEPARATED BY SPACE.
CONCATENATE 'DIST_' w_vnam INTO w_vnam.
READ TABLE i_t_var_range INTO wa_var_range_1 WITH KEY vnam = w_vnam.
CHECK sy-subrc = 0.
w_vnam
= sy-index + 1.
SHIFT w_vnam LEFT DELETING LEADING SPACE.
CONCATENATE w_message 'is greater then' w_vnam INTO w_message SEPARATED BY SPACE.
CONCATENATE 'DIST_' w_vnam INTO w_vnam.
READ TABLE i_t_var_range INTO wa_var_range_2 WITH KEY vnam = w_vnam.
CHECK sy-subrc = 0.
IF wa_var_range_1-low > wa_var_range_2-low.
CALL FUNCTION 'RRMS_MESSAGE_HANDLING'
EXPORTING
i_class 
= 'OO'
i_type  
= 'E'
i_number
= '000'
i_msgv1 
= w_message.
RAISE no_processing.
ENDIF.
ENDDO.
ENDCASE.

 

ABAP 7.0 syntax is almost twice the size of ABAP 7.40 syntax. The comparison speaks for itself.

 

Now I want quickly go over the ABAP 7.40 syntax features that are the most useful for coding Customer Exit Variables.

 

 

String Templates

They are powerful option for defining Variables values. String Templates saves you trouble wrting multiple CONCATENATE, WRITE, SHIFT, REPLACE, etc statements. All of them can be combined into one String Template thanks to:

  • Chaining Operators && (to concatenate strings)

  • Embedded Expressions  { expression }

  • Build-in functions


In my example, I build w_message string concatenating strings and expressions (sy-index system variable and sy-index offset system variable). Note that also inline declaration of w_message ABAP variable was used to save trouble defining it beforehand.

 

DATA(w_message) = |Range| && |{ sy-index }| && | is greater then Range | && |{ sy-index + 1 }|.

 

 

VALUE Operator

Can be used initalize Variable table parameter in just one statement.

In my example, I set default Distance Ranges as

 

c_t_range = VALUE #( ( sign = 'I' opt = 'EQ' low = '00600' ) ).

 

 

Expression to Access Internal Table

In i_step = 2 (after selection screen) Variable value can be conveniently read from Internal Table using expression rather then READ TABLE statement

In my example, I populate Distance Text Variable reading Distance Characteristic Variable. Note that replace function is strips leading 0. This is also a good example of nested expressions.

 

c_t_range = VALUE #( ( low  = replace( val = |{ i_t_var_range[ vnam = substring( val = |{ i_vnam }| off = 0 len = 6 ) ]-low }| regex = '^0+' with = '' occ = 1 ) ) ).


 

 

Expression in IF Statment

In i_step = 3 (validation) expressions can be used in IF statement to validate Variables values.

In my example, in IF statement I check if preceding Distance Range is not greater then subsequent Distance Range.

 

IF i_t_var_range[ vnam = 'DIST_' && |{ sy-index }| ]-low > i_t_var_range[ vnam = 'DIST_' && |{ sy-index + 1 }| ]-low.
     ...

ENDIF.

1 Comment
Labels in this area