Skip to Content

Hi All,

This blog is all about to write BDC program with OOPs in ABAP. In one of my projects I got a requirement that while we creating a PO with respect to a quotation, the unused quotations of same RFQ should be marked as Rejected. To Implement this I found a BADI, unfortunately we don’t have BAPI’s to update quotations so we should opt BDC to update Quotations. usually BDC programs will be written by using two subroutines to fill BDCDATA internal table, one is for screen information and other one is for field name and value, the problem is that BADI class methods won’t allow perform and from statements, so we should write the same code in OOABAP.

So, what I did here is that simply I have converted those two subroutines into two methods in a class. Initially I created a Z_class in that I have create required attributes and methods. Please follow below steps you can understand.

Class Attributes

/wp-content/uploads/2013/10/1_291709.jpg

  Class Methods

/wp-content/uploads/2013/10/2_291818.jpg

Class Methods Implementation

method BDC_DYNPRO.
wa_bdcdataprogram = program. ” Program name
wa_bdcdatadynpro = dynpro. ” Screen Number
wa_bdcdatadynbegin = ‘X’. ” X
*** Append bdc table and clear work area
APPEND wa_bdcdata TO it_bdcdata.
CLEAR wa_bdcdata.
endmethod.

method BDC_FIELDVALUE.
wa_bdcdatafnam = fnam. ” Field Name
wa_bdcdatafval = fval. ” Field Value
  APPEND wa_bdcdata TO it_bdcdata.
CLEAR wa_bdcdata.
endmethod.

Now I simply used this class in my BADI Class Method  and solve the problem .

Here it is a sample code for BDC into OOABAP to update quotations Tcode ME47.

DATA: ob_bdc TYPE REF TO zcl_bdc_bps.

  CREATE OBJECT ob_bdc.

TYPES: BEGIN OF t_ekko,

         ebeln TYPE ekpo-ebeln,

         END OF t_ekko,

         BEGIN OF t_ekpo,

         ebeln TYPE ekpo-ebeln,

         ebelp TYPE ekpo-ebelp,

         END OF t_ekpo.

data: it_ekko     TYPE TABLE OF t_ekko,

        it_ekpo TYPE TABLE OF t_ekpo,

it_message  TYPE TABLE OF t_message,

it_bdcdata TYPE STANDARD TABLE OF bdcdata INITIAL SIZE 0,

it_bdc_messages TYPE STANDARD TABLE OF bdcmsgcoll INITIAL SIZE 0,

wa_message  TYPE t_message,

        wa_ekpo1 TYPE t_ekpo,

        wa_ekko TYPE  t_ekko,

        wa_ekpo TYPE ekpo,

        w_anfnr TYPE ekpo-anfnr,

        w_submi TYPE ekko-submi,

w_mode(1)   TYPE c VALUE ‘E’,

w_update(1) TYPE c VALUE ‘S’.

CLEAR wa_ekpo.

      READ TABLE im_ekpo into wa_ekpo  index 1.

      IF sy-subrc EQ 0.

        CLEAR w_submi.

        SELECT SINGLE submi INTO w_submi FROM ekko WHERE  ebeln  = wa_ekpo-anfnr.

        IF sy-subrc EQ 0.

          SELECT ebeln  FROM ekko INTO TABLE it_ekko WHERE submi = w_submi.

          IF sy-subrc EQ 0.

SELECT ebeln ebelp  FROM ekpo INTO TABLE it_ekpo

FOR ALL ENTRIES IN it_ekko

WHERE ebeln = it_ekko-ebeln.

delete it_ekko where ebeln = wa_ekpo-anfnr.

delete it_ekpo where ebeln = wa_ekpo-anfnr.

LOOP AT it_ekko INTO wa_ekko.

CLEAR:ob_bdc->it_bdcdata[].

*Populate BDC data to Maintain Quotation in ME47

CALL METHOD ob_bdc->bdc_dynpro

EXPORTING

program  = ‘SAPMM06E’

dynpro   = ‘0305’

dynbegin = ‘X’.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘BDC_CURSOR’

fval = ‘RM06E-ANFNR’.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘BDC_OKCODE’

fval = ‘/00’.

w_ebelp = wa_ekko-ebeln.

CONDENSE w_ebelp.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘RM06E-ANFNR’

fval = w_ebelp.

CLEAR:w_ebelp.

