0% found this document useful (0 votes)
8 views6 pages

Using RFCs Not Just For Integration

The document discusses various techniques for using RFCs in SAP for integration and processing tasks, including opening transactions in new GUI windows, scheduling document creation after current LUW completion, and handling database updates with BAPI calls. It also covers parallel processing of resource-intensive calculations using class methods and functions to optimize performance. The document provides code examples and explanations for implementing these techniques effectively.

Uploaded by

aditya.rajak2024
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views6 pages

Using RFCs Not Just For Integration

The document discusses various techniques for using RFCs in SAP for integration and processing tasks, including opening transactions in new GUI windows, scheduling document creation after current LUW completion, and handling database updates with BAPI calls. It also covers parallel processing of resource-intensive calculations using class methods and functions to optimize performance. The document provides code examples and explanations for implementing these techniques effectively.

Uploaded by

aditya.rajak2024
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

/in/borodin-igor Using RFCs not only for integration

Opening some t-code in the separate SAP GUI window


Sometimes, you need to perform drilldown from source report into some t-code, but without leaving the source
screen. You able to use FM 'ABAP4_CALL_TRANSACTION' with STARTING NEW TASK instruction. As result, the new
GUI-window will be created and required transaction will be called there:
FORM call_iw32_in_new_window USING pv_aufnr TYPE aufk-aufnr.

DATA:
ls_spagpa TYPE rfc_spagpa,
lt_spagpa TYPE STANDARD TABLE OF rfc_spagpa,
l_act_sessions TYPE sm04dic-counter,
l_max_sessions TYPE sm04dic-counter.

" is there available sessions


CALL FUNCTION 'TH_USER_INFO'
IMPORTING
act_sessions = l_act_sessions
max_sessions = l_max_sessions.

IF l_act_sessions GE l_max_sessions.
MESSAGE i027(14).
RETURN.
ENDIF.

" prepare parameters


ls_spagpa-parid = 'ANR'.
ls_spagpa-parval = pv_aufnr.
APPEND ls_spagpa TO lt_spagpa.

" call t.code


CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'ZZZ' " -->> to open in new window
EXPORTING
tcode = 'IW32'
skip_screen = abap_on
TABLES
spagpa_tab = lt_spagpa
EXCEPTIONS
call_transaction_denied = 1
tcode_invalid = 2
OTHERS = 3.

MESSAGE 'New window is opening' TYPE 'S'.

ENDFORM.
/in/borodin-igor Using RFCs not only for integration

Calling some functionality strictly after the current LUW completion


Sometimes, you need that current document creation to trigger creation of another related document (where
related document should base on current document). Obviously related document creation should start strictly after
current document presents in database. Problem is you can't know when exactly update task of current document
creation will complete (due its asynchrony).

To handle it, staying inside the source LUW (using BADI or UE), you can use IN BACKGROUND TASK instruction to
schedule required function (in this case, BAPI for related document creation) start directly after the high-priority
update function modules execution.

Another example is when you need to scheduling the material stock revaluation process each time when prices
changes. Here we schedule it from Badi called while source document is saving, but revaluation process will start
after source document is already saved.
METHOD if_ex_invoice_update~change_at_save. " -->> BADI-impl. method

" 1) At this point the document (which sets new prices) is beginning to create,
" and we are INSIDE its LUW now
"
" 2) We need to schedule the start of Stock revaluation process
" immediately AFTER current UPDATE TASK will be finished
" (this requirement is because external stock revaluation process must consider current document)

CALL FUNCTION 'Z_MY_REVALUATION_PROCESS'


IN BACKGROUND TASK " -->> to schedule run immediately after current update task will be finished
EXPORTING
is_some_data = ls_some_data.

ENDMETHOD.

FUNCTION 'Z_MY_REVALUATION_PROCESS'.

CALL FUNCTION 'BAPI_MATVAL_PRICE_CHANGE'


...
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
...

ENDFUNCTION.
/in/borodin-igor Using RFCs not only for integration

DB Updates and BAPI calls isolated from the current LUW


