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.
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.
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( i_bdc_type = 'CT'
i_tcode = 'VD05' ).
ELSEIF p_sess = 'X'.
g_bdc = zcl_bc_bdc=>s_instantiate( i_bdc_type = 'BI'
i_tcode = 'VD05'
i_group = 'MY_SESSION'
i_keep = 'X'
i_holddate = '20140528' ).
ENDIF.
* Populate first screen
g_bdc->add_screen( i_repid = 'SAPMF02D' i_dynnr = '0507').
g_bdc->add_field( i_fld = 'BDC_OKCODE' i_val = '/00').
g_bdc->add_field( i_fld = 'RF02D-KUNNR' i_val = p_kunnr ).
g_bdc->add_field( i_fld = 'RF02D-VKORG' i_val = p_vkorg ).
g_bdc->add_field( i_fld = 'RF02D-VTWEG' i_val = p_vtweg ).
g_bdc->add_field( i_fld = 'RF02D-SPART' i_val = p_spart ).
* Populate second screen
g_bdc->add_screen( i_repid = 'SAPMF02D' i_dynnr = '0510').
g_bdc->add_field( i_fld = 'BDC_OKCODE' i_val = '=UPDA').
g_bdc->add_field( i_fld = 'KNA1-LIFSD' i_val = p_delblk ).
g_bdc->add_field( i_fld = 'KNA1-FAKSD' i_val = p_bilblk ).
*----------------------------------------------------------------------*
* End of Selection
*----------------------------------------------------------------------*
END-OF-SELECTION.
IF p_tran = 'X'.
g_bdc->process( IMPORTING e_subrc = g_subrc
e_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.