LOOP AT it_ekpo INTO wa_ekpo1 WHERE ebeln EQ wa_ekko-ebeln.

CALL METHOD ob_bdc->bdc_dynpro

EXPORTING

program  = ‘SAPMM06E’

dynpro   = ‘0323’

dynbegin = ‘X’.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘BDC_CURSOR’

fval = ‘RM06E-EBELP’.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘BDC_OKCODE’

fval = ‘/00’.

w_ebelp = w_ebelp + 10.

CONDENSE w_ebelp.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘RM06E-EBELP’

fval = w_ebelp.

CALL METHOD ob_bdc->bdc_dynpro

EXPORTING

program  = ‘SAPMM06E’

dynpro   = ‘0323’

dynbegin = ‘X’.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘BDC_CURSOR’

fval = ‘EKPO-EMATN’.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘BDC_OKCODE’

fval = ‘=DETA’.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘RM06E-EBELP’

fval = w_ebelp.

CALL METHOD ob_bdc->bdc_dynpro

EXPORTING

program  = ‘SAPMM06E’

dynpro   = ‘0311’

dynbegin = ‘X’.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘BDC_CURSOR’

fval = ‘RM06E-ANMNG’.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘EKPO-ABSKZ’

fval = ‘X’.

ENDLOOP.

CALL METHOD ob_bdc->bdc_fieldvalue

EXPORTING

fnam = ‘BDC_OKCODE’

fval = ‘=BU’.

refresh it_bdcdata.

it_bdcdata = ob_bdc->it_bdcdata.

CALL TRANSACTION c_me47 USING    it_bdcdata

MODE     w_mode

UPDATE   w_update

MESSAGES INTO it_bdc_messages.

endloop.

To report this post you need to login first.