It is known that in enhancements, BADI, User Exits it is forbidden to call explicit commit and rollbacks (implicit ones
are allowed). But, for various reasons, sometimes it is necessary. For example, it needs to save into the log
information about attempting of document posting (regardless of how this attempt ended). Or, at the moment of
saving the source document, it is necessary to receive information from an external system (calling an ABAP proxy
with a commit), and write the received information to the saved document. In this case, synchronous RFC will help
us.
METHOD if_ex_le_shp_delivery_proc~save_document_prepare. " -->> BADI-impl. method

...................
...................

CALL FUNCTION 'Z_MY_SEPARATE_LUW_WITH_COMMIT'


DESTINATION 'NONE' " -->> to update and commit there regardless of current luw
EXPORTING
is_some_data = ls_some_data.

ENDMETHOD.

FUNCTION 'Z_MY_SEPARATE_LUW_WITH_COMMIT'.

UPDATE z_journal FROM is_some_data.


COMMIT WORK.

CALL FUNCTION 'BAPI_GOODSMVT_CREATE'


....
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'

ENDFUNCTION.

Skip the global variables data buffered while previous function call
LOOP AT ....

CALL FUNCTION 'BAPI_GOODSMVT_CREATE'


DESTINATION 'NONE' " -->> to avoid using buffered data remained from previous call
EXPORTING
GOODSMVT_HEADER = ...
GOODSMVT_CODE = ...
TESTRUN = ...
IMPORTING
GOODSMVT_HEADRET = ...
MATERIALDOCUMENT = ...
MATDOCUMENTYEAR = ...
TABLES
GOODSMVT_ITEM = ...
GOODSMVT_SERIALNUMBER = ...
RETURN = LT_RETURN.

IF cl_rsdme_error=>has_error_static( LT_RETURN ) = abap_true.


CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK' DESTINATION 'NONE'.

ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' DESTINATION 'NONE'
EXPORTING
wait = abap_true.
ENDIF.

" necessary requirement to close connection after each usage


CALL FUNCTION 'RFC_CONNECTION_CLOSE'
EXPORTING
destination = 'NONE'.

ENDLOOP.
/in/borodin-igor Using RFCs not only for integration

Parallel processing of resource intensive calculations


Using in code

DATA(lt_key) = VALUE lcl_parallel=>ty_t_some_key(


( matnr = '0000123123124' werks = '0001' lgort = '0001' )
( matnr = '0000341245634' werks = '0002' lgort = '0002' )
( matnr = '0000003000011' werks = '0003' lgort = '0003' )
………
………
………
).

DATA(lt_result) = lcl_parallel=>run( lt_key ).

Class for parallelization of calculations


CLASS lcl_parallel DEFINITION.
PUBLIC SECTION.
TYPES:
ty_t_some_key TYPE STANDARD TABLE OF zs_key_structure WITH DEFAULT KEY,
ty_t_some_result TYPE STANDARD TABLE OF zs_result_structure WITH DEFAULT KEY.
CLASS-DATA:
mv_processed TYPE i,
mt_result TYPE ty_t_some_result.
CONSTANTS:
mc_group_name TYPE rzlli_apcl VALUE space.

CLASS-METHODS:
run
IMPORTING it_key TYPE ty_t_some_key
RETURNING VALUE(rt_result) TYPE ty_t_some_result,

end_processing_of_portion
IMPORTING p_task TYPE clike.

PRIVATE SECTION.
CLASS-METHODS:
start_processing_of_portion
IMPORTING iv_taskname TYPE i
it_key TYPE ty_t_some_key
CHANGING cv_successfully_started TYPE i,

get_available_workprocesses
RETURNING VALUE(rv_count) TYPE i.

ENDCLASS.

CLASS lcl_parallel IMPLEMENTATION.


METHOD run.
CLEAR:
mv_processed,
mt_result.

"====================================================================
" determine the number of available work processes
"====================================================================
DATA(lv_available_workprocesses) = get_available_workprocesses( ).

"====================================================================
" if there are not enough available work processes,
" we push to perform without parallelization
"====================================================================
IF lv_available_workprocesses <= 1.
CALL FUNCTION 'Z_VERY_SLOW_PROCESSING'
TABLES
it_key = it_key
et_result = rt_result.
RETURN.
ENDIF.
/in/borodin-igor Using RFCs not only for integration

