Regelmäßig bekomme ich die Anfrage, wie unbearbeitete Inbox Items (offene Dialog Workitems) ermittelt und weitergeleitet werden können. Das kann zum Beispiel erforderlich sein, wenn eine Führungskraft ein Unternehmen verlässt und vorher nicht alle Workitems in der Inbox abgearbeitet hat. Diese sollen daher dann meistens der neuen Führungskraft zugewiesen werden. Es gibt verschiedene Wege diese Workitems zu ermitteln und weiterzuleiten.
Mit dem Fuba SAP_WAPI_CREATE_WORKLIST kann man sich den Inbox-Content zu einem User anzeigen lassen (siehe hier), meist scheitert das aber an den Berechtigungen auf der Produktion. Ist aber ein praktisches Mittel, um sich einen schnellen Überblick über die Inbox eines Users zu machen.
Geht es z.B. speziell nur um Abwesenheitsantrage, könnte man in der PTARQ schauen. Mit dem Report “Belege anzeigen” kann man dann auf die Führungskraft filtern, dazu einfach den Radiobutton “Nächsten Bearbeiter” auswählen und die Personalnummer der Führungskraft eingeben. Hier gibt es einen direkten Absprung in das Workflow-Log und man kann sich die Workitem ID des Dialogschritts über Springen → Technische Workitem-Anzeige holen, um damit in der SWIA weiterleiten zu können.
Ich nutze für diese Aufgabe aber vorwiegend die SWI5. Typ US auswählen + die User ID und weiter unten auf “Zu erledigende Workitems” stellen. Optional noch auf einen speziellen Aufgabentyp filtern.
Als Ergebnis erhält man eine Liste mit Aufgaben IDs und zugehörigen Workitem IDs. Und da es direkt die Workitem ID des Dialogschritts ist, kann man damit direkt in der SWIA selektieren und das Workitem weiterleiten.
Recently, I had the task of assigning a workflow decision step to some users that were customized in a Z-Table. Normally I would have done this, by creating a container element “Actors”, a task that calls a method to return these Actors and use these Actors in the decision step. But this time I tried a custom AC Rule for the first time and I must say it was much easier than expected.
To begin, simply create a function module. The function module only needs two table parameters, AC_CONTAINER and ACTOR_TAB. They can be copied from RH_GET_ACTORS or GM_GET_RESP_FROM_INTERNAL. There you can also check, how to access the AC_CONTAINER table, if you need any input values from the WF. In my case, I just had to read the Z-Table and return the result via ACTOR_TAB.
SELECT * FROM ztable INTO TABLE @DATA(lt_table).
LOOP at lt_table INTO DATA(ls_table).
"you can also check if the provided user exists by using function module 'SUSR_USER_CHECK_EXISTENCE'
APPEND VALUE #( otype = 'US' objid = ls_table-userid ) TO actor_tab.
ENDLOOP.
IF lines( actor_tab ) = 0.
RAISE nobody_found.
ENDIF.
Then simply go to tcode PFAC, create a rule, choose Type F, provide the function module and check the flag box at the end.
In the PFAC transaction, you can also simulate the rule resolution.
If everything works fine, add the new created rule to the decision step.
Since my workflow was already in this state, I had to find another way, and found it with transaction code SWWL. Simply find the unique Identification of the top level workitem via t-code SWIA and then use it in SWWL. When running the report, you will first get a list, then simply select the result items you want to delete and hit the trash icon, or restart the selection and check the flag for Delete immediately.
If you have connected any workflows to a pernr via BUS1065 (like it is described here), you can receive all related workflows/workitems related to this pernr via the following code:
NEW cl_def_im_com_bsp_workflow( )->if_ex_com_bsp_workflow~read_workitems_for_object( EXPORTING iv_swo_objtype = 'BUS1065'
iv_swo_objkey = CONV #( lv_pernr )
IMPORTING et_workitems = DATA(lt_workitems) ).
LOOP AT lt_workitems ASSIGNING FIELD-SYMBOL(<workitems>).
"If you are only interested in specific workflows, you could filter here
"WHERE wi_rh_task = 'WSxxxxxxxx'
"AND wi_stat = 'STARTED'.
NEW /iwwrk/cl_wf_read_workitem( <workitems>-wi_id )->get_wi_container( IMPORTING et_wi_container = DATA(lt_wi_container) ).
" access container items via lt_wi_container[ element = 'IV_PERNR' ]-value
ENDLOOP.
To attach your own workflow in this overview, you have to add the Task TS51900010 to your workflow and pass over the employee number to the Business Object “Employee” (BUS1065)
The Function Module SAP_WAPI_START_WORKFLOW uses RH_TASK_START_CHECK to check, if the calling user is allowed to start the Workflow. In it RH_TASKS_TO_START is used to read the WF and Task IDs which the user is allowed to call. But it uses a buffer and if you just did some changes to the Workflow Classification, i.e. setting it to General Task,
it can be that this check will continue to fail as it is reading old data from the buffer.
You will receive an error message from Message Class WZ: You are not one of the possible agents of task ‘&1’
I had this problem sometimes when transporting objects to the next system, but until now I could not figure out when it happens and when not.
Luckily the solution is pretty simple, just call T-Code SWU_OBUF and do a buffer refresh/synchronization. Rob Dielemans has explained the cause very well here.
If you want to use the decision note / action comment of a Workitem in a mail step, you have to write a method to read the comment and then pass it to the mail step. To do this, I always create a method in my Workflow helper class called READ_DECISION_NOTE with the following parameters:
For the importing parameter, you must store the Workitem ID of your Decision Step in you Workflow Container, by creating a Container Element like DecisionWIID of type SWW_WIID and fill it with the Workitem ID of your decision step. Then use it later for calling your method READ_DECISION_NOTE.
Regarding the exporting parameter; If you want to send a mail via class cl_cbs you’re a fine reading the comment as string. But if you want to use the default workflow mail step, and you are expecting comments with more than >255 characters, you will need the comment as SOLI_TAB.
If you take a look at the decision Workitem, you will properly find the Attribute ACTION_COMMENTS, which is of type SWC_VALUE and is of type char with length 255. But this is only the case, if the entered text has less than < 255 characters.
If the user entered a text with more than 255 characters, the text is split and there are more elements named with ACTION_COMMENTS_1, ACTION_COMMENTS_2 etc. (Note 3017539)
There is the function module SAP_WAPI_READ_CONTAINER to read Workitems. As input for the function module, you need the Workitem ID from the decision step. You will then find the ACTION_COMMENTS in the simple_container table.
DATA: return_code TYPE sy-subrc,
simple_container TYPE TABLE OF swr_cont,
message_lines TYPE TABLE OF swr_messag,
message_struct TYPE TABLE OF swr_mstruc,
subcontainer_bor_objects TYPE TABLE OF swr_cont,
subcontainer_all_objects TYPE TABLE OF swr_cont,
object_content TYPE TABLE OF solisti1.
" Read the work item container from the work item ID
CALL FUNCTION 'SAP_WAPI_READ_CONTAINER'
EXPORTING
workitem_id = iv_wiid
IMPORTING
return_code = return_code
TABLES
simple_container = simple_container
message_lines = message_lines
message_struct = message_struct
subcontainer_bor_objects = subcontainer_bor_objects
subcontainer_all_objects = subcontainer_all_objects.
TRY.
DATA(text) = simple_container[ element = 'ACTION_COMMENTS' ]-value.
CATCH cx_sy_itab_line_not_found.
" Check for ACTION_COMMENTS_1 etc.
" or follow the approach below
ENDTRY.
The comment is also added as SOFM-Object (SAP-Office-Document) to the Workitem. Just check the table subcontainer_all_objects, which is also returned by the previous function module, for attribute _ATTACH_COMMENT_OBJECTS (or _ATTACH_OBJECTS or DECISION_NOTE or _DECISION_COMMENT). With function module SO_DOCUMENT_READ_API1 you can then get the actual comment.
" Read the _ATTACH_COMMENT_OBJECTS element
" There can be more than one comment, just take the last one
LOOP AT subcontainer_all_objects INTO DATA(comment_object) WHERE element = '_ATTACH_COMMENT_OBJECTS'.
ENDLOOP.
CHECK comment_object-value IS NOT INITIAL.
" Read the SOFM Document
CALL FUNCTION 'SO_DOCUMENT_READ_API1'
EXPORTING
document_id = CONV so_entryid( comment_object-value )
TABLES
object_content = object_content
EXCEPTIONS
OTHERS = 1.
et_decision_note = object_content.
* Or create a single string
* LOOP AT object_content INTO DATA(lv_soli).
* CONCATENATE text lv_soli-line INTO text.
* ENDLOOP.
This SOLI_TAB can be passed to a default mail step and will keep line breaks etc.
Update 02.06.2026: A shorter approach can be the following.
If you forward a workitem manually from the MyInbox or via function module SAP_WAPI_FORWARD_WORKITEM, the function module SWW_WI_FORWARD will be called. There the SAP implemented a BAdI call of the BAdI WF_WI_FORWARD.
BAdI WF_WI_FORWARD
The BAdI provides a method to add additional checks, when forwarding a workitem. I will use it, to send notification mails.
BAdI Filter
Create your own BAdI implementation and add a task id as filter. In my case it’s the task TS21500003 of the leave request approval workflow. Now your implementation will only be called, if this specific workitem is forwarded. Now we implement the method CHECK_BEFORE_FORWARD. The method has enough parameters to get all necessary information to enrich the mail text.
First the workitem container is read out of the context. There we get the _WI_OBJECT_ID element, which contains the request object reference. With this information we are able to get the current request object out of the workflow. I pass this into antother class where I already have a mail sending implementation.
METHOD if_ex_wf_wi_workitem~check_before_forward.
*---------------------------------------------------------------------------------*
* This BAdI implementation is used to send an info mail when a workitem is forwarded.
*---------------------------------------------------------------------------------*
TRY.
"Get workitem container and requestId
DATA(container) = im_workitem_context->get_wi_container( ).
container->get_value_ref( EXPORTING name = |_WI_OBJECT_ID|
IMPORTING value_ref = DATA(lr_req_id) ).
ASSIGN lr_req_id->* TO FIELD-SYMBOL(<lpor>).
"Get current request object
DATA(lo_req) = NEW cl_pt_req_wf_attribs( )->bi_persistent~find_by_lpor( lpor = <lpor> ).
"Send an info mail to each new agent (should be only one)
LOOP AT im_table_new_agents INTO DATA(new_agent).
zcl_hcm_leave_request_assist=>send_mail( io_req = CAST cl_pt_req_wf_attribs( lo_req )
iv_tdname = mc_mailtext
iv_pernr = cl_hcmfab_employee_api=>get_instance( )->get_employeenumber_from_user( iv_user = new_agent-objid ) ).
ENDLOOP.
CATCH cx_hcmfab_common.
CATCH cx_swf_cnt_elem_not_found.
CATCH cx_swf_cnt_container.
"In error case, do nothing. The workitem should still be forwarded.
RETURN.
ENDTRY.
"Write Info to WF Log
MESSAGE s001(00) WITH |Forward: Mail { mc_mailtext }| INTO DATA(lv_message).
im_workitem_context->set_message_to_log( im_function = CONV #( lv_message ) "max char30
im_message = VALUE #( msgid = sy-msgid
msgty = sy-msgty
msgno = sy-msgno
msgv1 = sy-msgv1 ) ).
COMMIT WORK.
ENDMETHOD.
At the end I’m writing a little notification in the workflow log. The workitem context provides the method set_message_to_log for this. The log will look like this.
But to add a message in general, only the workitem context is needed. If you got the context, just use method set_message_to_log.
* context type: im_workitem_context TYPE REF TO if_wapi_workitem_context
" text in im_function will be displayed in workitem log (max char30),
" message in im_message will give further information when clicking on the traffic light (max char 70).
im_workitem_context->set_message_to_log( im_function = |Forward: Mail { var }|
im_message = VALUE #( msgid = '00'
msgty = 'S'
msgno = '000'
msgv1 = |var 1|
msgv2 = |var 2| ) ).
* In some cases "COMMIT WORK" is needed.
If you want to copy the standard workflow of the leave request approval process (WS12300111) and are adding another approval step (or you just want to add an escalation where you set the approve workitem to obsolete and create a new approval step for the next approver) you have to implement the following BAdI. In detail you only have to add the new step ID in the filter, else the approver will not see any approval or reject buttons in his inbox. See details here.
BAdI: /IWWRK/BADI_WF_BEFORE_UPD_IB
Default implementation: HCMFAB_LEAVE_APPROVAL_INBOXDefault Workflows and Step ID’sAdd your custom workflow and the custom approval step id in your own BAdI implementation
As second step you have to add the Workflow in the customizing. You’ll find further information here.
SM30 View /IWWRK/V_WFSTEP.Add the Workflow with Approval StepIdAdd the Approve and Reject Buttons