Skip to Content
Technical Articles
Author's profile photo Eng Swee Yeoh

Objectify: ABAP Objects Model for BDC

Update 6 May 2014: Updated method parameters following Objectify’s naming convention. Updated Github repository link to Project Objectify

This is my first contribution to Project Objectify which is being “revived” by Bruno Esperança.

This an Object-Oriented approach for BDC processing. I’m aware that there is already a model published here but this is my own attempt at the design which includes the functionality to process the BDC via Call Transaction or Batch Input Session.

I develop in ABAP Objects wherever I can, so this is one of the classes where I bring along to every new project I start on as it is highly reusable. I am aware of the never-ending debate between developing ABAP in OO vs. procedural in SCN, but I will not get into that here. Please feel free to reuse this model and/or leave any comments if it can be improved any further.

Source Code

The corresponding objects and code for this article can be found in the following public repository on Github.

GitHub repository for BDC Model

Class Design

The design of the class is based on the Singleton pattern whereby there can be only 1 active instance of the class in a single session.

Methods

The screenshot below displays the methods available in the class.

/wp-content/uploads/2014/05/methods_444773.png

Methods Explanation

 

1) Instantiation

Instantiation of the class is via static method S_INSTANTIATE, whereby the type of processing (CT = Call Transaction, BI = Batch Input) and related T-Code are mandatory inputs.

Additionally, other parameters are available for finer control of the BDC processing. All the input values are stored into the instance’s private attributes.

/wp-content/uploads/2014/05/instant_446496.png

2) Construct BDC table

Once the class is instantiated, instance methods ADD_FIELD and ADD_SCREEN are used to construct the BDC table.

3) BDC Processing

After the BDC table has been fully populated, instance method PROCESS is used to process that data. Depending on the processing type (CT/BI), private methods CALL_TRANSACTION or CREATE_BATCH_INPUT_SESS will be executed.

4) Reset BDC table

If there is a need to execute the same BDC T-Code multiple times (i.e. in a loop), instance method CLEAR_BDC_DATA can be used to clear the BDC table so that it can be reconstructed again.

5) Garbage collection

Finally, if the BDC instance is no longer required during an internal session, static method S_FREE_INSTANCE can be used to free the instance of the singleton, which then allows the memory to be freed during the next run of the garbage collector.

Usage Example

Below is an example of a simple report program to illustrate the usage of the class. It shows both processing by Call Transaction and Batch Input Session.

*&———————————————————————*

*& Report  ZESY_CALL_OO_BDC

*&

*&———————————————————————*

REPORT  zesy_call_oo_bdc.

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

*  Selection Screen

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

PARAMETER:

  p_kunnr  TYPE kna1-kunnr DEFAULT ‘2400’,

  p_vkorg  TYPE knvv-vkorg DEFAULT ‘1000’,

  p_vtweg  TYPE knvv-vtweg DEFAULT ’10’,

  p_spart  TYPE knvv-spart DEFAULT ’00’.

SELECTION-SCREEN SKIP 1.

PARAMETER:

  p_delblk TYPE kna1-lifsd DEFAULT ’01’,

  p_bilblk TYPE kna1-faksd DEFAULT ’01’.

SELECTION-SCREEN SKIP 1.

PARAMETER:

  p_tran RADIOBUTTON GROUP r1 DEFAULT ‘X’,

  p_sess RADIOBUTTON GROUP r1.

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

*  Data Declarations

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

DATA:

  g_bdc       TYPE REF TO zcl_bc_bdc,

  g_messages  TYPE tab_bdcmsgcoll,

  g_message   LIKE LINE OF g_messages,

  g_subrc     TYPE sy-subrc,

  g_exception TYPE REF TO zcx_batch_input_error,

  g_error     TYPE string.

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

*  Initialization

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

*INITIALIZATION.

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

*  Start of Selection

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

START-OF-SELECTION.

* Create an object for BDC

  IF p_tran = ‘X’.

    g_bdc = zcl_bc_bdc=>s_instantiate( im_bdc_type = ‘CT’

                                       im_tcode    = ‘VD05’ ).

  ELSEIF p_sess = ‘X’.

    g_bdc = zcl_bc_bdc=>s_instantiate( im_bdc_type = ‘BI’

                                       im_tcode    = ‘VD05’

                                       im_group    = ‘MY_SESSION’

                                       im_keep     = ‘X’

                                       im_holddate = ‘20140528’ ).

  ENDIF.

