Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Call dynamically different BAdIs

BjörnKorioth
Employee
Employee
0 Kudos

Hi I am trying to call diefferent BAdIs dynamically.

Scenario:

I am looping through my lt_idoc_data and depending on the value in there I have to call a different BAdI that is saved in the table lt_bdi.

I think that with the interface if_badi_interface I can create dynamically the object needed., but I have no idea how to then dynamically call the different functions?

Could you please help me out?

Greetings Björn

DATA:
      ls_header    TYPE /sapcdp/iafwcsbth,
      ls_item      TYPE LINE OF /sapcdp/iafwttbti,
      lt_item      TYPE /sapcdp/iafwttbti,
      ls_condition TYPE LINE OF /sapcdp/iafwttbtc,
      lt_condition TYPE /sapcdp/iafwttbtc,
      ls_reference TYPE LINE OF /sapcdp/iafwttbtr,
      lt_reference TYPE /sapcdp/iafwttbtr,
      lt_bdi       TYPE /sapcdp/iafwttbdi,
      ls_bdi       TYPE LINE OF /sapcdp/iafwttbdi,
      lt_lvl       TYPE /sapcdp/iafwttlvl,
      ls_lvl       TYPE LINE OF /sapcdp/iafwttlvl,
      ls_idoc_data TYPE edidd,
      lt_idoc_data TYPE edidd_tt,
      lo_badi      TYPE REF TO if_badi_interface.

* get Enrichmentfunction per level and corresponding BAdIs in itab
    SELECT enrichment_function badi FROM /sapcdp/iafwtc15 INTO TABLE lt_bdi.
    SELECT enrichment_function tabname FROM /sapcdp/iafwtc16 INTO TABLE lt_lvl.

    MOVE-CORRESPONDING it_idoc_data TO lt_idoc_data.
    SORT lt_idoc_data BY docnum segnum.

* Loop through idoc_data
    LOOP AT lt_idoc_data INTO ls_idoc_data.
* Loop at lvl
      LOOP AT lt_lvl INTO ls_lvl WHERE tabname EQ ls_idoc_data-segnam.
* Loop at badi
        LOOP AT lt_bdi INTO ls_bdi WHERE enrichmentfunction EQ ls_lvl-enrichmentfunction.


          CREATE OBJECT lo_badi TYPE (ls_bdi-badi).
* Call BAdI


        ENDLOOP.
      ENDLOOP.
    ENDLOOP.
1 ACCEPTED SOLUTION

Former Member

Hello Björn,

I would suggest that you will use the BAdI Framework and not creating the objects manually.

You can create a filter dependent BAdI, where one filter argument is the segmant name of the idoc and the other filter argument is enrichment function. Than you can create a BAdI implementation for each combination. If you have multiple implementations for each combination, you have to switch on the flag multiple use. With this you can have several active implementations at the same time.

I would also switch on the flag reusing instantiation, as it will reuse an already created instance. Instance creation is quite expensive in ABAP. In your case, every time a new object instance will be created and I think it is not really necessary in your case.

You can simply get the BAdI instance like for example:

try.
   get badi idoc_processor
     filters segment_name = idoc_data-segnam
              enrichment_function = enrichmentfunction.

* If you have multiple active implementations, you can get them from 
* idoc_processor->imps.

   catch cx_badi_not_implemented.
endtry.

Some additional comments.

(1) I think it is not necessary to prefix your data with ls_ or lt_. They all are local anyway and which kind of data it is, can easily be identified by the context of the data. Within the official programming guidelines, I think there is some good recommandation for naming conventions.

http://help-legacy.sap.com/abapdocu_751/en/index.htm?file=abenprog_intern_names_guidl.htm

(2) You may want to consider to create a factory class for the BAdI creation. This has the advantage that if some day you want to write unit tests for your developments, you can can create some mock implementation for your factory and your BAdI respectively.

(3) I always create a BAdI abstract class in addition to the BadI interface. This can be used for common methods/attributes etc...it's a real life safer... The concrete BAdI implementation than inherits from the abstract class.

Sample coding:

This sample coding will not activate, but I think it will give you an idea.

Best regards, Tapio

1 REPLY 1

Former Member

Hello Björn,

I would suggest that you will use the BAdI Framework and not creating the objects manually.

You can create a filter dependent BAdI, where one filter argument is the segmant name of the idoc and the other filter argument is enrichment function. Than you can create a BAdI implementation for each combination. If you have multiple implementations for each combination, you have to switch on the flag multiple use. With this you can have several active implementations at the same time.

I would also switch on the flag reusing instantiation, as it will reuse an already created instance. Instance creation is quite expensive in ABAP. In your case, every time a new object instance will be created and I think it is not really necessary in your case.

You can simply get the BAdI instance like for example:

try.
   get badi idoc_processor
     filters segment_name = idoc_data-segnam
              enrichment_function = enrichmentfunction.

* If you have multiple active implementations, you can get them from 
* idoc_processor->imps.

   catch cx_badi_not_implemented.
endtry.

Some additional comments.

(1) I think it is not necessary to prefix your data with ls_ or lt_. They all are local anyway and which kind of data it is, can easily be identified by the context of the data. Within the official programming guidelines, I think there is some good recommandation for naming conventions.

http://help-legacy.sap.com/abapdocu_751/en/index.htm?file=abenprog_intern_names_guidl.htm

(2) You may want to consider to create a factory class for the BAdI creation. This has the advantage that if some day you want to write unit tests for your developments, you can can create some mock implementation for your factory and your BAdI respectively.

(3) I always create a BAdI abstract class in addition to the BadI interface. This can be used for common methods/attributes etc...it's a real life safer... The concrete BAdI implementation than inherits from the abstract class.

Sample coding:

This sample coding will not activate, but I think it will give you an idea.

Best regards, Tapio