A business scenario using SAP Shared Objects
A business scenario using SAP “Shared Objects”
Most of you working in SAP ECC 6.0 version would have heard about “Shared Objects” and its wonderful features. You can get a hands-on idea about the concept by referring to the excellent blog written by Thomas Jung, the link is as below:
Netweaver for the Holidays: A Lession in Sharing (ABAP Shared Memory)
In this blog I would like to explain a real time business scenario in which we used this concept very successfully.
Business requirement:
In a typical production environment users need to create sales orders on a large scale. Depending on the group to which a particular user belongs or depending upon the requirements of the user, there will be certain default values for certain fields in the sales order which always have to be entered by the user. These default values may also have to be changed from time to time based on the business needs.Repetative entering of the same data for every sales order results in wastage of user productive time. So a solution is required in which a user is able to save his specific default data and the same data gets automatically reflected on creation of the sales order in the sales order creation transaction(VA01).
Solution:
The solution to this requirement is in two broad steps:
1. A custom transaction in which the user can enter default values for common fields.
The screenshot of the screen is as below:
2. Initializing the values in VA01 Transaction
This is done so that the user saved default values gets loaded on the screen on opening of the VA01 transaction. This can be done by using “Enhancement points” available in the standard SAP VA01 code. (Screen 100 of program SAPMV45A)The screen shot is as below:
Steps for creating Shared objects:
1. Creation of Root Class:
This class will contain the methods for storing and retrieving the default values specific for a user. The values will be stored in table type “PARAMETER_TABLE” whose definition has been defined in a type pool as shown below:
TYPE-POOL zpid .
TYPES : BEGIN OF zpid_t_id,
fieldname TYPE fieldname,
pid(3) TYPE c,
value TYPE string,
username TYPE syuname,
END OF zpid_t_id.
TYPES :
zpid_it_pid TYPE STANDARD TABLE OF zpid_t_id WITH DEFAULT KEY,
zpid_wa_pid TYPE zpid_t_id.
This type pool will be declared in the “Forward declaration” section of the class. This class will be the usual ABAP class with “Share memory enabled” from the general data of the class properties. Include the interface IF_SHM_BUILD_INSTANCE in the interface section of the class. We will be using the “BUILD” method of this interface to automatically create the shared memory area whenever a sales order is been created. A screenshot of the methods of the class is as below:
METHOD if_shm_build_instance~build.
DATA: area TYPE REF TO zcl_shared_area_pid,
root TYPE REF TO zcl_shared_root_pid,
lt_parameter_table TYPE zpid_it_pid.
****get a pointer to the Shared Area
TRY.
area = zcl_shared_area_pid=>attach_for_write(
attach_mode = cl_shm_area=>attach_mode_wait
wait_time = 1 ).
CATCH cx_shm_no_active_version.
CATCH cx_shm_pending_lock_removed.
CATCH cx_shm_change_lock_active.
CATCH cx_shm_version_limit_exceeded.
CATCH cx_shm_exclusive_lock_active.
WAIT UP TO 1 SECONDS.
area = zcl_shared_area_pid=>attach_for_write( ).
ENDTRY.
****Create an instance of our root
CREATE OBJECT root AREA HANDLE area.
*****Set the Initial value for our table
CALL METHOD root->set_parameters
EXPORTING
i_parameter_table = lt_parameter_table.
****Set the root back into the Area
area->set_root( root ).
****Commit and detatch
area->detach_commit( ).
ENDMETHOD.
METHOD set_parameters.
DATA :
lv_index TYPE sytabix,
wa_pid TYPE zpid_wa_pid,
wa_pid1 TYPE zpid_wa_pid.
CLEAR : lv_index,wa_pid,wa_pid1.
DELETE paramter_table WHERE username = sy-uname.
LOOP AT i_parameter_table INTO wa_pid.
lv_index = sy-tabix.
wa_pid-username = sy-uname.
wa_pid1 = wa_pid.
APPEND wa_pid1 TO paramter_table.
CLEAR : wa_pid,wa_pid1.
ENDLOOP.
ENDMETHOD.
METHOD get_parameters.
DATA :
lv_index TYPE sytabix,
wa_pid TYPE zpid_wa_pid,
wa_pid1 TYPE zpid_wa_pid.
LOOP AT paramter_table INTO wa_pid WHERE username = sy-uname.
wa_pid1 = wa_pid.
APPEND wa_pid1 TO r_parameter_table.
CLEAR : wa_pid1,wa_pid.
ENDLOOP.
ENDMETHOD.
2. Creating the Shared memory area :
The screen shot is as below
3. The custom Z program will be used by the user to save his default values to the shared memory. A snippet of the code is as below:
*&———————————————————————*
*& Form SUB_UPDATE_PID
*&———————————————————————*
* exporting data to the shared memory
*———————————————————————-*
FORM sub_update_pid.
DATA: area TYPE REF TO zcl_shared_area_pid,
root TYPE REF TO zcl_shared_root_pid,
lt_parameter_table TYPE zpid_it_pid,
lwa_parameter TYPE zpid_wa_pid.
*****get a pointer to the Shared Area
TRY.
area = zcl_shared_area_pid=>attach_for_update(
attach_mode = cl_shm_area=>attach_mode_wait
wait_time = 1 ).
CATCH cx_shm_no_active_version.
WAIT UP TO 1 SECONDS.
area = zcl_shared_area_pid=>attach_for_update( ).
ENDTRY.
****Get a pointer to the Root
root ?= area->get_root( ).
IF root IS INITIAL.
****Create an instance of our root
CREATE OBJECT root AREA HANDLE area.
ENDIF.
*Pass the filled Parameters from the screen to the Shared memory.
*This will be done in the custom transaction screen where user will
*enter his default values.
LOOP AT it_pid INTO wa_pid.
lwa_parameter-fieldname = wa_pid-fname.
lwa_parameter-pid = wa_pid-parid.
lwa_parameter-value = wa_pid-value.
APPEND lwa_parameter TO lt_parameter_table.
ENDLOOP.
CALL METHOD root->set_parameters
EXPORTING
i_parameter_table = lt_parameter_table.
****Set the root back into the Area
area->set_root( root ).
****Commit and detatch
area->detach_commit( ).
ENDFORM. “SUB_UPDATE_PID
4. An enhancement point will be used in SAP standard program SAPMV45A screen 100 to write the code to read the data from the shared memory and populate the corresponding fields in the sales order. The code snippet is as below:
*&———————————————————————*
*& Form SUB_GET_PARAMETER_IDS
*&———————————————————————*
*———————————————————————-*
* This will fill default values to the transaction VA01 from shared memory
*———————————————————————-*
FORM SUB_GET_PARAMETER_IDS.
TYPE-POOLS : zpid.
DATA :
lt_parameter_table TYPE zpid_it_pid,
lwa_parameter TYPE zpid_wa_pid.
*Auto Preloading of Shared instance
DATA: area TYPE REF TO zcl_shared_area_pid,
root TYPE REF TO zcl_shared_root_pid.
****The read doesn’t wait for initialization to finish
****Therefore we have to wait.
TRY.
area = zcl_shared_area_pid=>attach_for_read( ).
CATCH cx_shm_no_active_version.
WAIT UP TO 1 SECONDS.
area = zcl_shared_area_pid=>attach_for_read( ).
ENDTRY.
****Get a pointer to the Root
root ?= area->get_root( ).
IF root IS INITIAL.
****Create an instance of our root
CREATE OBJECT root AREA HANDLE area.
ENDIF.
CALL METHOD root->get_parameters
RECEIVING
r_parameter_table = lt_parameter_table.
LOOP AT lt_parameter_table INTO lwa_parameter.
CASE lwa_parameter-fieldname.
WHEN ‘VKORG’.
vbak-vkorg = lwa_parameter-value.
WHEN ‘VTWEG’.
vbak-vtweg = lwa_parameter-value.
WHEN ‘SPART’.
vbak-spart = lwa_parameter-value.
WHEN ‘VKBUR’.
vbak-vkbur = lwa_parameter-value.
WHEN ‘VKGRP’.
vbak-vkgrp = lwa_parameter-value.
WHEN ‘WERKS’.
vbap-werks = lwa_parameter-value.
rv45a-dwerk = vbap-werks.
ENDCASE.
ENDLOOP.
area->detach( ).
ENDFORM.
The screen shot of the sales order with the default values filled is as below:
SAVE DEFAULT VALUES THROUGH CUSTOM TRANSACTION
GO TO TRANSACTION VA01.: DEFAULT USER VALUES ARE POPULATED