* Populate first screen

  g_bdc->add_screen( im_repid = ‘SAPMF02D’ im_dynnr = ‘0507’).

  g_bdc->add_field( im_fld = ‘BDC_OKCODE’  im_val = ‘/00’).

  g_bdc->add_field( im_fld = ‘RF02D-KUNNR’ im_val = p_kunnr ).

  g_bdc->add_field( im_fld = ‘RF02D-VKORG’ im_val = p_vkorg ).

  g_bdc->add_field( im_fld = ‘RF02D-VTWEG’ im_val = p_vtweg ).

  g_bdc->add_field( im_fld = ‘RF02D-SPART’ im_val = p_spart ).

* Populate second screen

  g_bdc->add_screen( im_repid = ‘SAPMF02D’ im_dynnr = ‘0510’).

  g_bdc->add_field( im_fld = ‘BDC_OKCODE’ im_val = ‘=UPDA’).

  g_bdc->add_field( im_fld = ‘KNA1-LIFSD’ im_val = p_delblk ).

  g_bdc->add_field( im_fld = ‘KNA1-FAKSD’ im_val = p_bilblk ).

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

*  End of Selection

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

END-OF-SELECTION.

  IF p_tran = ‘X’.

    g_bdc->process( IMPORTING ex_subrc    = g_subrc

                              ex_messages = g_messages ).

*   Display processing status

    IF g_subrc = 0.

      WRITE:/ ‘Success:’.

    ELSE.

      WRITE:/ ‘Error:’.

*     Display messages in list

      LOOP AT g_messages INTO g_message.

        MESSAGE ID g_message-msgid

                TYPE g_message-msgtyp

                NUMBER g_message-msgnr

                WITH g_message-msgv1

                     g_message-msgv2

                     g_message-msgv3

                     g_message-msgv4

                INTO g_error.

        WRITE:/ g_error.

      ENDLOOP.

    ENDIF.

  ELSEIF p_sess = ‘X’.

    TRY.

        g_bdc->process( ).

        WRITE: ‘Success: Check session in SM35’.

      CATCH zcx_batch_input_error INTO g_exception.

        WRITE:/ ‘Error creating batch input session:’.

        MESSAGE ID g_exception->msgid

                TYPE ‘E’

                NUMBER g_exception->msgno

                WITH g_exception->msgv1

                     g_exception->msgv2

                     g_exception->msgv3

                     g_exception->msgv4

                INTO g_error.

        WRITE:/ g_error.

    ENDTRY.

  ENDIF.

