Skip to Content

If you want to control the processing of BEx-Queries you can define different types of variables: Manual Entry/Default Value, Replacement Path, SAP Exit, Authorization or Customer Exit. This blogs deals about how to define such variables and how you can develop them by using ABAP Objects.

UPDATE: A new blog post has been created to this topic: BEx-Userexits reloaded . There, I discuss an important change and share some experiences within the usage of this framework.

Introduction

For implementing customer-exit variables you have to implement the Extension RSR00001 in the transaction SMOD. There have been some documents about it, like http://scn.sap.com/docs/DOC-26617.

The used customer-exit has to following interface-definition based on the function module EXIT_SAPLRRS0_001:

/wp-content/uploads/2013/04/interface_110653.png

The parameters have the following meaning

  • I_VNAM: Name of the Variable
  • I_VARTYP: Type of the Variable
  • I_IOBJNM: Used InfoObject
  • I_S_COB_PRO: Structure with the properties of this InfoObject
  • I_S_RKB1D: Structure with the properties of the executed query
  • I_PERIV: Current fiscal-period
  • I_T_VAR_RANGE: Selected Values of the variablen screen
  • I_STEP: Processing Step
  • E_T_RANGE: Result-Selection of the variable
  • E_MEEHT, E_MEFAC, E_WAERS, E_WHFAC these fields are not used!
  • C_S_CUSTOMER: Structure with steering data

The processing of the variable will be managed by the importing parameter I_STEP. Each step represents a specific point in the processing of a variable screen. The following diagram shows the several options. The green check marks means an error-free proceeding and the red bolt means an error is raised by an exception.

/wp-content/uploads/2013/04/process_110652.png

For your own variables you will have to program in ABAP your extension and interpret the parameters. This behaviour will be discussed here:

Now – If you want to implement customer-exit variables, you will have several options:

1. Implement directly in the include ZXRSRU01, as it is shown in the SAP Help. Using this way, you will have a very fast implementation, but the price will be very high:

  • Every user of exit-variables will have to change this include. The main disadvantage of this approach is the fact, that each modification of this peace of code will influence all users of exit-Variables.
  • An error in this include leads into an error for each report with exit-variables.
  • Tracing and debugging will be very difficult because you will have to look about the whole source code.
  • Some more…

2. Encapsulate your exit-variables. E.g. use function modules or classes for building your user-exit variables. As we are in 2012, I will show a framework with ABAP Objects, which makes it very easy to implement BEx-Customerexit Variables.

By using this approach, you will gain a lot of features, without dealing with them directly:

  • Minimal effort for new Variables through Inheritance.
  • Type-safe and clear structure for variables.
  • No coding dependencies between different variables.
  • No redundant parameters while step-processing.
  • You can see at anytime, which coding implements a variable.
  • Tracing and debugging will be very easy, through a clear structure.

The Idea

The idea is quite simple: Just say, every variable is a instance of a class. Every instance must support at least the following events of the processing-cycle (in Brackets, I write the “old” abbreviation ):

– Initialization

– before Variablescreen ( I_STEP = 1 )

– after Variablescreen ( I_STEP = 2 )

– Authority check ( I_STEP = 3 )

– check  ( I_STEP = 0 )

Now, put this events in methods of an interface. Why using a interface? I often talk about a contract, when building dynamic systems with ABAP OO based upon interfaces, because both partners ( client and service ) can rely on it. If a class implements an interface, every client can be sure, that this interface will be fulfilled by its specification.

In the following, I will show, how easy it is to encapsulate exit-variables with ABAP Objects. You will need at least these classes:

  • A factory for creating and managing variable instances
  • An variable interface, which defines the methods of the variable processing
  • A abstract variable for building the first node in your variable hierarchy
  • Concrete implementations of the variable interface

Look at the UML diagram. The central element is the variable interface, which will be implemented by an abstract class and used by a factory. The used function-pool has been inserted due to the example-class later.

