Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Jocelyn_Dart
Product and Topic Expert
Product and Topic Expert

How do I know I'm ready for this?



Easy ... did you read the first 3 blogs and create the examples mentioned in blogs 2 and 3? If not, here are the links...


Why use ABAP OO with Workflow?


Getting started with ABAP OO for Workflow ... using the IF_WORKFLOW interface


Using ABAP OO methods in Workflow Tasks


If you want to try the exercise in this blog in your own system, you will need an ABAP Class with the IF_WORKFLOW interface, and a system/client (SAPNetWeaver 6.20 minimum) with the workflow environment activated. You also need to have created the "Display Plant" workflow task mentioned in blog number 3.


+Note: As mentioned in the last blog, this blog won't teach you ABAP OO. It won't teach you workflow either, but it should give you enough to get going even if you've never touched workflow before. +


Defining an ABAP OO Event for Workflow


Defining an ABAP OO Event for Workflow is the same as defining any other event for ABAP OO.  To start just go to transaction SE24, enter your class in edit mode, and go to the Events tab.  Give your event a technical name and make sure it is a Public event.



Continuing with the ZCL_PLANT class example, here's an example event SITE_VISIT_PROPOSED.






You can also define event parameters if you wish by selecting the Parameters button. By definition all event parameters are Exporting parameters, i.e. they are exported with the event when the event is raised.

Usually however you don't need to create any event parameters, as the standard Workflow event container (remember that's workflow's name for a data area) adds sufficient standard parameters, such as the user who raised the event, and a local persistent object reference to the ABAP OO class (of course you know all about that because you've read the previous blogs). Of course, you won't see the standard Workflow event container in your class - you'll only see it in the Workflow screens.

Here's an event parameter PROPOSED_VISIT_DATE for the event SITE_VISIT_PROPOSED. I've made the parameter Optional so that later we can look at how to raise an event with or without parameters.





Tip! Don't forget to activate your class afterwards.

Using an ABAP OO Event in Workflow



For anyone who's using Business Object Events with Workflow, you use ABAP OO Events in exactly the same way. The only real difference is you specify category ABAP Class instead of Business Object. For those who haven't done much with events before, in Workflow an event can be used to:


    1. Trigger a multi-step workflow

    2. Terminate a multi-step workflow

    3. Perform special functions on a multi-step workflow, e.g. re-evaluate agents of active work items, cancel and restart with same data

    4. Trigger a single workflow task

    5. Terminate a single workflow task





+Note: The last option - terminate a single workflow task - is particularly useful for asynchronous scenarios. For example if you had a task (it could be background or dialog - i.e. involving a user) that kicked off a database update in background, and then let the raising of an event confirm that the change had been committed to the database. If you did this of course you would leave the Synchronous object method flag off in your background task (this flag was mentioned in blog number 3). +


Triggering a single workflow task with an event isn't a very common practice, simply because most workflows involve more than one step. So usually we want to trigger a multi-step workflow that represents a whole business process. So let's expand our example to a multi-step workflow triggered by an event.


Start by calling transaction SWDD, the Workflow Builder.
Press the Create New Workflow button - the top-left hand button immediately under the text "Workflow Builder".






Then before you go any further, save your new empty workflow. You'll be asked to give it an abbreviation and a name - these are free text and are mainly used when searching for your workflow. Just like our task or an ABAP Class, you'll need to add it to a change request or save it as a Local Object.






This going to be a very simple workflow for now, as we are just going to include our "Display Plant" task in it. So to do that, either single-click on the Undefined step in either the Navigation area or double-click on the Undefined step icon in the center Graphical Model editing area. Select the step type Activity and continue on to the next screen.


The very first field in the Control tab asks for a task id. Search for your "Display Plant" task by using the search help on the Task field. You can search for all tasks that are based on your ABAP Class.







All we need to do now is nominate who should perform this step of our business process. To keep it simple for our example, just make the workflow initiator, i.e. the person who started the process, the Agent of the step. In the Agents section, drop down the Expression field to choose the Workflow initiator.





+Note: Usually we want to calculate who's going to do the work using an agent determination rule but this is just an example after all. +