Assigned Tags

      21 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hello,

      First-of-all, kudos for your submission to project Objectify 🙂

      Would it not have been flexible to have a FACTORY method & return the instance based on whether the developer wanted to use BDC/Call Transaction?

      The method PROCESS( ) had to be in the BDC & Call Transaction classes accordingly. I think that would make the solution more flexible to use.

      What is your opinion?

      BR,

      Suhas

      PS - Sorry for being critical, ol' habits die hard 😛

      Author's profile photo Eng Swee Yeoh
      Eng Swee Yeoh
      Blog Post Author

      Hi Suhas

      Thanks for your feedback - don't worry, constructive criticisms are always welcome, it is these that help oneself grow 🙂

      When I modelled this in the past, my idea was to have a simple class that is able to handle both Call Transaction and Batch Input, hence it was all in one class. The PROCESS( ) method can then be invoked independent of whether it was CT or BI.

      I'm interested to understand how having having a factory method and separate classes would make it more flexible. Can you elaborate with maybe a use-case?

      Thanks!

      Eng Swee

      Author's profile photo Former Member
      Former Member

      Hello Eng Swee,

      This is what i meant -

      1. CLASS lcl_data_upload DEFINITION ABSTRACT.
      2.       
      3.   PUBLIC SECTION.
      4.     CLASS-METHODS:
      5.     factory
      6.         IMPORTING
      7.             im_process_type TYPE char1
      8.         RETURNING VALUE(re_instance) TYPE REF TO lcl_data_upload.
      9.     METHODS:
      10.     process ABSTRACT. "To be implemented in the relevant subclasses
      11. ENDCLASS.
      12. CLASS lcl_bdc DEFINITION INHERITING FROM lcl_data_upload.
      13.       
      14.   PUBLIC SECTION.
      15.     METHODS process REDEFINITION.
      16. ENDCLASS.
      17. CLASS lcl_call_trans DEFINITION INHERITING FROM lcl_data_upload.
      18.   PUBLIC SECTION.
      19.     METHODS process REDEFINITION.
      20. ENDCLASS.
      21. CLASS lcl_data_upload IMPLEMENTATION.
      22.   METHOD factory.
      23.     CASE im_process_type.
      24.       WHEN 'B'. "BDC session
      25.         CREATE OBJECT re_instance TYPE lcl_bdc.
      26.       WHEN 'C'. "Call transaction
      27.         CREATE OBJECT re_instance TYPE lcl_call_trans.
      28.     ENDCASE.
      29.   ENDMETHOD.
      30. ENDCLASS.
      31. CLASS lcl_bdc IMPLEMENTATION.
      32.   METHOD process.
      33.     MESSAGE 'I will process BDC session' TYPE 'I'.
      34.   ENDMETHOD.
      35. ENDCLASS.
      36. CLASS lcl_call_trans IMPLEMENTATION.
      37.   METHOD process.
      38.     MESSAGE 'I will process Call Transaction' TYPE 'I'.
      39.   ENDMETHOD.
      40. ENDCLASS.
      41. PARAMETERS:
      42. rb_ctran    RADIOBUTTON GROUP gr1,
      43. rb_bdc      RADIOBUTTON GROUP gr1.
      44. START-OF-SELECTION.
      45.   IF rb_ctran = abap_true.
      46.     DATA(process_type) = 'C'. "(C)all transaction
      47.   ELSE.
      48.     process_type = 'B'. "(B)DC session
      49.   ENDIF.
      50. * Get the data upload processing object
      51.   DATA(oref_data_process) = lcl_data_upload=>factory( process_type ).
      52. * Upload the data
      53.   oref_data_process->process( ).

      Just an idea. Not sure if it can be applied to this specific use case.

      BR,

      Suhas

      Author's profile photo Eng Swee Yeoh
      Eng Swee Yeoh
      Blog Post Author

      Hi Suhas

      Thanks for the info. I think I get you now - I think you are suggesting modelling it with the Strategy Pattern, which is also similar to the IDoc framework model that I posted previously, right?

      I agree with you that the strategy pattern is definitely more flexible especially for extending the behaviours of the class in the future. However, for this specific case, I can't foresee there being more than the 2 behaviours (Call transaction and Batch Input.)

      Anyway, it is definitely a point to ponder! When I get some time in my hands, I might redesign this to make it a more robust model 🙂

      Rgds

      Eng Swee

      Author's profile photo Former Member
      Former Member

      Strategy pattern it is, indeed! I should have mentioned it, my bad 😳

      I see how design patterns help developers think on identical terms.

      Cheers,

      Suhas

      Author's profile photo Bruno Esperança
      Bruno Esperança

      Fantastic 🙂

      I wonder if it's possible to "fork" this and add this class in a folder in the project object github 😕

      Or, alternatively, if you would contemplate being a contributor to project object and adding it there directly!

      Thanks 🙂

      Best,

      Bruno

      Author's profile photo Bruno Esperança
      Bruno Esperança

      Also, as I have discussed with Florian Henninger, would be great if contributions to the project followed *at least* the naming conventions mentioned here:

      Naming Conventions in ABAP Objects -  ABAP Workbench Tools - SAP Library

      Just to try and make it something as consistent as possible. I'm not asking you to change what you've done already, but maybe in the future you could think about it ^_^

      Thanks!!

      Best,

      Bruno

      Author's profile photo Eng Swee Yeoh
      Eng Swee Yeoh
      Blog Post Author

      Hi Bruno

      Can you add me as a contributor to your existing Project Object repository? I will then move the codes there. I'm not that familiar of how the fork function works in Github yet...

      Thanks for the naming convention link.

      For method parameters, this other Help SAP document suggests the following instead of IM, EX, CH, RE. Any thoughts on which one to stick to?

      ABAP Keyword Documentation

      • i_ for IMPORTING parameters
      • e_ for EXPORTING parameters
      • c_ for CHANGING parameters
      • r_ for RETURNING parameters

      Rgds

      Eng Swee

      Author's profile photo Bruno Esperança
      Bruno Esperança

      Hi again!

      I have now added you as a contributor 🙂 You should have full access, let me know if you haven't. I'm not sure how this works either! Hopefully someday we will understand better how github works 🙂 I'm guessing I have to block some time to look into it properly.

      Regarding the naming convention on parameters, I was using the one you shared. Then I found out the one I shared above. Apparently one is for OO and the other is for reports. So I think it makes more sense if we use the one for OO, with IM, EX, etc.

      (If you look at the classes in the repository at the moment they have the same naming convention you used... but in the future I'll be using the IM, EX naming convention, if "everyone" in the project agrees!

      Thanks!!

      Best,

      Bruno

      Author's profile photo Eng Swee Yeoh
      Eng Swee Yeoh
      Blog Post Author

      Hi Bruno

      Thanks for sorting out the Github access. I have now moved the codes over.

      I'm fine with the IM, EX convention, so I've also updated the codes with that too, it was just a quick tweak.

      Thanks again!

      Eng Swee

      Author's profile photo Bruno Esperança
      Bruno Esperança

      Great!

      Welcome to the team 🙂

      I guess I'll change the "signature" in the readme file to "The Project Object Team" 😛

      Best regards,

      Bruno

      Author's profile photo Former Member
      Former Member

      can you show me the source code of  ZCX_BATCH_INPUT_ERROR,ths

      Author's profile photo Eng Swee Yeoh
      Eng Swee Yeoh
      Blog Post Author

      Hi Weiqiong,

      That is an exception class with attributes MSGID, MSGNO, MSGV1-4. There is no other source code for it as it is auto generated by the system when the class is created.

      Rgds

      Eng Swee

      Author's profile photo Former Member
      Former Member

      i get it ,thank you!

      Author's profile photo Guido Schöpp
      Guido Schöpp

      Hi Eng Swee,

      I extracted the ZCX_BATCH_INPUT_ERROR class from the NUGG_BDC_MODEL.nugg file.

      It would be nice if you would include the ZCX_BATCH_INPUT_ERROR as .txt file (in the objectify project, too).

      Regards
      Guido

      Author's profile photo Kim Ternstrøm
      Kim Ternstrøm

      In the method called add_field you have a rutine to handle the date conversion from internal to external.

      You should also have a routine that can handle the same for an amount/quantity field depending on how the user is configured with decimal point ( . or , ) and at the same time left justify the field to aviod the error "A screen field was supplied with longer field contents by batch input."

      Author's profile photo Bruno Esperança
      Bruno Esperança

      Hi,

      FM MOVE_CHAR_TO_NUM can be used for this.

      Kim, maybe you could work on it? 🙂

      Cheers,

      Bruno

      Author's profile photo Eng Swee Yeoh
      Eng Swee Yeoh
      Blog Post Author

      Thanks for the feedback Kim.

      Unfortunately in my current project, I am not involved in ABAP developments so I won't be getting around to enhancing that for a while.

      As suggested by Bruno, in the spirit of the community and Project Objectify, maybe you can help to enhance it?

      Rgds

      Eng Swee

      Author's profile photo Former Member
      Former Member

      Hi. Good job. But I had little to add support to convert defsize. 🙂

      Author's profile photo Frank Zaiser
      Frank Zaiser

      Hi i tried this code but it isnt working for me.

      I get the error:

      But i copied the whole code. And i created the second exception class with following attributes.

       

      Author's profile photo Carlos Garcia
      Carlos Garcia

      Hello, I need to use this approach, but for a lot of register in a batch input session, how can I do it ?, because the example is for one record. how can the program separate the transactions.

       

      Thanks in advance.