/wp-content/uploads/2013/04/uml_diagramm_111272.png

The factory used here based upon the pattern, which I have discussed in http://scn.sap.com/community/abap/application-development/objects/blog/2012/02/20/factory-pattern-in-abap-oo. At least, the implementation pattern for the BEx-Variables is the so-called “Strategy-Pattern”.

I suggest the usage of an abstract class from which every concrete variable should inherit. With this construction, you will gain more flexibility and can reuse a lot of coding.

The Variable-Interface

The interface should looks like this:

/wp-content/uploads/2013/04/zif_111248.png

Every method of the interface encapsulate a step in the variable-processing. But the main difference is the fact, that every method has only those parameters which are needed in this step.

Now you can see what is the big advantage of using this strategy: At least you have a simple but powerful method signature for each processing step. If you develop a new variable you do not have to consider about “I_VNAM”, “I_STEP” and those other parameters, because the method signature has been optimized for each step!

Customization

By using the described factory-oo-pattern, you will have to define a customing table, which holds all implementation classes for the variables. In this table, you can define foreign-keys to the table RSZGLOBV where all variables are stored. With this key, you can ensure, that only variables of type “Customer-Exits” are entered and you can ensure, that only classes with a valid interface are used-for. ( Ok, this check have to be built by another view/search-help ).

/wp-content/uploads/2013/04/sm30_111250.png

By the way: Do you know who and how are your Customizing-Exit-Variables are implemented within your system? Even if you have function modules and select them at runtime – you do not know exactly where they are and if they are existing. With OO-approach, you can even ensure this at design-time!

Implementation in RSR00001

The implementation in the corresponding User-Exit include is even quite easy:

/wp-content/uploads/2013/04/zxrsru01_111187.png

As you can see, the coding in the include is very small and does not include any application specific coding.

At least, it is in the responsibility of each project to define and test the correct variables. But: No variable can destable the whole system!

If you have already an encapsulation, I will suggest that you only create the new variables with this new approach and only changes in existing exit-code will be migrated.

Example

The following class will show, how you can build an implementation class for a customer-exit variable. In my example, I need a customer-exit for determining the last day of the first quarter of the selected year. This exit has to be processed after the variable screen have been executed and the user inputs the selected year.

First, you will have to define your variable in the BEx-Querydesigner – because without this definition, no entry will be made in the RSZGLOBV-table and we use this for our customizing.

After this, you need to create a new class which implements the interface  ZIF_BIU001_VARIABLE. In the described framework, I implemented an abstract class, do this for me and give me some supporting features.

/wp-content/uploads/2013/04/test_1_111254.png

Then you have to redefine the method “after_variable_screen” of the corresponding interface:

/wp-content/uploads/2013/04/test_2_111255.png

In this method you implement your desired functionality. When you look at this code you will discover that it is very short and does not handle to much interaction with the classical BEx-Customer-Exit Interface. So, you can get a clean and stable implementation for BEx-Customer-Exit variables.

The last step for using this variable is the customizing in the customizingtable above.

In one of my future blogs, I will show, how you can tests these variables with ABAPUnit.

Conclusion

In this blog, I show how easy it is to implement BEx-User-Exit-Variables with ABAP Objects. The here shown framework will bring up some very important features:

  • A more use-case centric development. For those you will have to implement a User-exit, it will be easier to say “the variable have to been executed {before|after} the variables popup” instead of the classical “i_step”-handling
  • Tracability: You can very easy track and debug each variable without having to much effort.
  • Easy-Enhancements: Use an abstract class and inherit from this and you will have your new variable.
  • Inherit different features for similar use-cases. Through a implementation hierarchy, you can reuse a lot of coding in similar variables.
  • Using other patterns like proxy and adapter bringing new aspects to your variables. For example: Tracing-Proxy or Authority-Proxy.
  • Unit-Testing with ABAP Unit. No more to say: Using a “variable-class”, it will be very easy to build up a Unit-Test for this variable.

