Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
sergey_korolev
Active Contributor

Preamble

BADi is

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'>

EXIT_SAPxxxxxx

style='_nnn

style=',

you are to define some ABAP object class which implements a particular

interface (BADi interface) – a set of predefined method declarations.

What are

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.

And one

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

CL_EXITHANDLER=>GET_INSTANCE

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.

The Problem

In our

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).

In transaction

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

  EXIT_SAPFP50M_002

for additional checks after a user has entered values into infotype fields.

 Both user-exits have their counterparts in

BADi HRPAD00INFTY

. These are corresponding

methods IF_EX_HRPAD00INFTY~BEFORE_OUTPUT

and IF_EX_HRPAD00INFTY~AFTER_INPUT

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

and EXIT_SAPFP50M_002

.

Creating BADI

So, let’s

start with transaction SE18. At the initial screen I entered the name – style='mso-bidi-font-weight:normal'>ZPBAS0001_BADI_FLT and clicked the

button Create

.

By checking

Multiple use

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.

Filtering

<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>

Next step

Now it’s

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.

By double

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.

Saving

Now the

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

activated.

At the call-up point

The BADI

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

style='

we obtain an instance of the proxy

class, implementing BADI interface, and examine whether or not any

implementation exists.

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

. No

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.

Global data

declarations:

>CLASS

> cl_exithandler style='mso-bidi-font-weight:normal'>DEFINITION LOAD

.

DATA

:

  act_imp_existing TYPE

sxrt_boolean,

  pbas0001_badi_instance style='mso-bidi-font-weight:normal'>TYPE REF

TO

zif_ex_pbas0001_badi.

CONSTANTS:

  c_exit_name TYPE

exit_def VALUE

'ZPBAS0001_BADI'.

BADi call:

*&----


*

*&   Include

           ZXPADU01

                     

                   *

*&----


*

*"----

-


""Lokale Schnittstelle:

*"   IMPORTING

*"      VALUE(TCLAS) LIKE

  PSPAR-TCLAS

*"      VALUE(INNNN) LIKE

  PRELP STRUCTURE

  PRELP

*"      VALUE(IPSYST) LIKE

  PSYST STRUCTURE

  PSYST

*"      VALUE(I001P) LIKE

  T001P STRUCTURE

  T001P

*"      VALUE(I503) LIKE

  T503 STRUCTURE

  T503

*"   EXPORTING

*"      VALUE(INNNN) LIKE

  PRELP STRUCTURE

  PRELP

*"   CHANGING

*"      REFERENCE(IPREF) LIKE

  PREF STRUCTURE

  PREF

*"----

-


IF

pbas0001_badi_instance style='mso-bidi-font-weight:normal'>IS INITIAL

.

  CALL

METHOD

cl_exithandler=>

get_instance

    EXPORTING

      exit_name

                     = c_exit_name

    IMPORTING

      act_imp_existing

            

 = act_imp_existing

    CHANGING

      instance

                      = pbas0001_badi_instance

    EXCEPTIONS

      no_reference

                  = 1

      no_interface_reference

        = 2

      no_exit_interface

             = 3

      class_not_implement_interface

= 4

      single_exit_multiply_active

   = 5

      cast_error

                    = 6

      exit_not_existing

             = 7

      data_incons_in_exit_managem

   = 8

      OTHERS

                        = 9.

  IF

sy-subrc <> 0.

    MESSAGE

ID

sy-msgid

TYPE

sy-msgty

NUMBER

sy-msgno

               WITH

sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

  ENDIF

.

ENDIF

.

IF

NOT

act_imp_existing IS

INITIAL

.

  CALL

METHOD

pbas0001_badi_instance->

get_default_values

    EXPORTING

      tclas

   = tclas

      ipsyst

  = ipsyst

      i001p

   = i001p

      i503

    = i503

      flt_val =

innnn-infty

    CHANGING

      innnn

  = innnn

      ipref

  = ipref.

ENDIF

.

Implementation

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

automatically.

Strange

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.

I intend

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.

Finally,

after entering appropriate code into a method implementation we can activate

implementation and begin testing and debugging.

!https://weblogs.sdn.sap.com/weblogs/images/3886/Image7_resize.gif|height=400|alt=image|width=533|src...!</body>

8 Comments