an object oriented version of SAP enhancement concept. Its main idea is that
instead of filling special includes with ABAP code in some customer function style=’mso-bidi-font-weight:normal’>
you are to define some ABAP object class which implements a particular
interface (BADi interface) – a set of predefined method declarations.
the pros of the BADi concept besides the fact it is object-oriented (though I
know some people think OO overweighs all others pros and cons)? At my recent
project I was assigned a role of a development team leader and so I was aware
of software engineering management. And from this point of view BADI is much
better than customer exits. Sometimes more than one developer has different
tasks which include programming of the same customer-exit. One of the possible
consequences is a mixture of the code provoking errors, transport request
locking problems, etc. On the contrary, a particular BADI can have several
independent implementations, and so different tasks can be safely separated
with no source code conflicts or request deadlocks.
more idea… There are still lots of questions on various SAP ABAP forums (including
SDN) concerning ways of searching possible enhancements of one or another
business transaction. BADi
gives you one stable method of searching:
just place a break-point inside the method
style=’ and then execute the business transaction. After
the program stops at the break-point you can easily obtain BADi name and browse
the source code around the call point to get the most exact knowledge of
“terms and conditions” of the BADi call.
project we had to implement HR functionality, and there were several development
tasks including default value calculations for various infotypes (infotype is a
time dependent chunk of a person attributes – e.g. personal data, address data,
etc., infotype has its unique four-digit code).
SMOD you can find a customer enhancement designed for this kind of task – style=’mso-bidi-font-weight:normal’>PBAS0001. The enhancement contains
function module EXIT_SAPFP50M_001
which is commonly used for setting infotype defaults, and
for additional checks after a user has entered values into infotype fields.
Both user-exits have their counterparts in
. These are corresponding
and they are called from nearly the same call-up points of the source code.
It would be
nice to use them, but the matter is that those methods have only importing
parameters and obviously they were not intended to change infotype values.
And after hard
reflections and mental sweating on possible ways of the tasks separation I found
a solution – to create my own BADI and call it from the EXIT_SAPFP50M_001
start with transaction SE18. At the initial screen I entered the name – style=’mso-bidi-font-weight:normal’>ZPBAS0001_BADI_FLT and clicked the
checkbox I allowed my
BADI to have multiple implementations, and that is the main goal of the
proceeding. Now each developer (informed of the BADI existence) can create
his/her own fully independent implementation.
<p class=MsoNormal>But here we can improve the BADI. As we make developments for HR functionality the infotype code will always be involved. Different infotypes have different structure and we cannot make universal code for calculating default values. What I am leading to is that every implementation of the newly created BADI will be essentially infotype dependent. In that case I bet the very first statement of every implementation would be </p> <div style='mso-element:para-border-div;border:solid windowtext 1.0pt; mso-border-alt:solid windowtext .5pt;padding:1.0pt 4.0pt 1.0pt 4.0pt; background:#CCFFFF;margin-left:0cm;margin-right:206.75pt'> <p class=Sourcecode style='background:#CCFFFF;border:none;mso-border-alt:solid windowtext .5pt; padding:0cm;mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><b style='mso-bidi-font-weight: normal'> ><br> CHECK</b> > infty = <i style='mso-bidi-font-style:normal'>some_infotype_number</i>.<br style='mso-special-character:line-break'> <![if !supportLineBreakNewLine]><br style='mso-special-character:line-break'> <![endif]></p> </div> <p class=MsoNormal>Thus infotype code is an ideal candidate to become a filter value for implementations. In the <b style='mso-bidi-font-weight:normal'>Attributes</b> tab of the BADI definition you can see a checkbox <b style='mso-bidi-font-weight: normal'>Filter-depend</b>. The checkbox turns on filter capabilities of the BADI. <p><img height='400' alt='image' width='533' src='https://weblogs.sdn.sap.com/weblogs/images/3886/Image1_resize.gif' border='0'/> <p> <p> To finalize definition of filter dependent BADI we have to enter some data element name into <b style='mso-bidi-font-weight:normal'>Filter type</b> field, and the data element has to accept infotype codes as a value.</p> <p class=MsoNormal>There are special requirements for the data element to be used as a <b style='mso-bidi-font-weight: normal'>Filter type</b>. It has to be associated with some Search help, and one of the import parameter of the search help must be of the same type as data element. So, I was not successful when tried hastily to enter INFTY data element into the <b style='mso-bidi-font-weight:normal'>Filter type</b> field as it has no associated Search help. I did not find proper SAP standard data element (maybe I did not search thoroughly) and had to create one of name <b style='mso-bidi-font-weight:normal'>ZINFTY_FLT</b>. </p> <p><img height='400' alt='image' width='533' src='https://weblogs.sdn.sap.com/weblogs/images/3886/Image2_resize.gif' border='0'/> <p> <p> <p class=MsoNormal>Also I have created a Search help <b style='mso-bidi-font-weight:normal'>ZH_T582A_BADI</b> with export parameter of type <b style='mso-bidi-font-weight:normal'>ZINFTY_FLT</b>. </p> <p><img height='400' alt='image' width='533' src='https://weblogs.sdn.sap.com/weblogs/images/3886/Image4_resize.gif' border='0'/> <p> <p> <p class=MsoNormal>Finally, I associated previously created Search help with new Data element. </p> <p><img height='400' alt='image' width='533' src='https://weblogs.sdn.sap.com/weblogs/images/3886/Image3_resize.gif' border='0'/> <p> <p> <p class=MsoNormal>After that I could successfully enter the name of my Data element as the Filter type of the BADI.</p> <p class=MsoNormal>To be honest, the requirement looks odd. At least, I do not clearly understand the reason for an idea of obligatory Search help connection. Certainly defining filter values with Search help is convenient but what’s wrong if one can enter values manually?</p> <p class=MsoNormal>Why use Filtering? One can think that all the mess is about getting rid of one <b style='mso-bidi-font-weight:normal'>CHECK</b> statement. But do not forget that without filtering every time the BADI fires it creates class instances for all implementations defined and that costs.</p>
time to define methods of the BADI interface. It is done in the style=’mso-bidi-font-weight:normal’>Interface tab of BADI definition. Here
I can enter method names. Being not much eccentric I called them style=’mso-bidi-font-weight:normal’>GET_DEFAULT_VALUES and style=’mso-bidi-font-weight:normal’>CHECK_BEFORE_UPDATE.
clicking at the method name we are driven into a common class/interface
designer (SE24). And here we define all the method parameters. Note that each method
has one predefined import parameter
FLT_VAL of type ZINFTY_FLT for we defined the
BADI as filter dependent.
definition of the BADI seems to be completed and we can click the button style=’mso-bidi-font-weight:normal’>Save. As a result the BADI interface
will be activated and a special proxy class will be generated and also
At the call-up point
now is almost ready for an implementation. The final stroke is to call it up
somewhere. At the beginning of EXIT_SAPFP50M_001
function module we insert a special aided fragment of code. First, by
calling method style=’mso-bidi-font-weight:normal’>CL_EXITHANDLER=>GET_INSTANCE
we obtain an instance of the proxy
class, implementing BADI interface, and examine whether or not any
If it does,
then we call appropriate method of the interface instance which does the rest.
Note that before the call we calculate
proper filter value, and in this case it is an infotype code. At the first
glance it seems slightly odd that we place a single call to the BADI method while
it was defined as Multiple use
internal tables, no loop. Actually the interface instance is the instance of
the proxy class which was generated after saving BADI definition. Each proxy
class method contains a standard code snippet which finds and calls all the
implementations complying with filter value.
> cl_exithandler style=’mso-bidi-font-weight:normal’>DEFINITION LOAD
pbas0001_badi_instance style=’mso-bidi-font-weight:normal’>TYPE REF
*” VALUE(TCLAS) LIKE
*” VALUE(INNNN) LIKE
*” VALUE(IPSYST) LIKE
*” VALUE(I001P) LIKE
*” VALUE(I503) LIKE
*” VALUE(INNNN) LIKE
*” REFERENCE(IPREF) LIKE
pbas0001_badi_instance style=’mso-bidi-font-weight:normal’>IS INITIAL
sy-subrc <> 0.
sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
To create a
BADI implementation we start SE19 transaction. After entering implementation
name and BADI definition name you also can manually enter the name of the class
already existent which will implement the BADI, or the system can generate it
enough, for some reason or another a single class cannot be used for
implementing more than one BADI, in spite the fact that a class can implement
arbitrary number of interfaces. There could be circumstances when it is convenient
to use a single class to implement more than one BADI. Let’s treat it as an
item to a wish list for coming versions of ABAP.
this particular implementation to create some custom infotype automatically
when user executes some personnel management action (infotype 0000) or changes
somehow organizational assignment (infotype 0001). At the Defined filters
ALV control I insert two items: 0000 and 0001.
after entering appropriate code into a method implementation we can activate
implementation and begin testing and debugging.