The coding examples, I have shown here and the framework itself has been published at the CodeExchange Project “BI-Utils”. In the future, I plan to publish some more nice tools in this context.

To report this post you need to login first.

25 Comments

You must be Logged on to comment or reply to a post.

  1. Avinash Verma

    Hi Hendrik,

    Very nice blog, Bex user exit with strategy pattern will be very useful in terms of reusability and encapsulated methods.

    This will be really helpful in Transport of User exits into different landscapes. 🙂

    @Hendrik : Please elaborate customizing part, how we will define customization / table and where we will use it. In the given example I haven’t seen any custom tables.

    (0) 
    1. Hendrik Brandes Post author

      Hi Avinash,

      thank you for your annotations. Well, the customizing part is very easy: You build a customizing table, where you will have the keys “Variable”, “Class” and perhaps some more technical fields. I will share how to build the customizing part in detail – hopefully tomorrow.

      Kind regards,

      Hendrik

      (0) 
      1. Avinash Verma

        Hi Hendrik,

        Thanks for reply, i have done with customizing table creation and maintenance, in my views this customizing table is only for BW control and has no relationship with processing of User Exit using factory OO pattern, correct me and explain if it is not the case.

        I have 1 more question in “Implementation in RSR00001” can you please provide definition of class/interface zcl_biu001_var_factory and zcx_biu001_execution_failed

        method: get_var_instance

        Thanks,

        Avinash

        (0) 
        1. Avinash Verma

          Hi Hendrik,

          thanks for very useful blog 🙂

          Few more question in “Implementation in RSR00001” can you please provide definition of class/interface zcl_biu001_var_factory and zcx_biu001_execution_failed 

          method: get_var_instance  and its parameters and explain below 2 classes

          • A factory for creating and managing variable instances 
          • A abstract variable for building the first node in your variable hierarchy
          • Parameters and events defined for methods of variable interface
          • how  value for I_VNAM and I_STEP will be processed by this factory pattern into customer exit.

          I am new to ABAP OO so stucked here, please help me out.

          Thanks,

          Avinash

          (0) 
            1. Avinash Verma

              Hi Hendrik,

              Thanks for reply, I tried to access nugget from bi tools codex project , but i am not able to get anything its showing xml error.

              Regard,

              Avinash

              (0) 
              1. Hendrik Brandes Post author

                Hello Avinash,

                finally I did it (had some work todo ;-)): I created some documentation for the BI-Utils 001 (“Bex Customer-Exit Variables”). The appendix of this documentation includes the sourcecodes for those, who are not able to use the SAPLink toolset.

                Kind regards,

                Hendrik

                (0) 
                1. Jomy Joy

                  Hello Hendrik,

                  Can you please post this document on this page as an attachement as I cant find this project in Code Exchange Project ?

                  Thanks & regards,

                  Jomy

                  (1) 
  2. Michael Fluch

    Hi Hendrik,

    I installed and tested your framework in our test environment. with the excellent documentation it worked our very well.

    just one thing…

    the implementation works quite well for i_step 1 and 2, but not for i_step 3. Because i_step 3 is not called by variable, hence i_vnam is empty and no class can be determined by the factory class.

    question: what is the idea how i_step 3 logic should be handled by your framework? did I do anything wrong while installation, or is i_step 3 just not yet supported?

    best regards

    Michael

    (0) 
    1. Hendrik Brandes Post author

      Hello Michael,

      thank you for your comments and remarks. You got right, I have implemented the I_STEP 3 quite simple and not (very) useable. So you didn’t make any error in the installation.

      In the meantime, I have published a new version of the framework and introduced a check-model for the I_STEP = 3 and prepare a new article about it.

      Kind regards,

      Hendrik

      (0) 
  3. Matthew Billingham

    I wish I’d read this a few months ago when I “invented” and implemented something fairly similar to what you have here.

    I think it is better than the Z-BADI suggestion that has been implemented in a number of places.That solution clogs up when you have more than one variable defined in a single BAID implementation.

    (0) 
    1. Hendrik Brandes Post author

      Hello Matthew,

      thank you for your comment. I agree to you, that most of the BADI-Implementations are not very handy. I often see solutions, which only encapsulates the calling step but do not simply the implementation process nor the traceability.

      Sadly, but true: SAP itself has introduced a new BADI (RSROA_VARIABLES_EXIT_BADI for BEx-Variables (available with SAP BW7.30), which is just another copy of the customer-exit interface and in addition…they refactored internally with function modules called “RSR_VAR_VALUES_{BEFORE|AFTER|CHECK} ).

      Kind regards,

      Hendrik

      (0) 
      1. Matthew Billingham

        Revisiting this, as I’ve mentioned it as an excellent use of OO design in this discussion. http://scn.sap.com/community/abap/blog/2014/01/09/classical-way-to-abap-oo-style-of-coding

        My implementation, btw, was based on creating classes containing the same name as the variable, with a ZCL_BEX prefix.

        My top level code looks something like.

        var = zcl_bex=>get_var( vnam ).

        if var->it_is_this_step( step )

          var->get_value( exporting… changing… ).

        endif.

        (0) 
      2. Jürgen Noe

        Hi Hendrik,

        what are your experiences with BADI ‘RSR_OLAP_BADI’ or enhancement spot ‘RSROA’?

        They were highly recommended from SAP to use instead of old CMOD exits.

        Kind Regards,

        Jürgen

        (0) 
        1. Hendrik Brandes Post author

          Hi Jürgen,

          I know both, the BADI and the enhancement spot. Sadly, SAP missed the change to redesign the interface of the BEx-Customer variables. E.g. internally, they work already in an event-driven mechanism, as I suggest with the “Easy Bex-Variable”-pattern. (Look for the FM RRS_VAR_VALUES_EXIT_AFTER|BEFORE|CHECK ).

          All of my customer perform a normal migration with out going into this new enhancement options. Currently, I see no really advantage of using them – only the reduction of the call-stack. And: Most of the consultants are not really familar with the configuration options via SE18/SE19. So, they decide to use the well-known include driven approach.

          Additional: The new enhancement spot is not well designed, because the filter options for info-object is not really sufficient.

          Do you use the new approach?

          Kind regards,

          Hendrik

          (0) 
          1. Jürgen Noe

            Hi Hendrik,

            I experience the same, most of the consultants don’t know how to handle the  BADI in SE18/SE19.

            One of my customer successfully uses the BADI implementation and it helped him to get rid of transportation problems when several developers have to make changes in the BEX exit or want to create new vraibles. He’s very lucky with it.

            But more than 90% of my customers use old techniques like calling FMs that use a certain naming convention. For the normal BW developer is ABAP/OO sometimes also a little challenge. But I recognize a knowledge increase in ABAP/OO and it is used quite more often over the last years.

            But the functional approach has still the majority of supporters.

            Thanks for sharing your thoughts and experiences.

            King regards,

            Jürgen

            (0) 
  4. Senthil Kumar

    Hi Hendrik,

    thanks for very useful documents.

    i am having a small doubt. IN the CMOD exit code, i_vnam will be blank for I_STEP = 3. How we will find the class from the factory ?

    If I_VNAM is blank, then the check “If lc_variable is bound” will be failed, you will not reach the Case i_step = 3.

    Am I missing something ?

    Thanks

    Senthil A

    (0) 
  5. Loed Despuig

    Hi Hendrik, nice document!

    May I ask what will be the difference of I_STEP = 2 to I_STEP = 0 or 3?

    I mean, based on the diagram (data flow) above, I think those 3 have no differences? Am I right? Or how will I use the I_STEP = 0 or 3? In what scenario will I need them? Can you cite an example for 0 and 3?

    Thank you!

    Loed

    (0) 

Leave a Reply