Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
arijitkumardas
Product and Topic Expert
Product and Topic Expert



Objective

Businesses often maintain critical data in a bespoke table. This data is then rendered to users via a standard transaction/(s). The entries in the table are maintained from a single access point; using a bespoke transaction code that accesses the table maintenance transaction - SM30 or a dialog program. When the data changes, the updated value is displayed when the standard transaction is next executed. We will use the SAP Plant Maintenance module to demonstrate this.

Create the following objects

Table, Data Elements and Domains


Create table ZPRPS in SE11.

Include the following fields in it with the appropriate Data Elements and Domains –

These fields will be available to the user in the following standard transactions –


IW21 - Create PM Notification – General,

IW22 - Change PM Notification, and
IW23 - Display PM Notification.
Create the Table Maintenance Generator (menu - Utilities >> Table Maintenance Generator).
Name the Function group as ZPRPS, give it an appropriate package, Maintenance type - one step, Overview screen – 100, Recording routine - no, or user, recording routine (ignore the Authorization Group which has been set to ZMMT; this has been done to restrict user access). Click the Create icon (not shown here).

Change Document Object for the Table


In transaction SCDO create a Change Document Object - ZPRPS_CD for the table.


Save it, and Back out of this screen.
Place the cursor on ZPRPS_CD and click Generate update pgm.

Accept the following options, click Generate.


The next screen displays the objects that have been created.


We can call Function Module ZPRPS_CD_WRITE_DOCUMENT to log changes for new records, updates to exiting records, and records that are deleted from ZPRPS. We also need to foolproof the table maintenance to prevent users deleting records that are currently referenced in one or more Notification/(s).
Go to Table Maintenance Generator for table ZPRPS, (menu - Environment >> Modification >> Events).
Click through the pop-up screen.

Create 3 custom Form routines for keys 01, 02 and 03 and give them an appropriate name.

Z_BEFORE_SAVE retrieves the records currently in the database, Z_AFTER_SAVE writes the change records for inserts, updates and deletes, and Z_BEFORE_DEL prevents a record from being deleted if it is referenced in a Notification.

Click on the Editor button, this will take us to the include LZPRPSF01. This include is part of the Function Group ZPRPS which was created when we generated the table maintenance for table ZPRPS.


Before we code the routines we will need to declare a global variable in the TOP include LZPRPSTOP.


DATA: gt_zprps TYPE STANDARD TABLE OF zprps.


Now enter the code provided below for the routines –

*&---------------------------------------------------------------------*
*&      Form  z_before_save
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM z_before_save.

* Select all the current entries from ZPRPS
  SELECT *
    FROM zprps
    INTO TABLE gt_zprps.

* Set the SY-SUBRC to 0 - the first time when you populate entries in the
* table, SY-SUBRC will be set to 4 and you will not be able to Save it
  sy-subrc = 0.

ENDFORM.                    "Z_BEFORE_SAVE

*&---------------------------------------------------------------------*
*&      Form  z_after_save
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM z_after_save.

  DATA: lt_cdtxt TYPE STANDARD TABLE OF cdtxt,
        ls_cdtxt TYPE cdtxt,
        lv_objectid TYPE cdobjectv,
        ls_zprps_o TYPE zprps,
        ls_zprps_n TYPE zprps,
        lv_objkey TYPE swo_typeid,
        lt_swcont TYPE STANDARD TABLE OF swcont,
        ls_qmel TYPE qmel,
        lv_exists_flg TYPE c.

* Insert and Update
  LOOP AT extract.

*   Check that this record exists in the database
    CLEAR: ls_zprps_o.
    READ TABLE gt_zprps
      INTO ls_zprps_o
      WITH KEY zzposid = extract+3(24).

    IF sy-subrc = 0.

*     Check that the current record differs from the original – comparison is
*     based on Project Name and Project Date
      CHECK: ls_zprps_o-zzpost1 <> extract+27(40) OR
             ls_zprps_o-zzpstrt <> extract+80(8).

      CLEAR: lv_objectid,
             ls_cdtxt,
             lt_cdtxt,
             ls_zprps_n.

*     Create the data to be written to the change logs
      lv_objectid = extract+3(24).

      ls_zprps_n-mandt   = extract+0(3).
      ls_zprps_n-zzposid = extract+3(24).
      ls_zprps_n-zzpost1 = extract+27(40).
      ls_zprps_n-zzprart = extract+67(13).
      ls_zprps_n-zzpstrt = extract+80(8).

