cancel
Showing results for 
Search instead for 
Did you mean: 

Assign value to one filed of structure in workflow container element

Former Member
0 Kudos

Hi ,

I have a structure in my workflow container.

I need to assign a constant value say '03' to the one field of that structure.

I tried to use container operation. But it allow me to assign the value of whole structure, not a particular field of that structure. Please let me know if this possible?

Thanks

Minal

Accepted Solutions (1)

Accepted Solutions (1)

bpawanchand
Active Contributor
0 Kudos

NO it is not possible to assign a single field value of structure in the container operation , what all you can do is if you want to access single record in the multi-line container element ,into a structre of compatible type you can acheive this check this [wiki|https://www.sdn.sap.com/irj/scn/wiki?path=/display/abap/accessingSingleEntryfromMulti-line+Element]

But is is not possible to access a single field from a structure in the container operation it is better you modify in the business object method and return it to the workflow container.

Answers (6)

Answers (6)

Former Member
0 Kudos

Hi,

you would need something like:

With an expression like this:

%YCL_SI_WF_TOOLBOX.ASSIGN_COMPONENT_OF_STRUCTURE(IV_FLOWITEM_ID= &_Workitem.WorkitemID& ;IV_CONTAINER_ELEMENT= 'RBKP' ;IV_COMPONENT= 'BUKRS' ;IV_VALUE= '0001' )%

Sadly, but I didn't find any way to retrieve the current flowitem from the workflow-runtime during a container operation (which otherwise is provided when running a BOR object method in a task).

This is, why you need to pass the current flowItem ID to the method, as well.

I'm using the class-based WAPI interfaces, which is running nicely. The function calls to the WAPI do basically work the same, as the retrieve an object instance of the same.

I did paste the coding in the screenshot, as otherwise the nice colors are gone since the SCN isn't supporting the ABAP syntax highlightning anymore 😞

Take care

   Florin

pokrakam
Active Contributor
0 Kudos

Hi Florin,

I like the OO approach, but why the long way around?

Why not go directly to using a method with parameter I_STRUCT, I_COMPONENT, I_NEW_VALUE and return R_STRUCT?

Then work with the data dictionary instead of WF containers. In the step we export the structure and receive the updated version back. Bonus: the code doesn't even need anything WF-related and we have kept WF and ABAP completely separate.

Simples, no?

Regards,

Mike

Former Member
0 Kudos

Hello Mike,

yes, I was trying this shortcut on the first place, too, but you can't do a generic version then, as the  RETURNING ... TYPE ANY  declaration is not allowed.

You would need a method-version for each structure that you'd be using, e.g.  method assign_component_of_RBKP( ... ) returning es_rbkp TYPE RBKP.

A workaround to use an abstract character-based return type (e.g. TEXT255) and assigning this to a structure has "some" limitations.

Then, a functional method that could be used within a container operation (to avoid an excess background step) cannot have a changing parameter at the same time (which basically could solve the problem).

This is, why I needed to make a direct access to the workflow container. Basically, it's the concept of a changing parameter, where the given reference is a name to a variable that the called method needs to pick for itself.

And yes ... 🙂  it's a long way around...

Best wishes

   Florin

pokrakam
Active Contributor
0 Kudos

Hi Florin,

Interesting, I wasn't aware RETURNING ... TYPE ANY is not permitted. It doesn't even like CLIKE. Learned something new...

Probably haven't stumbled on this one because I tend to use references in these scenarios. But workflow doesn't like them. I still don't like writing into containers unless I have to, so a possible compromise might be a 'dereferencing class', just for workflow, with a single-line method for each data type. The expression is a little bit cumbersome, but fairly understandable:

%zcl_deref=>get_sflight( zcl_assign_comp( i_struct=&FLIGHT& i_comp='FLDATE' i_val=&NEW_DATE& ) )%

Anyhow, it depends on the OPs requirement. Most likely it the value comes from a task anyway, in which case a programmed binding might also be an alternative.

Regards,

Mike

Former Member
0 Kudos

Well,

interesting enough, that one  can  assign a value to a component of a structure through the Binding of a task, but you can't do the same using the container operation.

So here, a programmed binding is ... "the long way around" 🙂

With the very best wishes and greetings

   Florin

pokrakam
Active Contributor
0 Kudos

Indeed! So theoretically it should be a small fix to enable it in a container operation...

Former Member
0 Kudos

yeah, thought so, too...

But I think, the missing returning-type-ANY is still a problem... or probably was the problem, not to offer it.

The calls to the container-operations in BOR or OO-context all use the changed values as either an importing element or as a changing element.

So the solution would be, that there's a container operation available, which is a procedural call and not a functional method. Something like "Execute method", instead of "Assign value"...

Thinking of the Workflow Customer connection 2016 ... if there is one 🙂

pokrakam
Active Contributor
0 Kudos

Florin Wach wrote:


So the solution would be, that there's a container operation available, which is a procedural call and not a functional method. Something like "Execute method", instead of "Assign value"...

er... isn't that called a background task? 🙂

Former Member
0 Kudos

Hi,

here are GET and SET FMs to change any container element also structure and table elements.

You can get the structure element, change the value of any field of the structure and save this structure to the workitem container using the set FM.

I'm using these FMs without any problems/side effects.

GET:


FUNCTION zget_wi_container_element.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     REFERENCE(IV_WITEM_ID) TYPE  SWW_WIID
*"     REFERENCE(IV_ELEMENT_NAME) TYPE  SWC_EDITEL
*"  EXPORTING
*"     REFERENCE(EV_ELEMENT) TYPE  DATA
*"     REFERENCE(EV_RETURN_CODE) TYPE  SYSUBRC
*"----------------------------------------------------------------------

  DATA lt_wi_container  TYPE TABLE OF swcont.
  DATA: lo_container_handle TYPE REF TO if_swf_cnt_container.

*    read workitem container
  CALL FUNCTION 'SWW_WI_CONTAINER_READ'
    EXPORTING
      wi_id                    = iv_witem_id
    IMPORTING
      wi_container_handle      = lo_container_handle
    TABLES
      wi_container             = lt_wi_container
* CHANGING
*     WI_HEADER                =
    EXCEPTIONS
      container_does_not_exist = 1
      read_failed              = 2
      OTHERS                   = 3.
  IF sy-subrc = 0.
    TRY .
        lo_container_handle->if_swf_ifs_parameter_container~get(
          EXPORTING
            name                          = iv_element_name    " Name der zu Komponente, deren Wert gelesen werden soll
          IMPORTING
            value                         = ev_element   " Kopie des aktuellen Wertes der Komponente
            returncode                    = ev_return_code    " Aufgetretener Fehler (falls abgefragt -> kein RAISE)
        ).

      CATCH cx_swf_cnt_container.
        ev_return_code = 1.
    ENDTRY.
  ELSE.
    ev_return_code = sy-subrc.
  ENDIF.

ENDFUNCTION.


SET:


FUNCTION zset_wi_container_element.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     REFERENCE(IV_WITEM_ID) TYPE  SWW_WIID
*"     REFERENCE(IV_ELEMENT_NAME) TYPE  SWC_EDITEL
*"     REFERENCE(IV_ELEMENT) TYPE  DATA
*"     REFERENCE(IV_MERGE_OLD_ELEMENT) TYPE  XFELD DEFAULT ABAP_TRUE
*"  EXPORTING
*"     REFERENCE(EV_RETURN_CODE) TYPE  SYSUBRC
*"----------------------------------------------------------------------

  DATA lt_wi_container  TYPE TABLE OF swcont.
  DATA: lo_container_handle  TYPE REF TO if_swf_cnt_container.
  DATA lo_exception  TYPE REF TO  cx_swf_cnt_container.

*    read workitem container
  CALL FUNCTION 'SWW_WI_CONTAINER_READ'
    EXPORTING
      wi_id                    = iv_witem_id
    IMPORTING
      wi_container_handle      = lo_container_handle
    TABLES
      wi_container             = lt_wi_container
* CHANGING
*     WI_HEADER                =
    EXCEPTIONS
      container_does_not_exist = 1
      read_failed              = 2
      OTHERS                   = 3.
  IF sy-subrc = 0.
    TRY .
        lo_container_handle->if_swf_ifs_parameter_container~set(
          EXPORTING
            name                          = iv_element_name    " Name des Parametes, deren Wert gesetzt werden soll
            value                         = iv_element   " Wert
*          unit                          =     " Einheit
          IMPORTING
            returncode                    = ev_return_code    " Aufgetretener Fehler (falls abgefragt -> kein RAISE)
        ).
      CATCH cx_swf_cnt_container.
        ev_return_code = 1.
        RETURN.
    ENDTRY.

    IF ev_return_code EQ 0.

      CALL FUNCTION 'SWW_WI_CONTAINER_MODIFY'
        EXPORTING
          wi_id               = iv_witem_id
*         DO_COMMIT           = 'X'
          merge_old_container = iv_merge_old_element
          wi_container_handle = lo_container_handle
        IMPORTING
          exception           = lo_exception.
      IF lo_exception IS NOT INITIAL. "Fehler
        ev_return_code = 2.
      ENDIF.
    ENDIF.
  ELSE.
    ev_return_code = sy-subrc.
  ENDIF.

ENDFUNCTION.

pokrakam
Active Contributor
0 Kudos

As Sue explained, and as has been posted hundreds of times in these forums, using the API (SAP_WAPI_* functions) is easier and supported by SAP.

It is irrelevant that you use your code "without any problems/side effects", I have also modified code in production without problems, but that doesn't mean I recommend everyone should do it.

What would be a far more interesting post is to explain why you suggest people not to use the API...

Former Member
0 Kudos

That piece of code is not solving the problem, as it doesn't assign a component of a structure to the workflow container.

Former Member
0 Kudos

Hi,


you can do this using the funciton modules 'SWW_WI_CONTAINER_READ' and  'SWW_WI_CONTAINER_MODIFY'. The values of structure elements in the container table of type  swcont have the same element name but different  tab_index. The tab_index has the same index as the structure type description.


With the following function module is it possible to change structure elements within a workflow container of a workitem.



FUNCTION zmodify_wi_container_element.

*"----------------------------------------------------------------------

*"*"Lokale Schnittstelle:

*"  IMPORTING

*"     REFERENCE(IV_WITEM_ID) TYPE  SWW_WIID

*"     REFERENCE(IV_ELEMENT_NAME) TYPE  SWC_EDITEL

*"     REFERENCE(IS_ELEMENT) TYPE  DATA

*"     REFERENCE(IV_MERGE_OLD_ELEMENT) TYPE  XFELD DEFAULT ABAP_TRUE

*"----------------------------------------------------------------------

   DATA lt_wi_container  TYPE TABLE OF swcont.

   DATA: lr_rtti_struc TYPE REF TO cl_abap_structdescr.

   DATA: lt_comp       TYPE cl_abap_structdescr=>component_table.

   DATA ls_struc                         TYPE REF TO data.

   FIELD-SYMBOLS <fs_cnt_element>            TYPE any.

   DATA: ls_comp       LIKE LINE OF lt_comp.

   DATA lv_index TYPE sy-index.

   FIELD-SYMBOLS <fs_field>              TYPE any.

   DATA ls_wi_container  TYPE swcont.

   DATA lv_element_name  TYPE swc_editel.

*  Containerelement immer in Großbuchstaben

   lv_element_name = to_upper( iv_element_name ) .

*    read workitem container

   CALL FUNCTION 'SWW_WI_CONTAINER_READ'

     EXPORTING

       wi_id                    = iv_witem_id

* IMPORTING

*     WI_CONTAINER_HANDLE      =

     TABLES

       wi_container             = lt_wi_container

* CHANGING

*     WI_HEADER                =

     EXCEPTIONS

       container_does_not_exist = 1

       read_failed              = 2

       OTHERS                   = 3.

   IF sy-subrc = 0.

*  DELETE lt_wi_container  WHERE element NE lv_element_name.  "

     "Datentyp

     lr_rtti_struc ?= cl_abap_structdescr=>describe_by_data( is_element ). " Get the description of the data

     lt_comp = lr_rtti_struc->get_components( ). "Get the fields of the structure

     CREATE DATA ls_struc LIKE is_element.

     ASSIGN ls_struc->* TO <fs_cnt_element>.

     <fs_cnt_element> = is_element.

     "Felder der Struktur prozessieren

     LOOP AT lt_comp INTO ls_comp.

       lv_index = sy-tabix.

       ASSIGN COMPONENT ls_comp-name OF STRUCTURE <fs_cnt_element> TO <fs_field>.

       "Wert setzen nur wenn nicht initial oder wenn die Struktur ersetzt werden soll

       IF <fs_field> IS NOT INITIAL OR iv_merge_old_element EQ abap_false.

         READ TABLE lt_wi_container WITH KEY element = lv_element_name tab_index = lv_index INTO ls_wi_container.

         IF sy-subrc <> 0.

           ls_wi_container-element = lv_element_name.

           ls_wi_container-tab_index = lv_index.

         ENDIF.

         "Wert setzen

         ls_wi_container-value = <fs_field>.

         APPEND  ls_wi_container TO lt_wi_container.

       ENDIF.

     ENDLOOP.

*    modify workitem container

     CALL FUNCTION 'SWW_WI_CONTAINER_MODIFY'

       EXPORTING

         wi_id        = iv_witem_id

*       DO_COMMIT    = 'X'

*       DELETE_OLD_CONTAINER       = ' '

*       MERGE_OLD_CONTAINER        = 'X'

*       WI_CONTAINER_HANDLE        =

*  IMPORTING

*       EXCEPTION    =

       TABLES

         wi_container = lt_wi_container

*  CHANGING

*       WI_HEADER    =

       .

   ENDIF.

ENDFUNCTION.

keohanster
Active Contributor
0 Kudos

Actually, SAP_WAPI functions are a better way to read and put values to the workflow container.

Former Member
0 Kudos

Hi Minal,

There is no direct possible way to do. You need to create activity(Method) for the same. Keep importing and exporting parameter as the strucrure to be filled up in the Method.

Thanks,

Jyoti

surjith_kumar
Active Contributor
0 Kudos

Hi,

It NOT possible to assign structure to container operation.

If you want to use it.

1) Create your own custom structure

2) call it inside the workflow container, by giving the structure name in "ABAP Dict. Table Type"

3) Then from method you have fetch the value and assign it to the workflow container (structure).You have to give correct binding.

4) Then use it in the workfow

Regards,

Surjith

Former Member
0 Kudos

Hi ,

What you need to do is - Create a custom method in your business object . There declare a export parameter as the structure you have mentioned and assign your value that you wants to assign say '03' to the perticular field of that structure .

Now in binding you can pass that structure to workflow container staructure .

Hope this helps .

Rgds

Prabhudutta