Problems with BEx Customer Exit Variables
Problems with BEx Customer Exit Variables

Problems with BEx Customer Exit Variables

Published at January 5, 2021by Jörg Brandeis

The following texts were partially or completely generated with the help of generative AI models.

The source code implementing the BAdI for customer exit variables is a disaster for quality-conscious developers, because it violates several Clean Code principles. And the BAdI concept in SAP BW/4HANA doesn't make things any easier here.

This article is part of a series on the topic "A design pattern for implementing customer exit variables".

  • first, in this article I want to analyze where the problems come from
  • then I make suggestions for what a clean design pattern could look like
  • finally I want to implement a concrete design pattern

Where is the problem?

Actually, there are several problems in the area of BEx customer exit variable implementations that reinforce each other. I have rarely seen a mature BW system in which everything in this area was implemented cleanly, clearly, and well-structured. Most of the time, sheer chaos reigns here. Even where a "framework" for outsourcing code has been implemented, there is a lot of uncontrolled growth.

The causes are manifold, and they start with the exit or BAdI concept of SAP....

The BAdI structure

The granularity of the classes

For implementing customer exit variables, the BAdI RSROA_VARIABLES_EXIT_BADI is used. It has a filter by InfoObject. That means we can decide, per InfoObject, which class should implement it. Unfortunately, however, this is the wrong granularity for the problem we want to solve. Because an InfoObject often has several variables, and these (usually) have different logics.

Here people often help themselves with a central implementation of the BAdI together with a custom framework, e.g. with function modules or methods that are then called based on naming conventions.

But the granularity of the classes should be neither InfoObject nor variable, but the different logics.

The granularity of the methods

The second problem with the BAdI is the single method PROCESS that the interface IF_RSROA_VARIABLES_EXIT_BADI specifies. Because this one method is called for each of the different processing points in time (parameter I_STEP) for different tasks with a multitude of parameters. This means the concept contradicts several Clean Code principles

"Functions should do one thing. They should do it well. They schoud do it only. "

"The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification -- and then shouldn't be used anyway."

Robert C. Martin, Clean Code

But what are the problems with this?

  • We need several case distinctions CASE in different dimensions:
    • InfoObject - I_VNAM
    • processing point in time - I_STEP
  • We have one central piece of code
    • if I adjust one aspect, then I have to test all the other aspects too. Only then can I be sure that nothing was broken.
    • Everything is transported together and not just the code that was actually changed.
  • Methods with extensive CASEs and many parameters are hard to test carefully. Unit tests with good coverage are most easily created for code with few branches.

The right granularity of the methods is the different processing points in time I_STEP. So one method for each point in time.

Too many cooks

I would like to begin this section with a quote from another article on this topic, which I can fully endorse:

"The customer exit for BEx variables has always been a good candidate for unstructured, extensive, and historically (often also hysterically) grown coding. This is due, on the one hand, to the fact that the exit (include ZXRSRU01) is usually worked on by many different developers (often also externally hired short-term consultants) with different programming views (functional or object-oriented). Not infrequently, they bring their own methods and approaches for structuring the customer exit (calling dynamic function modules / methods, nesting of includes, …) from other projects."

From the article "Coexistence of BAdI RSROA_VARIABLES_EXIT_BADI and customer exit EXIT_SAPLRRS0_001" by Thorsten Kessler

Over time, in a larger BW system, very many different authors of BEx exit variable implementations can be involved. In one project I once counted over 25. And of course these authors also have different experiences, interests, skills, and preferences. One might look for a similar logic and work with copy & paste and then adapt it. Another uses the latest features from ABAP, e.g. the VALUE constructor expression and inline declarations. Maybe an older colleague still uses includes to make logic reusable, because he distrusts classes. And a younger colleague no longer knows includes at all, only classes and methods.

Often new variables are created even though exactly the same function is already available in an existing variable. This is due, on the one hand, to the fact that it is hard to get a complete overview of the existing variables. And on the other hand, perhaps one doesn't trust colleagues' variables either. Ultimately, it isn't much work to create a new variable.

So a uniform design pattern is needed so that the quality of the implementations is consistently high. The search for existing variable logics should be simplified, and the trust in colleagues' variable exits should be strengthened.

Same same, but different

Often there are several variable implementations that do exactly the same thing. They differ only in some small detail. Here are a few examples:

  • Variables that refer to another variable. E.g.
    • FISCPER minus 1 for variable X
    • FISCPER minus 1 for variable Y
    • ...
  • Variables that differ only in a fixed value, e.g.
    • CALDAY minus 7 days
    • CALDAY minus 14 days
    • ...

Unfortunately, that one variable refers to another variable can only be seen in the code. Or in the (not always maintained) description text.

The goal has to be that logic is implemented exactly once. And that the dependencies of variables are made transparently visible.

DRY, DRY, DRY

In the logic there are again and again the same, similar patterns in three steps:

  1. Determine reference data - e.g. data from other variables or the system date
  2. Calculate new values - the actual logic, e.g. calculations, selection of data with Open SQL, etc.
  3. Assemble the output - build the CHANGING table C_T_RANGE with a value, lists of single values, intervals, or ranges

The code in these steps repeats again and again. Most of the things in it seem trivial, but nevertheless it contradicts the Don't Repeat Yourself (DRY) principle of Clean Code. A nice example here is accessing the values of another variable from the parameter I_T_VAR_RANGE. Although that is simple, it doesn't have to be implemented 100 times. And some less important aspects are often ignored in the many implementations. For example how error situations should be handled. For instance when a single value is needed, but the other variable returns a list of 4 values...

The remedy here is uniform methods that support the developer during implementation and reduce the code per logic to the essentials.

Persuasion work

For the problems shown, there are of course also elegant solutions, which I have already hinted at above. In the following articles on this topic I want to outline them. It is important to me to convince the BW developers with advantages. Because a new concept, framework, design pattern, or whatever you want to call it, must not only be defined but also lived. Only then can the BW project benefit from it.

As always, I look forward to comments on my page about this topic.

More articles

New!
New!