*     Call the FM to write the changes to CDHDR & CDPOS for the updated record
      CALL FUNCTION 'ZPRPS_CD_WRITE_DOCUMENT'
        EXPORTING
          objectid                = lv_objectid
          tcode                   = sy-tcode
          utime                   = sy-timlo
          udate                   = sy-datlo
          username                = sy-uname
          object_change_indicator = 'U'
          upd_icdtxt_zprps_cd     = 'U'
          n_zprps                 = ls_zprps_n
          o_zprps                 = ls_zprps_o
          upd_zprps               = 'U'
        TABLES
          icdtxt_zprps_cd         = lt_cdtxt.

*     This raises the Event CHANGED which triggers the Workflow
      COMMIT WORK AND WAIT.

    ELSE.

*     It’s a new record
      CHECK: extract+3(24) IS NOT INITIAL.

      CLEAR: lv_objectid,
             ls_cdtxt,
             lt_cdtxt,
             ls_zprps_n.

*     Create the data to be written to the change logs
      lv_objectid = extract+3(24).

      ls_zprps_n-mandt   = extract+0(3).
      ls_zprps_n-zzposid = extract+3(24).
      ls_zprps_n-zzpost1 = extract+27(40).
      ls_zprps_n-zzprart = extract+67(13).
      ls_zprps_n-zzpstrt = extract+80(8).

*     Call the FM to write the changes to CDHDR & CDPOS for the new record
      CALL FUNCTION 'ZPRPS_CD_WRITE_DOCUMENT'
        EXPORTING
          objectid                = lv_objectid
          tcode                   = sy-tcode
          utime                   = sy-timlo
          udate                   = sy-datlo
          username                = sy-uname
          object_change_indicator = 'I'
          upd_icdtxt_zprps_cd     = 'I'
          n_zprps                 = ls_zprps_n
          o_zprps                 = ls_zprps_o
          upd_zprps               = 'I'
        TABLES
          icdtxt_zprps_cd         = lt_cdtxt.

*     If there is an Event and a Workflow associated with Insert it will be
*     triggered
      COMMIT WORK AND WAIT.

    ENDIF.
  ENDLOOP.

* Delete
  LOOP AT gt_zprps
    INTO ls_zprps_o.

    CLEAR: lv_exists_flg.
    LOOP AT extract.
*     If the record is not found in GT_ZPRPS then it was deleted
      CHECK: extract+3(24) = ls_zprps_o-zzposid.
      lv_exists_flg = 'X'.
      EXIT.
    ENDLOOP.

    CHECK: lv_exists_flg IS INITIAL.

    CLEAR: lv_objectid,
           ls_cdtxt,
           lt_cdtxt,
           ls_zprps_n.

    lv_objectid = ls_zprps_o-zzposid.

*   Call the FM to write the changes to CDHDR & CDPOS for the deleted record
    CALL FUNCTION 'ZPRPS_CD_WRITE_DOCUMENT'
      EXPORTING
        objectid                = lv_objectid
        tcode                   = sy-tcode
        utime                   = sy-timlo
        udate                   = sy-datlo
        username                = sy-uname
        object_change_indicator = 'D'
        upd_icdtxt_zprps_cd     = 'D'
        n_zprps                 = ls_zprps_n
        o_zprps                 = ls_zprps_o
        upd_zprps               = 'D'
      TABLES
        icdtxt_zprps_cd         = lt_cdtxt.

*   If there is an Event and a Workflow associated with Delete it will be
*   triggered
    COMMIT WORK AND WAIT.

    CLEAR: ls_zprps_o.
  ENDLOOP.

  sy-subrc = 0.

ENDFORM.                    "z_after_save
*&---------------------------------------------------------------------*
*&      Form  Z_BEFORE_DEL
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM z_before_del.

  DATA: lt_cdtxt      TYPE STANDARD TABLE OF cdtxt,
        ls_cdtxt      TYPE cdtxt,
        lv_objectid   TYPE cdobjectv,
        ls_zprps_o    TYPE zprps,
        ls_zprps_n    TYPE zprps,
        lv_objkey     TYPE swo_typeid,
        lt_swcont     TYPE STANDARD TABLE OF swcont,
        ls_qmel      TYPE qmel,
        lv_exists_flg TYPE c.

  LOOP AT extract.