Press the green check icon Transfer and to graphic to return to the graphical flowchart view. You can save your workflow again at this point if you wish.



We are going to start our workflow with an event and pass in our ZCL_PLANT reference from the event, so we need to allow the new ZCL_PLANT container element to be imported. On the left hand side, under the Navigation area, use the dropdown to swap the bottom left hand area to the Workflow Container display. Double-click on the new ZCL_PLANT container element, and on the Properties tab check the Import flag.






So having completed our mini how-to-create-a-workflow exercise we now want to add the SITE_VISIT_PROPOSED event as the triggering event of the workflow. At the top of the screen press the Basic Data hat icon. On the Version-Independent tab, choose the sub-tab Start Events. Add a row and enter category CL, then Object Type = your ABAP Class, and then Event of the object = SITE_VISIT_PROPOSED.





+Tip! It's a good idea to use the dropdown help for all of these fields to avoid typing errors. +



You can see the event row starts with an A, B, and C columns. B stands for Binding.
We need to create the binding (mapping) between the event container and the workflow container to pass across the instance of our ABAP Class and the person who raised the event. Just click on the Binding icon and the binding will be generated for you.






Remember the A, B, and C columns? A stands for Activate. Click on the activate icon until the event activation icon turns green. Now use the back arrow icon to return to the graphical flowchart display and use the Activate (lit match) icon at the top of the screen to activate the workflow. Check the status of your workflow is Active, Saved in the Information Area in the top left hand window pane.


So now you have a workflow that's linked to a triggering event of your ABAP Class!  If you want to test it, use transaction SWUE to generate the event, or just wait until you have completed the next section on raising events.  You should see a new "Display Plant" work item added to the Workflow section of your SAP inbox (transaction SBWP).

Raising an ABAP OO Event for Workflow


Now of course we would not usually raise the event manually, normally an application - a transaction, a BAPI, a function module, a report, a WebDynpro, etc. - would actually trigger the event using code. 



Raising Business Object events usually involved a traditional function module call - such as SAP_WAPI_CREATE_EVENT. Raising ABAP OO events, not unsurprisingly, uses an object-oriented approach - instead of a function module call, a method call is used to raise the event.


The provided SAP ABAP Class that handles the raising of workflow events is CL_SWF_EVT_EVENT. This class contains two Static, Public methods for raising ABAP OO events for Workflow:


    1. RAISE - for raising an event immediately

    2. RAISE_IN_UPDATE_TASK - for raising an event in the update task of a Logical Unit of Work





Here's some example code to raise our SITE_VISIT_PROPOSED event using the RAISE method - without any parameters.


DATA:
  ls_zcl_plant_key TYPE werks,


  lv_objtype       TYPE sibftypeid,
  lv_event         TYPE sibfevent,
  lv_objkey        TYPE sibfinstid.


lv_objtype = 'ZCL_PLANT'.
lv_event   = 'SITE_VISIT_PROPOSED'.


  • Set up the LPOR instance id
ls_zcl_plant_key-werks = '1000'.
MOVE ls_zcl_plant_key TO lv_objkey.


  • Raise the event
TRY.
    CALL METHOD cl_swf_evt_event=>raise
      EXPORTING
        im_objcateg        = cl_swf_evt_event=>mc_objcateg_cl
        im_objtype         = lv_objtype
        im_event           = lv_event
        im_objkey          = lv_objkey
  •       IM_EVENT_CONTAINER =
        .
  CATCH cx_swf_evt_invalid_objtype .
  CATCH cx_swf_evt_invalid_event .
ENDTRY.


COMMIT WORK.



Tip! Just as for Business Object events, the <b>COMMIT WORK</b> statement is crucial when raising a Workflow event - without this the event will not be raised.



Check the event was raised correctly by turning on the event log (using transaction SWELS), and executing the event log. If your event was raised correctly you should have a new line in the event log that looks something like this:






The green light icon shows that a workflow was started as a result of this event.


The above code is fine for most events that just use the standard Workflow event container and have no specific parameters. Of course if you want to pass specific parameters you need a little extra code to:

  • Instantiate an empty event container

  • Add your event parameter name/value pairs to the event container

  • Raise the event passing the prepared event container