Unfortunately not all the SAP fields have parameter IDS available.The above screenshot is an simplified version of the program.There are a lot more conditions and rules involved in many fields which can't be handled by only parameter IDs.That is the reason we had to go for this concept.
Unfortunately not all the SAP fields have parameter IDS available.The above screenshot is an simplified version of the program.There are a lot more conditions and rules involved in many fields which can't be handled by only parameter IDs.That is the reason we had to go for this concept.
Thank you for presenting your idea. I was hoping to see what the real business scenario was when I read this blog summary. Unfortunately, the simplified example presented does not deliver in that regard. If possible, I'd really be curious to see one of the more complex real business scenarios in which simple PID's could not be used instead.
Cheers,
Jamie
For the 5% of fields that do not have parameter ID's I would use a field exit to pre-populate the field. SAP would claim that field exits no longer work, but they do - go into transaction CMOD and type in PRFB in the command box and the field exit screen appears.
Here is an example where I pre-populate the supplying plant field in VA01 with a users PID for plant.
FUNCTION FIELD_EXIT_DWERK.
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" VALUE(INPUT)
*" EXPORTING
*" VALUE(OUTPUT)
*"----------------------------------------------------------------------
DATA: L_AUART LIKE VBAK-AUART.
*** Start off by setting default value
OUTPUT = INPUT.
*** If the user is making a change, then let them
CHECK OUTPUT IS INITIAL.
*** Find sales order type
GET PARAMETER ID 'AAT' FIELD L_AUART.
*** Only VPN or Ex-Bin
CHECK ( L_AUART = 'ZOC' OR L_AUART = 'ZEX' ).
*** Default supplying plant from user master record
SELECT SINGLE PARVA FROM USR05 INTO OUTPUT
WHERE BNAME = SY-UNAME
AND PARID = 'WRK'.
*** Error handling
IF SY-SUBRC NE 0.
OUTPUT = INPUT.
ENDIF.
ENDFUNCTION.
USR05 has generic buffering so there is no database access at all after the system has been up for a short while. You can also create your own parameter ID's. You can also assign a field exit to more than one program, or even globally. In the shared memory example you would have to enahnce every program where you wanted the data pre-populated.
In the example above you will see I have a business rule - in this case I am sure that the parameter ID for the order type will have a value. If I was not 100% certain I would use the trick of assigning a field symbol and reading the call stack to retrieve values from the main program.
Cheersy Cheers
Paul