Wednesday, 21 August 2013
WEB Services
- http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/d0d0a250-ccd1-2c10-9e9f-b9d5cf259a6d?quicklink=index&overridelayout=true.
- http://saptechnical.com/Tutorials/Others/ABAPWebservices/create.htm
- http://wiki.sdn.sap.com/wiki/display/ABAP/Web+Service+Publishing
- http://help-sap.blogspot.in/search/label/SAP_BC_WEBSERVICE_SERVICE_USER
Wednesday, 7 August 2013
Parallel Processing technique in SAP ABAP and its Advantages
For
some SAP reports, the nights are getting too short. Especially at customers
with large volumes of data, some SAP reports that customarily run in the
background processing system (such as material planning runs) may have run
times of many hours. It can be difficult to finish such jobs in the
“night-time” that is available, especially if dialog users are spread across
several time zones.
With
Release 3.1G, SAP offers a solution to the “short nights” problem:
parallel-processed background jobs. Long-running SAP reports can now implement
parallel processing, which lets them parcel out the work to be done to
available dialog work processes in the SAP system and then collect the results.
Parallel
processing is implemented in ABAP reports and programs, not in the background
processing system itself. That means that jobs are only processed in parallel
if the report that runs in a job step is programmed for parallel processing.
Such reports can also process in parallel if they are started interactively.
Important Note: Parallel-processing is
implemented with a special variant of asynchonous RFC. It’s important that you
use only the correct variant for your own parallel processing applications: the
CALL FUNCTION STARTING NEW TASK DESTINATION IN GROUP keyword. Using other
variants of asynchronous RFC circumvents the built-in safeguards in the correct
keyword, and can bring your system to its knees
Below is the sample code which
will guide us to implement Parallel Processing in future whenever needed.
*&---------------------------------------------------------------------*
*& Report ZPAR_PARALLEL_PROCESS
*&
*&---------------------------------------------------------------------*
REPORT zpar_parallel_process.
TABLES : mara.
DATA : bapimatdoa TYPE bapimatdoa,
bapireturn TYPE bapireturn.
DATA : system TYPE rzlli_apcl,
taskname(8) TYPE c,
index(3) TYPE c,
snd_jobs TYPE i,
rcv_jobs TYPE i,
exc_flag TYPE i,
mess TYPE c LENGTH 80.
TYPES : BEGIN OF type_material,
desc TYPE maktx,
END OF type_material.
DATA : material TYPE TABLE OF type_material WITH HEADER LINE,
i_mara TYPE STANDARD TABLE OF mara.
DATA: functioncall1(1) TYPE c.
CONSTANTS: done(1) TYPE c VALUE 'X'.
FIELD-SYMBOLS: <fs_mara> TYPE mara.
SELECT-OPTIONS s_matnr FOR mara-matnr.
SELECT * FROM mara INTO TABLE i_mara WHERE matnr IN s_matnr.
**********************************************************************************
* RFC Server Group created from transaction RZ12
* It will be the config for Parallel processing.
* We can keep it as DEFAULT. In our case it is 'parallel_generators'
**********************************************************************************
system = 'parallel_generators'.
LOOP AT i_mara ASSIGNING <fs_mara>.
index = sy-tabix.
CONCATENATE 'Task' index INTO taskname. " Generate Unique Task Name
**********************************************************************************
* Below is the SYNTAX for calling our own FM (For which we need Papallel processing)
*
* CALL FUNCTION func STARTING NEW TASK task
* [DESTINATION {dest|{IN GROUP {group|DEFAULT}}}]
* parameter_list
* [{PERFORMING subr}|{CALLING meth} ON END OF TASK].
*
* We can keep the syntax as DESTINATION IN GROUP DEFAULT instead of
* DESTINATION IN GROUP system
*
* The above syntaxes will creates Different task name TASK in a separate work process.
* Each such task executes “process_parallel” in a separate work process.
*
**********************************************************************************
CALL FUNCTION 'BAPI_MATERIAL_GET_DETAIL' STARTING NEW TASK taskname
DESTINATION IN GROUP system
PERFORMING process_parallel ON END OF TASK
EXPORTING
material = <fs_mara>-matnr
EXCEPTIONS
system_failure = 1 MESSAGE mess
communication_failure = 2 MESSAGE mess
resource_failure = 3.
CASE sy-subrc.
WHEN 0.
snd_jobs = snd_jobs + 1.
WHEN 1 OR 2.
MESSAGE mess TYPE 'I'.
WHEN 3.
IF snd_jobs >= 1 AND
exc_flag = 0.
exc_flag = 1.
WAIT UNTIL rcv_jobs >= snd_jobs
UP TO 5 SECONDS.
ENDIF.
IF sy-subrc = 0.
exc_flag = 0.
ELSE.
MESSAGE 'Resource failure' TYPE 'I'.
ENDIF.
WHEN OTHERS.
MESSAGE 'Other error' TYPE 'I'.
ENDCASE.
ENDLOOP.
WAIT UNTIL rcv_jobs >= snd_jobs.
LOOP AT material.
WRITE : material-desc.
ENDLOOP.
*&---------------------------------------------------------------------*
*& Form process_parallel
*&---------------------------------------------------------------------*
* Each task will execute “process_parallel” in a separate work process.
*& Report ZPAR_PARALLEL_PROCESS
*&
*&---------------------------------------------------------------------*
REPORT zpar_parallel_process.
TABLES : mara.
DATA : bapimatdoa TYPE bapimatdoa,
bapireturn TYPE bapireturn.
DATA : system TYPE rzlli_apcl,
taskname(8) TYPE c,
index(3) TYPE c,
snd_jobs TYPE i,
rcv_jobs TYPE i,
exc_flag TYPE i,
mess TYPE c LENGTH 80.
TYPES : BEGIN OF type_material,
desc TYPE maktx,
END OF type_material.
DATA : material TYPE TABLE OF type_material WITH HEADER LINE,
i_mara TYPE STANDARD TABLE OF mara.
DATA: functioncall1(1) TYPE c.
CONSTANTS: done(1) TYPE c VALUE 'X'.
FIELD-SYMBOLS: <fs_mara> TYPE mara.
SELECT-OPTIONS s_matnr FOR mara-matnr.
SELECT * FROM mara INTO TABLE i_mara WHERE matnr IN s_matnr.
**********************************************************************************
* RFC Server Group created from transaction RZ12
* It will be the config for Parallel processing.
* We can keep it as DEFAULT. In our case it is 'parallel_generators'
**********************************************************************************
system = 'parallel_generators'.
LOOP AT i_mara ASSIGNING <fs_mara>.
index = sy-tabix.
CONCATENATE 'Task' index INTO taskname. " Generate Unique Task Name
**********************************************************************************
* Below is the SYNTAX for calling our own FM (For which we need Papallel processing)
*
* CALL FUNCTION func STARTING NEW TASK task
* [DESTINATION {dest|{IN GROUP {group|DEFAULT}}}]
* parameter_list
* [{PERFORMING subr}|{CALLING meth} ON END OF TASK].
*
* We can keep the syntax as DESTINATION IN GROUP DEFAULT instead of
* DESTINATION IN GROUP system
*
* The above syntaxes will creates Different task name TASK in a separate work process.
* Each such task executes “process_parallel” in a separate work process.
*
**********************************************************************************
CALL FUNCTION 'BAPI_MATERIAL_GET_DETAIL' STARTING NEW TASK taskname
DESTINATION IN GROUP system
PERFORMING process_parallel ON END OF TASK
EXPORTING
material = <fs_mara>-matnr
EXCEPTIONS
system_failure = 1 MESSAGE mess
communication_failure = 2 MESSAGE mess
resource_failure = 3.
CASE sy-subrc.
WHEN 0.
snd_jobs = snd_jobs + 1.
WHEN 1 OR 2.
MESSAGE mess TYPE 'I'.
WHEN 3.
IF snd_jobs >= 1 AND
exc_flag = 0.
exc_flag = 1.
WAIT UNTIL rcv_jobs >= snd_jobs
UP TO 5 SECONDS.
ENDIF.
IF sy-subrc = 0.
exc_flag = 0.
ELSE.
MESSAGE 'Resource failure' TYPE 'I'.
ENDIF.
WHEN OTHERS.
MESSAGE 'Other error' TYPE 'I'.
ENDCASE.
ENDLOOP.
WAIT UNTIL rcv_jobs >= snd_jobs.
LOOP AT material.
WRITE : material-desc.
ENDLOOP.
*&---------------------------------------------------------------------*
*& Form process_parallel
*&---------------------------------------------------------------------*
* Each task will execute “process_parallel” in a separate work process.
*----------------------------------------------------------------------
FORM process_parallel USING taskname.
rcv_jobs = rcv_jobs + 1.
RECEIVE RESULTS FROM FUNCTION 'BAPI_MATERIAL_GET_DETAIL'
IMPORTING
material_general_data = bapimatdoa.
bapireturn = bapireturn.
functioncall1 = done.
APPEND bapimatdoa-matl_desc TO material.
ENDFORM.
FORM process_parallel USING taskname.
rcv_jobs = rcv_jobs + 1.
RECEIVE RESULTS FROM FUNCTION 'BAPI_MATERIAL_GET_DETAIL'
IMPORTING
material_general_data = bapimatdoa.
bapireturn = bapireturn.
functioncall1 = done.
APPEND bapimatdoa-matl_desc TO material.
ENDFORM.
-----------------------------------------------------------------------
-----------------------------------------------------------------------
Program without Parallel
Processing:
Here with normal loop process (without using parallel processing), the
control would wait for each record inside the loop until the FM would return
the values.
*&---------------------------------------------------------------------*
*& Report ZPAR_LOOP
*&
*&---------------------------------------------------------------------
REPORT ZPAR_LOOP.
TABLES : MARA.
DATA : BAPIMATDOA TYPE BAPIMATDOA,
BAPIRETURN TYPE BAPIRETURN.
DATA: i_mara TYPE STANDARD TABLE OF mara.
FIELD-SYMBOLS: <fs_mara> TYPE mara.
SELECT-OPTIONS S_MATNR FOR MARA-MATNR.
SELECT * FROM mara INTO TABLE i_mara WHERE matnr IN s_matnr.
LOOP AT i_mara ASSIGNING <fs_mara>.
CALL FUNCTION 'BAPI_MATERIAL_GET_DETAIL'
EXPORTING
MATERIAL = <fs_mara>-matnr
IMPORTING
MATERIAL_GENERAL_DATA = BAPIMATDOA.
write : BAPIMATDOA-MATL_DESC.
ENDLOOP.
*& Report ZPAR_LOOP
*&
*&---------------------------------------------------------------------
REPORT ZPAR_LOOP.
TABLES : MARA.
DATA : BAPIMATDOA TYPE BAPIMATDOA,
BAPIRETURN TYPE BAPIRETURN.
DATA: i_mara TYPE STANDARD TABLE OF mara.
FIELD-SYMBOLS: <fs_mara> TYPE mara.
SELECT-OPTIONS S_MATNR FOR MARA-MATNR.
SELECT * FROM mara INTO TABLE i_mara WHERE matnr IN s_matnr.
LOOP AT i_mara ASSIGNING <fs_mara>.
CALL FUNCTION 'BAPI_MATERIAL_GET_DETAIL'
EXPORTING
MATERIAL = <fs_mara>-matnr
IMPORTING
MATERIAL_GENERAL_DATA = BAPIMATDOA.
write : BAPIMATDOA-MATL_DESC.
ENDLOOP.
With Parallel Processing
(Runtime Analysis – SE30)
Without Parallel Processing
(Runtime Analysis – SE30)
Now SAP has provided a standard framework for parallel
processing. This is very sophisticated to use. Find the details in
below link.
Tuesday, 6 August 2013
Parallel Cursor Vs. Nested Loop
Nested Loops – This is one of the fear factors for all the ABAP developers as this consumes lot of program execution time. If the number of entries in the internal tables is huge, then the situation would be too worse. The solution for this is to use parallel cursor method whenever there is a need for Nested Loop.
Sample program to compare the Parallel Cursor Vs. Nested Loop:
*&---------------------------------------------------------------------*
*& Report ZPARALLEL_CURSOR_Vs_NESTED LOOP
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT ZPARALLEL_CURSOR.
TYPES: ty_t_vbak TYPE STANDARD TABLE OF vbak.
DATA: it_vbak TYPE ty_t_vbak .
*
TYPES: ty_t_vbap TYPE STANDARD TABLE OF vbap.
DATA: it_vbap TYPE ty_t_vbap.
*
FIELD-SYMBOLS: <lfs_vbak> LIKE LINE OF it_vbak,
<lfs_vbap> LIKE LINE OF it_vbap.
*
* necessary data selection
SELECT * FROM vbak
INTO TABLE it_vbak
UP TO 1000 ROWS.
CHECK it_vbak IS NOT INITIAL.
SELECT * FROM vbap
INTO TABLE it_vbap
FOR ALL ENTRIES IN it_vbak
WHERE vbeln = it_vbak-vbeln.
*
DATA: lv_start_time TYPE timestampl,
lv_end_time TYPE timestampl,
lv_diff TYPE timestampl.
DATA: lv_tabix TYPE i.
*
*...... Normal Nested Loop .................................
* Get the Start Time
GET TIME STAMP FIELD lv_start_time.
*
* Nested Loop
LOOP AT it_vbak ASSIGNING <lfs_vbak>.
LOOP AT it_vbap ASSIGNING <lfs_vbap>
WHERE vbeln = <lfs_vbak>-vbeln.
ENDLOOP.
ENDLOOP.
*
* Get the end time
GET TIME STAMP FIELD lv_end_time.
*
* Actual time Spent:
lv_diff = lv_end_time - lv_start_time.
WRITE: /(50) 'Time Spent on Nested Loop', lv_diff.
*
CLEAR: lv_start_time, lv_end_time, lv_diff.
*
*....... Parallel Cursor with Nested Loop .......................
* Get the Start Time
GET TIME STAMP FIELD lv_start_time.
*
* Starting the Parallel Cursor
SORT: it_vbak BY vbeln,
it_vbap BY vbeln.
LOOP AT it_vbak ASSIGNING <lfs_vbak>.
*
* Read the second internal table with BINARY SEARCH
READ TABLE it_vbap TRANSPORTING NO FIELDS
WITH KEY vbeln = <lfs_vbak>-vbeln
BINARY SEARCH.
* Get the TABIX number
lv_tabix = sy-tabix.
* Start the LOOP from the first accessed record in
* previous READ i.e. LV_TABIX
LOOP AT it_vbap FROM lv_tabix ASSIGNING <lfs_vbap> .
*
* End the LOOP, when there is no more record with similar key
IF <lfs_vbap>-vbeln <> <lfs_vbak>-vbeln.
EXIT.
ENDIF.
* Rest of the logic would go from here...
*
ENDLOOP.
*
ENDLOOP.
*
* Get the end time
GET TIME STAMP FIELD lv_end_time.
*
* Actual time Spent:
lv_diff = lv_end_time - lv_start_time.
WRITE: /(50) 'Time Spend on Parallel Cursor Nested loops:', lv_diff.
Analysis
report: Runtime in microseconds:
Friday, 2 August 2013
Play with IDOC :-)
Transactions to play with IDOC(s):
RBDAPP01 - change status for Inbound IDOC (yellow to green)
RSEOUT00 - Process all selected IDocs (EDI)
RSNAST00 - trigger idoc with output type.
RBDMIDOC - trigger change pointer (BD21)
RBDAGAIN (For Outbound) - Process Outbound IDOCs with Error Again
RBDMANI2 (For Inbound) - Manual Processing of IDOCs: Post IDOCs Not Yet Posted
(Reprocess the failed IDOC)
RBDAGAI2 - Reprocess IDOCs after inbound ALE Error (BD84)
RSARFCEX - Execute Calls Not Yet Executed
RBDMOIND - Status Conversion with Successful tRFC Execution
(to change the idoc status from 30
to 03)
RBDMANIN - Start error handling for non-posted IDocsRBDSTATE - Send Audit Confirmations
BD87 - IDoc reprocessing
WE19 – IDoc reprocessing
Edit the iDoc using WE02 ……
Outbound:
RBDAGAIN or T-Code BD87
This would push your Idoc from *02*(Error passing data to port) to 30(Idoc ready to dispatch) status.
Now to send the Idoc from 30 to *03*(Data passed to port OK) use the "RSEOUT00" program and run another job as stated above.
This would send the Idocs to 03.
Similarly at Inbound side:
To reprocess an Idoc in 51 status:
Use program "RBDMANI2" and run a job.It will push Idocs from 51 to 53 status.
For 64 status use "RBDAPP01" program.
You can do it in transaction code BD87
IDOC STATUS:
For Inbound --
53 - Idoc Posted successfully
51 - Failed .(Can find the reason under the status in WE02 or from Table - EDIDS).
68 - This is basically failure status .This happens in between between 64 and 51. (From here also we can find the cause of failure). Sometime what happened that there we can see that the green light against the IDOC but the latest status message is 68 (Error no further processing).
64 - Idoc ready for transfer. (We can use Transaction BD20 to process the waiting IDOCs).
50 - Idoc Added.
74 - Idoc was created by test transaction . (i.e-With using the transaction WE19).
For Outbound --
03 - Idoc passed to the port OK .
02 - Error passing data to port. (Could not find code page for receiving system).
30 - Idoc ready for dispatch.
01 - Idoc Generated .
Pop up for Month and Year
*&---------------------------------------------------------------------*
*& Report ZPAR_TEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zpar_test.
DATA: v_year_month LIKE isellist-month,
v_code LIKE sy-subrc.
PARAMETER: v_month LIKE isellist-month.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR v_month.
v_year_month = sy-datum+0(6).
CALL FUNCTION 'POPUP_TO_SELECT_MONTH'
EXPORTING
actual_month = v_year_month
language = sy-langu
start_column = 8
start_row = 5
IMPORTING
selected_month = v_month
return_code = v_code
EXCEPTIONS
factory_calendar_not_found = 1
holiday_calendar_not_found = 2
month_not_found = 3
OTHERS = 4.
*& Report ZPAR_TEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zpar_test.
DATA: v_year_month LIKE isellist-month,
v_code LIKE sy-subrc.
PARAMETER: v_month LIKE isellist-month.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR v_month.
v_year_month = sy-datum+0(6).
CALL FUNCTION 'POPUP_TO_SELECT_MONTH'
EXPORTING
actual_month = v_year_month
language = sy-langu
start_column = 8
start_row = 5
IMPORTING
selected_month = v_month
return_code = v_code
EXCEPTIONS
factory_calendar_not_found = 1
holiday_calendar_not_found = 2
month_not_found = 3
OTHERS = 4.
Subscribe to:
Comments (Atom)