"====================================================================
" if available work processes exists,
" we split keys table into portions, and push portions to parallel processing
"====================================================================
DATA(lv_lines) = lines( it_key ).
DATA(lv_portion_size) = lv_lines / lv_available_workprocesses.
DATA lv_successfully_started TYPE i.

DO lv_available_workprocesses TIMES.

" 1) prepare keys for current portion


" --- current portion number
DATA(lv_current_workprocess) = sy-index.

" --- calculate first and last line for current portion
DATA(lv_index_from) = lv_portion_size * ( lv_current_workprocess - 1 ) + 1.

IF lv_current_workprocess = lv_available_workprocesses.
DATA(lv_index_to) = lv_lines.

ELSE.
lv_index_to = lv_portion_size * lv_current_workprocess.
ENDIF.

" --- compose keys table for portion


DATA(lt_key_portion) = VALUE ty_t_some_result( ).

LOOP AT it_key ASSIGNING FIELD-SYMBOL(<ls_key>)


FROM lv_index_from
TO lv_index_to.

APPEND <ls_key> TO lt_key_portion.


ENDLOOP.

" 2) push the portion to parallel processing


start_processing_of_portion(
EXPORTING iv_taskname = lv_current_workprocess
it_key = lt_key_portion
CHANGING cv_successfully_started = lv_successfully_started ).
ENDDO.

" assembly point


WAIT UNTIL lv_successfully_started = mv_processed.

" return result


rt_result = mt_result.

ENDMETHOD.

METHOD start_processing_of_portion.

DATA lv_msg_txt TYPE c LENGTH 200.

CALL FUNCTION 'Z_VERY_SLOW_PROCESSING'


STARTING NEW TASK iv_taskname
DESTINATION IN GROUP mc_group_name
CALLING end_processing_of_portion " -->> callback method, after portion processing complete
ON END OF TASK
TABLES
it_key = it_key
EXCEPTIONS
resource_failure = 1
communication_failure = 2 MESSAGE lv_msg_txt
system_failure = 3 MESSAGE lv_msg_txt
OTHERS = 4.
IF sy-subrc = 0.
cv_successfully_started += 1.
ELSE.
" some error processing
ENDIF.

ENDMETHOD.
/in/borodin-igor Using RFCs not only for integration

METHOD end_processing_of_portion.

mv_processed += 1.

" receive portion result


DATA(lt_result_portion) = VALUE ty_t_some_result( ).

RECEIVE RESULTS FROM FUNCTION 'Z_VERY_SLOW_PROCESSING'


TABLES et_result = lt_result_portion
EXCEPTIONS OTHERS = 0.

" add portion result to common


APPEND LINES OF lt_result_portion TO mt_result.

ENDMETHOD.

METHOD get_available_workprocesses.

CALL FUNCTION 'SPBT_INITIALIZE'


EXPORTING
group_name = mc_group_name
IMPORTING
free_pbt_wps = rv_count
EXCEPTIONS
invalid_group_name = 1
internal_error = 2
pbt_env_already_initialized = 3
currently_no_resources_avail = 4
no_pbt_resources_found = 5
cant_init_different_pbt_groups = 6
OTHERS = 7.
IF sy-subrc <> 0.
CALL FUNCTION 'SPBT_GET_CURR_RESOURCE_INFO'
IMPORTING
free_pbt_wps = rv_count
EXCEPTIONS
internal_error = 1
pbt_env_not_initialized_yet = 2
OTHERS = 3.
IF sy-subrc <> 0.

CLEAR rv_count.
ENDIF.
ENDIF.

ENDMETHOD.

ENDCLASS.

RFC- Function module, which contains resource intensive calculations.


FUNCTION z_very_slow_processing.

LOOP AT it_key ASSIGNING FIELD-SYMBOL(<ls_key>).

" random delay to simulate resource intensive calculation


PERFORM random_delay.

" fill resulting table


APPEND CORRESPONDING #( <ls_key> ) TO et_result.

ENDLOOP.
ENDFUNCTION.

FORM random_delay.

" random delay to simulate resource intensive calculation


DATA lv_random_delay TYPE i.

CALL FUNCTION 'RANDOM_I4'


EXPORTING
rnd_min = 1
rnd_max = 5
IMPORTING
rnd_value = lv_random_delay.

WAIT UP TO lv_random_delay SECONDS.

ENDFORM.

You might also like