+Note: You don't need to worry about filling any of the standard event container parameters such as the event creator - Workflow will do that as part of raising the event. +


DATA:
  ls_zcl_plant_key    TYPE werks,


  lv_objtype          TYPE sibftypeid,
  lv_event            TYPE sibfevent,
  lv_objkey           TYPE sibfinstid,


  lr_event_parameters TYPE REF TO if_swf_ifs_parameter_container,
  lv_param_name       TYPE swfdname,


  lv_visit_date       TYPE datum.


lv_objtype = 'ZCL_PLANT'.
lv_event   = 'SITE_VISIT_PROPOSED'.


  1. Set up the LPOR instance id
ls_zcl_plant_key-werks = '1000'.
MOVE ls_zcl_plant_key TO lv_objkey.


  1. Instantiate an empty event container
CALL METHOD cl_swf_evt_event=>get_event_container
  EXPORTING
    im_objcateg  = cl_swf_evt_event=>mc_objcateg_cl
    im_objtype   = lv_objtype
    im_event     = lv_event
  RECEIVING
    re_reference = lr_event_parameters.


  1. Set up the name/value pair to be added to the container
lv_param_name = 'PROPOSED_VISIT_DATE'.
lv_visit_date = sy-datum + 7.


  1. Add the name/value pair to the event conainer
TRY.
    CALL METHOD lr_event_parameters->set
      EXPORTING
        name       = lv_param_name
        value      = lv_visit_date
  1.       UNIT       =
  2.     IMPORTING
  3.       RETURNCODE =
    .
  CATCH cx_swf_cnt_cont_access_denied .
  CATCH cx_swf_cnt_elem_access_denied .
  CATCH cx_swf_cnt_elem_not_found .
  CATCH cx_swf_cnt_elem_type_conflict .
  CATCH cx_swf_cnt_unit_type_conflict .
  CATCH cx_swf_cnt_elem_def_invalid .
  CATCH cx_swf_cnt_container .
ENDTRY.


  1. Raise the event passing the prepared event container
TRY.
    CALL METHOD cl_swf_evt_event=>raise
      EXPORTING
        im_objcateg        = cl_swf_evt_event=>mc_objcateg_cl
        im_objtype         = lv_objtype
        im_event           = lv_event
        im_objkey          = lv_objkey
        im_event_container = lr_event_parameters.
  CATCH cx_swf_evt_invalid_objtype .
  CATCH cx_swf_evt_invalid_event .
ENDTRY.


COMMIT WORK.


If you want to check that your proposed visit date was passed to the workflow, you'll need to create a new workflow container element to hold the proposed visit date, adjust the event to workflow binding, and re-activate your workflow before testing it.


What about Configuration options for Workflow Events?



Those of you who are familiar with Business Object events in R/3 and ECC are also aware that often no code at all is needed in these systems to raise an event for Workflow - you just need to complete the configuration in one of the many event configuration tables. These tables are provided by many different modules within the application, such as HR, SD message control, status management, and change documents. As of ECC6, most of these configuration tables unfortunately do not yet support ABAP OO events via configuration, with one notable exception - change documents.


In transaction SWEC, change document event configuration, you can specify the object category ABAP Class when specifying an event. The only difficulty you may have is matching the key of the change document to the key of your ABAP Class. You can overcome this conversion issue by coding your own conversion routine as a function module.


This function module can be called any valid name (within the customer namespace) but must have the same interface as the template function module SWE_CD_TEMPLATE_OBJKEY_FB_2. All you have to do in this function module is use the data in the change document header/items to build the local persistent object reference for your workflow-ready ABAP Class.


You then add the function module to the Function module field in the relevant row of transaction SWED - which defines the change document object relationship to an object type.


Hopefully some of the other configuration options will catch up soon and allow for ABAP OO event configuration also.


Where to now?


The next blog will look at fleshing out our workflow by using ABAP OO attributes to add meaningful text, descriptions, and additional parameters to each part of our workflow.
32 Comments