*   Is this record being deleted?
    CHECK: extract+89(1) = 'M'.

*   Is it being referenced in a Notification?
    CLEAR: ls_qmel.
    SELECT *
      UP TO 1 ROWS
      FROM qmel
      INTO ls_qmel
      WHERE zzposid = extract+3(24).
    ENDSELECT.

    CHECK: sy-subrc = 0.

*   Produce an Error
    MESSAGE e000(zs_cross_appl) WITH
    'Cannot delete Project - '
    extract+3(24)
    ' its referenced in Notification - '
    ls_qmel-qmnum.

  ENDLOOP.

  sy-subrc = 0.

ENDFORM.                    "Z_BEFORE_DEL


Business Object

In transaction SWO1 create an Object - ZPRPS.
Enter the following values –

Now, we give the object ‘eyes’ (to respond to the outside world), ‘ears’ (to hear for Event calls), and ‘limbs’ (to do some work) by defining a Key field, a Method, and an Event.

When a record is updated in ZPRPS, a Change Document is written for it. This raises an Event (which is linked to the Business Object in the next step). The Event triggers the Workflow. A Task in the Workflow executes the Method of the Business Object. The Method then updates the Notification.

Key field - Project ID

The following pop-up appears, click Yes.

Enter ZPRPS as the Table, the Primary Key is listed, select this and click Continue.
Click Create on the next screen.



Method - UpdateNotification

Answer No to the following pop-up.

Switch off Dialog, keep Synchronous on and click on Continue.

Select the Method, click Program, the following pop-up appears, click Continue.



Save the program and Back out.


When this Method is called by the Workflow we want it to update the Notification. Add the following lines of code to the Method –

begin_method updatenotification changing container.

DATA: lt_qmel TYPE STANDARD TABLE OF qmel.

* Check that the Project ID is referenced in a Notification
SELECT * FROM qmel
  INTO TABLE lt_qmel
  WHERE zzposid = object-key-projectid.

CHECK: sy-subrc = 0.

* Update the Notification
CALL FUNCTION 'Z_QMEL_UPD' IN UPDATE TASK
  EXPORTING
    it_qmel            = lt_qmel
    iv_zzposid         = object-key-projectid
  EXCEPTIONS
    record_not_updated = 1
    OTHERS             = 2.
IF sy-subrc <> 0.
  exit_return space space space space space.
ENDIF.

end_method.
Create Function Module Z_QMEL_UPD in a new Function Group ZPMWFUPD, with a Short Name - Update Notification PS Data.
FUNCTION z_qmel_upd.
*"----------------------------------------------------------------------
*"*"Update Function Module:
*"
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(IT_QMEL) TYPE  LE_T_DLV_QMEL
*"     VALUE(IV_ZZPOSID) TYPE  ZPS_POSID
*"  EXCEPTIONS
*"      RECORD_NOT_UPDATED
*"----------------------------------------------------------------------

  DATA: wa_qmel     TYPE qmel,
        wa_zprps    TYPE zprps,
        lv_objectid TYPE cdobjectv,
        lt_cdtxt    TYPE STANDARD TABLE OF cdtxt,
        ls_qmel_n   TYPE qmel,
        ls_iloa     TYPE iloa,
        ls_qmih     TYPE qmih,
        ls_qmfe     TYPE qmfe,
        ls_ihpa     TYPE ihpa,
        ls_qmma     TYPE qmma,
        ls_qmsm     TYPE qmsm,
        ls_qmur     TYPE qmur.

* Get all linked Notifications for the Project ID
  SELECT SINGLE *
    FROM zprps
    INTO wa_zprps
    WHERE zzposid = iv_zzposid.

  LOOP AT it_qmel
    INTO wa_qmel.

*   Update table QMEL with the changed values
    UPDATE qmel
      SET zzpost1 = wa_zprps-zzpost1
          zzpstrt = wa_zprps-zzpstrt
      WHERE qmnum = wa_qmel-qmnum.

    IF sy-subrc = 0.
      lv_objectid = wa_qmel-qmnum.

      ls_qmel_n   = wa_qmel.
      ls_qmel_n-zzpost1 = wa_zprps-zzpost1.
      ls_qmel_n-zzpstrt = wa_zprps-zzpstrt.

