Skip to Content

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:

image

 

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:

 

image

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:

image

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.

image

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.

image

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

image

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

image

GO TO TRANSACTION VA01.: DEFAULT USER VALUES ARE POPULATED

image

To report this post you need to login first.

5 Comments

You must be Logged on to comment or reply to a post.

  1. Jason Muzzy
    Are you familiar with parameter IDs?  Each user can save them in their own profile under System –> User Profile –> Own Data on the Parameters tab.  There are parameter IDs available for many, many fields.  You can find which PID is assigned to which field by putting your cursor in the field and pushing F1, then clicking the Technical Information button.  These PIDs are pretty much global across all transactions so no implementation of enhancement points is necessary.  For example, on the VA01 screen you can use PID AAT to default the order type, VKO for sales org, VTW for distribution channel, SPA for division, VKB for sales office, and VKB for sales group.  Those same PIDs would also work on the XD01 screen and many others.
    (0) 
    1. Ravi Shankar Rajan Post author
      Hi Jason
      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.
      (0) 
    2. Ravi Shankar Rajan Post author
      Hi Jason
      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.
      (0) 
      1. Anonymous
        Ravi,

        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

        (0) 
  2. Paul Hardy
    There is a much easier way to do this. In VA01 the bulk of fields already have parameter ID’s, so there is no need at all to store duplicate data in a custom table i.e. default values for sales organisation etc. If you store the same data in two different places in a database, then they will get out of synch.
    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

    (0) 

Leave a Reply