44 Comments

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

  1. Matthew Billingham

    Well, it’s nice to see an attempt at object orientation, so kudos for that. You’ve used FOR ALL ENTRIES rather than INNER JOIN, which isn’t good. In the vast majority of cases, INNER JOIN is more efficient that FOR ALL ENTRIES. You don’t need to have the data in separate internal tables.

    It’s better to use the functional form when calling methods.

    So: od_bdc->bdc_dynpro ( program = ‘SAPMM06E’ dynpro = ‘0323’ dynbegin = ‘X’ ) or od_bdc->bdc_fieldvalue( fnam = ‘BDC_CURSOR’ fval = ‘RM06E-EBELP’ ).

    Also, although the practice has been to use bdc_dynpro perhaps a more meaningful method name could be used?

    (0) 
  2. Tolga POLAT

    Hi,

    Actually you can declare this class local in report instead of se24. and you can sent multiple exporting parameters with using ‘:’ .

    Here is the example :

    CLASS lcl_bdc DEFINITION.

       PUBLIC SECTION.

         METHODS : set_bdc_data

                    IMPORTING

                      i_pname TYPE bdc_prog OPTIONAL

                      i_dynnr TYPE bdc_dynr OPTIONAL

                      i_field TYPE fnam_____4 OPTIONAL

                      i_value TYPE bdc_fval OPTIONAL.

       PROTECTED SECTION.

         DATA : lt_bdcdata TYPE STANDARD TABLE OF bdcdata WITH DEFAULT KEY.

    ENDCLASS.                    “lcl_bdc DEFINITION

    *———————————————————————-*

    *       CLASS lcl_bdc IMPLEMENTATION

    *———————————————————————-*

    *

    *———————————————————————-*

    CLASS lcl_bdc IMPLEMENTATION.

       METHOD set_bdc_data.

         DATA : ls_bdcdata TYPE bdcdata.

         IF i_pname NE space.

           ls_bdcdataprogram  = i_pname. ” Program name

           ls_bdcdatadynpro   = i_dynnr. ” Screen Number

           ls_bdcdatadynbegin = ‘X’. ” X

         ELSE.

           ls_bdcdatafnam = i_field. ” Field Name

           ls_bdcdatafval = i_value. ” Field Value

         ENDIF.

         APPEND ls_bdcdata

             TO lt_bdcdata.

       ENDMETHOD.                    “set_bdc_data

    ENDCLASS.                    “lcl_bdc IMPLEMENTATION

    DATA : lo_bdc TYPE REF TO lcl_bdc.

    START-OF-SELECTION.

       CREATE OBJECT lo_bdc.

       CALL METHOD lo_bdc->set_bdc_data :

         EXPORTING

           i_pname = ‘SAPMM06E’

           i_dynnr = ‘0305’,

         EXPORTING

           i_field = ‘BDC_OKCODE’

           i_value = ‘/00’.

    (0) 
        1. Matthew Billingham

          Start as you mean to go on, I say.

          SE24 isn’t exactly difficult to get to grips with. I started with global classes – it was quite a while before I did any local classes, since they are more complicated. I’d contend that it’s easier to use SE24 for newbies.

          Local class facilitates developing the same thing again and again and again…. πŸ˜‰

          (0) 
          1. Tolga POLAT

            Hi,

            I think for very basic use there no need to create global object ( data, structure etc. ).

            For this example, will you inherit other class from this? do you need to overwrite any method? This is simply changing perform to method.

            This is my thought about diffirence between global and local declaration.

            Also i wanted to give a example about writing code shorter, and usage of multi parameters with ‘:’ .

            (0) 
            1. Matthew Billingham

              A class to do BDC will be re-used. So you do it as a global class, where you will find classes that are re-usable. Whether it is subclass-able or not is irrelevant.  In Java I write classes that will probably never be subclassed.

              I don’t see why even the most basic class shouldn’t be global. It’s not as though database space is at a premium. Global classes are easier and less work to create than local ones.

              Methods are better than forms. Some kind of typing is enforced, and you have to name parameters.

              I understand the use of :, but if you rewrite as a functional method, then you get shorter clearer code anyway.

              (0) 
              1. solen dogan

                I think having a BDC object is good!!

                what will be better is to extend its functioanality

                For example: Make it a singleton object

                You wouldnt want to have another BDC object doing other things behind.

                or you can gave a BDC factory etc..

                Where to start will be to have an interface between them..

                Δ°f you make this a global class it should worth it:)

                (0) 
    1. CD Raju Post author

      Tolga,

      I hope you would have understood why I created a Global Class for this purpose with Matthew’s and Manish’s good explanation. And addition their explanation, let me give you one more reason  to create Global Class is that the above code is built in a BADI method and in method we can’t define a class.

      (0) 
      1. JΓΆrg Wulf

        Hi Radju,

        very nice aproach, but why stop at half the distance?

        I had to build something quite similar and used standard class CL_CACS_BDC_CNTRL for the basic functionality. I found to my regret, that this class is final, otherwise i’d have jus inherited the methods. As it is, i use said class as an instance attribute and have added the rest in my class around it. OPEN_GROUP, CLOSE_GROUP and ADD_TRANSACTION complete the set.

        By leaving OPEN_GROUP private and calling it from within, on first use of ADD_TRANSACTION i make sure, that no empty groups are created.

        So, each instance of my class represents a bdc-group.

        @Tolga Polat

        for shorter code, especially when providing bdc data, i recommend the below document on advanced use of macros.

        http://scn.sap.com/community/abap/blog/2012/10/28/use-macros-use-them-wisely

        In my code this reads like this:

        add_bdc_field  'BKPF-BUDAT' lv_hdat.

        add_bdc_field  'BKPF-MONAT' lv_monat.

        ...

        Best regards – Jörg

        (0) 
        1. solen dogan

          Thats a good idea Jörg:)

          I agree with you

          You could inherit and extend its functinality why leave it there

          Macros are powerfulç good link

          (0) 
        2. Tolga POLAT

          Hi Jörg,

          I’m using macro too, looks like SM35 record result and we can define macro in method too

          add_bdcdata_to_table : ‘SAPMM06E’  ‘0305’ ” ”,

                                                          ”  ”  ‘BDC_OKCODE’ ‘/00’.

          I dont know CL_CACS_BDC_CNTRL, I will look.

          (0) 
        3. Matthew Billingham

          Your approach to CL_CACS_BDC_CNTRL is a nice example of the power of composition. I’ve had to use it in the same circumstance – when for no really good reason, SAP have marked a class as final.

          Thanks for pointing out the blog. Interesting reading, though I think in major development centres Rainer’s approach of banning macros is eminently sensible. They’re too easy to misuse and cause problems. I find that OO programming, with functional method calls, usually is sufficient to meet the criteria of:

          • They help to make code more readable.
          • They help hide implementation details from the code’s main intentions.
          • They help avoid code repetition.
          (0) 

Leave a Reply