* Write the Change Document for the Notification
      CALL FUNCTION 'MELDUNG_WRITE_DOCUMENT'
        EXPORTING
          objectid                = lv_objectid
          tcode                   = sy-tcode
          utime                   = sy-timlo
          udate                   = sy-datlo
          username                = sy-uname
          object_change_indicator = 'U'
          n_ihpa                  = ls_ihpa
          o_ihpa                  = ls_ihpa
          n_iloa                  = ls_iloa
          o_iloa                  = ls_iloa
          n_qmel                  = ls_qmel_n
          o_qmel                  = wa_qmel
          upd_qmel                = 'U'
          n_qmfe                  = ls_qmfe
          o_qmfe                  = ls_qmfe
          n_qmih                  = ls_qmih
          o_qmih                  = ls_qmih
          n_qmma                  = ls_qmma
          o_qmma                  = ls_qmma
          n_qmsm                  = ls_qmsm
          o_qmsm                  = ls_qmsm
          n_qmur                  = ls_qmur
          o_qmur                  = ls_qmur
        TABLES
          icdtxt_meldung          = lt_cdtxt.
    ELSE.
      ROLLBACK WORK.
      RAISE record_not_updated.
    ENDIF.

    CLEAR: wa_qmel.
  ENDLOOP.

ENDFUNCTION.

Event - CHANGED



Change the status of the Object to Implemented, (menu - Edit >> Change Release Status >> Object Type >> To implemented).

Then change the status to Released.

Do the same for the Object Type Components (Key field, Method, and Event).


Assign the Change Document Object to an Object Type

Execute transaction SWED.
Click Change, and Continue on the pop-up.

Add a new entry to link the Change Document Object ZPRPS_CD and table ZPRPS so that changes are recorded when table entries change.

Save the entry.

Execute transaction SWEC. Click Continue on the pop-up.

Create a new entry to link the Change Document Object ZPRPS_CD with the Object ZPRPS and Event CHANGED earlier created. Select On Change as the Trigger Event.
When Function Module ZPRPS_CD_WRITE_DOCUMENT is called with the Change Indicator as Update, it will raise Event CHANGED in Object ZPRPS.

Save the entry.

Workflow

The Workflow is triggered when Event CHANGED is raised.
Go to transaction PFTC, select Workflow Template as Task Type, give the Workflow a meaningful name in Task (we will be using Z_NOTIF_UPD), and click Create.
Give a Name - Update Notification Data.

Create a new Container Element - ZPRPS, with reference to Object Type ZPRPS. The Name and Short Descript. is ZPRPS. On the Properties tab, tick Import in Parameter Settings.
Container Element ZPRPS receives the data passed to the Workflow from the Event triggered.


Create a Triggering Event with reference to Object Type ZPRPS and Event CHANGED. Click on the button to activate the Event (the icon turns from a Grey diamond to a Green square).


Select the entry and click the Call Binding Editor button. Now click Generate Automatic Binding to bind &_EVT_CREATOR& with &_WF_INITIATOR& and &_EVT_OBJECT& with &ZPRPS&.



Save the Workflow.

Go to the Basic Data tab and click on Workflow Builder.
Create an Activity step. Name it Update Notification Data. Create a Task - Z_NOTIF_UPD, with the Name - Update Notification Data, enter some appropriate Work item text, Object Category - BO, Object Type - ZPRPS, Method - UPDATENOTIFICATION.
Switch on Background processing since this step will be processed by the system and requires no user intervention.
Go back to the previous screen and click on Define Binding Autom., click Continue to accept the binding between _WI_OBJECT_ID in the Task and &ZPRPS& in the Workflow.

Display/Maintain Event Type Linkages

Execute transaction SWETYPV. Go to Object Type ZPRPS.

Double-click to bring up the next screen.

Extend the PM Notification

We now need to render the fields in ZPRPS in standard transactions IW21, IW22, and IW23. There are 2 parts to it; first we need to do some basic development to create a new sub screen for the fields, then we will look at configuration to assign the newly created screen area to the Notification Type. We will use Notification Type - M1 for our demo.
The fields will be added to table QMEL. Click on Append Structure, name it CI_QMEL and add the fields.


Go to transaction CMOD. Create a Project - ZPMNOTSC, click on Enhancement assignments to assign Enhancement - QQMA0001 to this Project. Save and Activate.

Go back into the Project, click on Components, double-click on Function exit - EXIT_SAPMIWO0_009, and create Include - ZXQQMU08. Add the following lines of code to ZXQQMU08 –
MOVE: viqmel-zzprart TO e_viqmel-zzprart,
      viqmel-zzposid TO e_viqmel-zzposid,
      viqmel-zzpost1 TO e_viqmel-zzpost1,
      viqmel-zzpstrt TO e_viqmel-zzpstrt,
      viqmel-zzflag  TO e_viqmel-zzflag.
Execute transaction SE80, Function Group - XQQM. Create a new screen - 0100. Include the fields in this screen. Fields Project Name (VIQMEL-ZZPOST1) and Project Date (VIQMEL-ZZPSTRT) are output only. Define a new PBO and include the given code in the subroutine –
*&---------------------------------------------------------------------*
*&      Form  DYNMOD_0100_PAI
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------
FORM dynmod_0100_pai .

* If it is display mode then disable all the fields
  CHECK: gv_t365-aktyp NE 'A'.

  LOOP AT SCREEN.
    screen-input = 0.
    MODIFY SCREEN.
  ENDLOOP.

ENDFORM.                    " DYNMOD_0100_PAI
Define a new PAI and include the given code in the subroutine –
*&---------------------------------------------------------------------*
*&      Form  ZZ_CHECK_WBS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM zz_check_wbs .

  IF viqmel-zzposid IS NOT INITIAL.
*   Fetch entries from ZPRPS
    SELECT SINGLE *
      FROM zprps
      INTO CORRESPONDING FIELDS OF viqmel
      WHERE zzprart = viqmel-zzprart AND
            zzposid = viqmel-zzposid.
  ENDIF.

ENDFORM.                    " ZZ_CHECK_WBS

And that is all the coding we require . Now we come to the customization. hGo to SAP Reference IMG in transaction SPRO. Navigate to the menu path - Cross-Application Components >> Notification >> Overview of Notification Type. Execute node - Overview of Notification Type, select Notification Type - M1 Maintenance Request.


Double click on Screen Structure for Extended View.

Double click 10\TAB02 Additional data 1.

Reposition Screen area 2 to include 090 Customer Subscreen (One Screen/Not.Type).

Save the changes.

Create a Notification

Execute transaction SM30 to create an entry in table ZPRPS. Enter the following values and Save the record –
Assignment    - CORRECTIVE,
Project ID       - PROJECT DEMO,
Project Name - DEMO OF A WF UPDATING THIS NOTIFICATION,
Project Date   - 10.03.2010.
Execute transaction IW21 to create a Notification. Our Notification Type is M1.

On the Notification tab enter all the mandatory data (depending on which fields are set to Required in customizing). We will enter a short Description for the Notification - Test. Click on the Risk Assessment tab. Enter Assignment - CORRECTIVE, select the Project ID we created in the above step and hit Enter (this will populate the dependant fields Project Name and Project Date). Feel free to enter a value in Switching Reqd or leave it blank (we will flag it as Y). Save the Notification.

Update the Notification


Switch On Event Trace

Execute transaction SWELS to switch on an Event Trace, click Switch on, Restriction for trace, enter 'Creator' object type - ZPRPS, Save and continue.


Update Table ZPRPS

Execute transaction SM30 and change the associate attributes for the Project ID - PROJECT DEMO to anything you want. We will change the Project Name to ‘HAS THE PROJECT NAME CHANGED?’ and the Project Date to ’10.03.2011’. Save it.

Display Event Trace

Execute transaction SWEL with 'Creator' object type - ZPRPS to see the Event and Workflow triggered for the Change Document.

We can thus confirm that the Workflow has successfully updated the Notification with the new values.
Execute transaction SWELS again and click Switch Off to switch off the Event Trace.

Display Change Documents

Carry out a sanity check just to confirm that the Change Documents were written for table ZPRPS. Execute transaction SE16N, enter the name of the Change Document Header table - CDHDR, and click Enter. Execute it with OBJECTCLAS - ZPRPS_CD, OBJECTID - PROJECT DEMO, UDATE - current date (whichever date you have created and changed the record). We will get the following 2 entries; one for Insert and the other for Update –

Make a note of the Document Numbers (CHANGENR), then query table CDPOS with them. This shows us what exactly changed in the record (from and to values).

Display Notification Changes

Execute transaction IW22/IW23 to see if the data has changed.

We see that both the Project Name and Project Date now have the new values.
View the change logs to the Notification (menu - Extras >> Notification documents >> Changes).

Related Content

Building a Workflow from Scratch
Extending a Business Object
Using the Event Trace

Labels in this area