Monday, August 27, 2018

CIF PM Orders (Instandhaltung, CS Order, Instandhaltungsaufträge)

CIF Outbound in ERP: Function module CIF_PMORD_SEND
CIF Inbound in APO: Function module /SAPAPO/CIF_MNT_INBOUND

Wednesday, April 4, 2018

Friday, February 2, 2018

Compress data with ABAP (ZIP, GZIP)

    DATA lv_string TYPE string.
    DATA lv_xstring TYPE xstring.


    " gzip 
    cl_abap_gzip=>compress_text(
      EXPORTING text_in  lv_string
      IMPORTING gzip_out lv_xstring
    ).



    " unzip 
    cl_abap_gzip=>decompress_text(
      EXPORTING gzip_in  lv_xstring
      IMPORTING text_out lv_string
    ).



See also methods COMPRESS_BINARY and DECOMPRESS_BINARY of cl_abap_gzip.

Robust ABAP to JSON serializer

SAP provides some classes to serialize and deserialize arbitrary ABAP variables. Unfortunately all of them have some disadvantages. The classes are often to complex to use. One method call should be enough to serialize. It is not necessary to call constructor and multiple methods. But a real problem of most classes is, that they just dump for some data constallations, e.g. if the variable contains json Control character like [, ], { or }. Even the colon can cause Problems.


Since the implementaion is easy, we made our own. I am sure that also our own implementation will have bugs... but we can correct them quickly, what is not possible with the SAP's standard classes


class ZCL_JSO_SERIAL definition
  public
  create public .

public section.
  types:
    BEGIN OF yt_s_component_value .
    TYPES   name TYPE string.
    TYPES   value TYPE string.
    TYPES END OF yt_s_component_value .
  types:
    yt_t_component_value TYPE SORTED TABLE OF yt_s_component_value WITH UNIQUE KEY name .

  class-methods SERIALIZE
    importing
      !I_ABAP type DATA
    returning
      value(R_V_JSONtype STRING .
  class-methods SERIALIZE_CHECK
    importing
      !I_ABAP type DATA
    exporting
      !E_V_JSON type STRING
    returning
      value(R_V_SUCCESStype ABAP_BOOL .
  class-methods DESERIALIZE
    importing
      !I_V_JSON type STRING
    exporting
      !E_ABAP type DATA
    raising
      CX_XSLT_DESERIALIZATION_ERROR .




protected section.
  class-methods GET_COMPONENTS_OF_STRUCTURE
    importing
      !I_V_JSON type STRING
    returning
      value(R_T_COMPONENT_VALUEtype YT_T_COMPONENT_VALUE
    raising
      CX_XSLT_DESERIALIZATION_ERROR .

  class-methods SPLIT
    importing
      !I_V_JSON type STRING
      !I_V_SPLITTER type CHAR1 default ','
    returning
      value(R_T_PARTtype STRING_TABLE .

  class-methods UNPACK
    importing
      !I_V_JSON type STRING
    returning
      value(R_V_JSONtype STRING
    raising
      CX_XSLT_DESERIALIZATION_ERROR .




  METHOD serialize.

    DATA lv_type.
    DATA lv_item_count TYPE i.
    DATA lo_structdescr TYPE REF TO cl_abap_structdescr.
    DATA lv_index TYPE syindex.
    FIELD-SYMBOLS <ls_compdescr> TYPE abap_compdescr.
    FIELD-SYMBOLS <lv_item> TYPE any.
    FIELD-SYMBOLS <lt_abap> TYPE ANY TABLE.

    DESCRIBE FIELD i_abap TYPE lv_type COMPONENTS lv_item_count.

    IF lv_type <> cl_abap_typedescr=>typekind_table.
      IF lv_item_count 0.
*** unstructured (plain field)
        r_v_json i_abap" This assignment can cause problems. Monitor carefully!
        r_v_json |"{ cl_http_utility=>escape_url( r_v_json ) }"|.
      ELSE.
*** structured
        r_v_json '{'.
        lo_structdescr CAST #cl_abap_typedescr=>describe_by_datai_abap ).
        LOOP AT lo_structdescr->components ASSIGNING <ls_compdescr>.
          lv_index sy-tabix .
          ASSIGN COMPONENT <ls_compdescr>-name OF STRUCTURE i_abap TO <lv_item> .

          r_v_json |{ r_v_json }| &&
            |{ to_lower<ls_compdescr>-name }:| &&
            |{ serialize<lv_item> }|.

          IF lv_index < lv_item_count.
            r_v_json |{ r_v_json },|.
          ENDIF .
        ENDLOOP .
        r_v_json |{ r_v_json }\}|.
      ENDIF.
    ELSE.
*** internal table
      r_v_json '['.
      ASSIGN i_abap TO <lt_abap>.
      LOOP AT <lt_abap> ASSIGNING <lv_item>.
        lv_index sy-tabix .

        r_v_json |{ r_v_json }{ serialize<lv_item> }|.

        IF lv_index < lines<lt_abap> ).
          r_v_json |{ r_v_json },|.
        ENDIF .
      ENDLOOP.
      r_v_json |{ r_v_json }]|.
    ENDIF.

  ENDMETHOD.




  METHOD deserialize.

    DATA lv_type.
    DATA lv_item_count TYPE i.
    DATA lv_value TYPE string.
    DATA lv_json TYPE string.
    DATA lo_structdescr TYPE REF TO cl_abap_structdescr.
    DATA ls_component TYPE yt_s_component_value.
    DATA lt_component TYPE yt_t_component_value.
    DATA lt_json TYPE string_table.
    DATA lr_row TYPE REF TO data.

    FIELD-SYMBOLS <ls_compdescr> TYPE abap_compdescr.
    FIELD-SYMBOLS <lv_item> TYPE any.
    FIELD-SYMBOLS <lt_abap> TYPE ANY TABLE.
    FIELD-SYMBOLS <l_abap> TYPE any.

    CLEAR e_abap.
    DESCRIBE FIELD e_abap TYPE lv_type COMPONENTS lv_item_count.

    IF lv_type <> cl_abap_typedescr=>typekind_table.
      IF lv_item_count 0.
*** unstructured
        lv_value unpacki_v_json )" remove quotation marks
        lv_value cl_http_utility=>unescape_urllv_value ).

        e_abap lv_value.
      ELSE" unstructured i_v_json (plain variable)
*** structured
        " get component descriptor for abap object
        lo_structdescr CAST #cl_abap_typedescr=>describe_by_datae_abap ).
        " get list of json components
        lt_component get_components_of_structurei_v_json ).
        " iterate components of abap structure
        LOOP AT lo_structdescr->components ASSIGNING <ls_compdescr>.
          " assign json components to components of abap structure
          ASSIGN COMPONENT <ls_compdescr>-name OF STRUCTURE e_abap TO <lv_item> .
          CLEAR ls_component.
          READ TABLE lt_component INTO ls_component
            WITH TABLE KEY name to_lower<ls_compdescr>-name ).
          IF sy-subrc 0.
            deserialize(
              EXPORTING i_v_json ls_component-value
              IMPORTING e_abap <lv_item>
            ).
          ELSE.
            CLEAR <lv_item>.
          ENDIF.
        ENDLOOP" components of structure
      ENDIF" structured i_v_json
    ELSE.
*** internal table
      " get field symbol for table
      ASSIGN e_abap TO <lt_abap>.

      " create work area for table
      CREATE DATA lr_row LIKE LINE OF <lt_abap>.
      ASSIGN lr_row->TO <l_abap>.

      " get table of json strings
      lv_json unpacki_v_json )" remove braces [ ]
      lt_json zcl_jso_serial=>splitlv_json )" split at comma

      " iterate json strings and deserialize each
      LOOP AT lt_json INTO lv_json.
        deserialize(
          EXPORTING i_v_json lv_json
          IMPORTING e_abap <l_abap>
        ).
        INSERT <l_abap> INTO TABLE <lt_abap>" collect result
      ENDLOOP.
    ENDIF" i_v_json contains data of internal table

  ENDMETHOD.




  METHOD get_components_of_structure.

    DATA lv_name TYPE string.
    DATA lv_value TYPE string.
    DATA lv_s TYPE string.
    DATA lt_part TYPE string_table.

    " remove braces { }
    lv_s unpacki_v_json ).

    " split at comma
    lt_part zcl_jso_serial=>splitlv_s ).

    " split name and value at colon
    LOOP AT lt_part INTO lv_s.
      SPLIT lv_s AT ':' INTO lv_name lv_value.
      INSERT VALUE #name lv_name  value lv_value INTO TABLE r_t_component_value.
    ENDLOOP.

  ENDMETHOD.




  METHOD split.

    DATA lv_i TYPE i.
    DATA lv_start TYPE i.
    DATA lv_len TYPE i.
    DATA lv_c.
    DATA lv_b1_count TYPE i.
    DATA lv_b2_count TYPE i.

    CHECK strleni_v_json 0.

    lv_i 0.
    lv_start 0.
    lv_len 0.
    WHILE lv_i < strleni_v_json ).
      lv_c i_v_json+lv_i(1).
      ADD TO lv_len.

      IF lv_c '['ADD TO lv_b1_countENDIF.
      IF lv_c ']'SUBTRACT FROM lv_b1_countENDIF.
      IF lv_c '{'ADD TO lv_b2_countENDIF.
      IF lv_c '}'SUBTRACT FROM lv_b2_countENDIF.

      IF lv_c i_v_splitter OR lv_i strleni_v_json AND lv_b1_count AND lv_b2_count 0.
        IF lv_i < strleni_v_json 1SUBTRACT FROM lv_lenENDIF.
        INSERT substringval i_v_json  off lv_start  len lv_len INTO TABLE r_t_part.
        lv_start lv_i + 1.
        lv_len 0.
      ENDIF.

      ADD TO lv_i.
    ENDWHILE.

  ENDMETHOD.




  METHOD unpack.

    DATA lv_first.
    DATA lv_last.

    " validity checks
    IF strleni_v_json 2.
      RAISE EXCEPTION TYPE cx_xslt_deserialization_error.
    ENDIF.

    " get first and last character
    lv_first i_v_json(1).
    lv_last  substringval i_v_json off strleni_v_json len ).

    IF lv_first '"' AND lv_last '"' OR
       lv_first '[' AND lv_last ']' OR
       lv_first '{' AND lv_last '}' ).
      " unpack
      r_v_json substringval i_v_json off len strleni_v_json ).
    ELSE.
      RAISE EXCEPTION TYPE cx_xslt_deserialization_error.
    ENDIF.

  ENDMETHOD.




  METHOD serialize_check.

    DATA lr_abap TYPE REF TO data.

    FIELD-SYMBOLS <l_abap> TYPE any.

    " create a second variable <l_abap> with the same type like i_abap
    CREATE DATA lr_abap LIKE i_abap.
    ASSIGN lr_abap->TO <l_abap>.

  TRY. 
  " serialize i_abap to e_v_json
    e_v_json serializei_abap ).

    " deserialize e_v_json to <l_abap>
    deserialize(
      exporting i_v_json e_v_json
      importing e_abap   <l_abap>
    ).
    CATCH cx_xslt_deserialization_error.
      r_v_success abap_false.
      RETURN.
  ENDTRY.


    " now i_abap and <l_abap> shall be equal
    IF i_abap <l_abap>.
      r_v_success abap_true.
    ELSE.
      r_v_success abap_false.
    ENDIF.

  ENDMETHOD.

Wednesday, December 13, 2017

Neue Berechtigungsgruppen für Tabellen anlegen

Einer Datenbanktabelle (transparenten Tabelle) kann ein Berechtigungsgruppe zugeordnet werden. Wenn eine neue Berechtigungsgruppe angelegt werden soll, kann dies über die Transaktion SE54 "Generierung Tabellensicht" durchgeführt werden. Auf dem Einstiegsbild wird über den Radio Button "Berechtigungsgruppe" ausgewählt. Durch den Button "Anlegen/Ändern" gelangt man in den Pflege-Dialog zum Anlegen von Berechtigungsgruppen für Tabellen.


Siehe auch: SAP Dokumentation "Berechtigungsgruppen pflegen"

Monday, December 4, 2017

Default Full Screen Container

mr_alv NEW #i_parent cl_gui_container=>screen0 ).

Thursday, May 18, 2017

Using HTML in Dynpro an react on user interactions

The report needs dynpro 2000 with a custom container 'CC' for the HTML control.

REPORT zjso_html_in_dynpro_event.

CLASS lcl_html DEFINITION.

  PUBLIC SECTION.
    CLASS-DATAmo_cc TYPE REF TO cl_gui_custom_container.
    CLASS-DATAmo_html TYPE REF TO cl_gui_html_viewer.
    CLASS-METHODSpbouser_commandleave_screen.
    CLASS-METHODS on_sapevent FOR EVENT sapevent OF cl_gui_html_viewer
      IMPORTING action frame getdata postdata query_table.

ENDCLASS.


START-OF-SELECTION.
  CALL SCREEN 2000.


*&---------------------------------------------------------------------*
*&      Module  STATUS_2000  OUTPUT
*&---------------------------------------------------------------------*
MODULE status_2000 OUTPUT.
  SET PF-STATUS '2000'.
  SET TITLEBAR '2000'.
  lcl_html=>pbo).
ENDMODULE.


*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_2000  INPUT
*&---------------------------------------------------------------------*
MODULE user_command_2000 INPUT.
  lcl_html=>user_command).
ENDMODULE.


CLASS lcl_html IMPLEMENTATION.

  METHOD pbo.
    DATA lv_url TYPE text1024.
    DATA lt_html TYPE STANDARD TABLE OF text1024 WITH DEFAULT KEY.
    DATA lt_event TYPE cntl_simple_events.

    CHECK mo_cc IS NOT BOUND.
    lt_html VALUE #(
      |<!DOCTYPE html><head>| )
      |  <meta charset="utf-8">| )
      |  <title>HTML in Dynpro</title>| )
      |  <style>| )
      '    body { font-family:segoe ui, arial, helvetica; }' )
      |  </style>| )
      |<script>| )
      |function onClick(source\{| )
      |  window.location.href 'SAPEVENT:'+source.innerHTML;| )
      |\}| )
      |</script>| )
      |</head>| )

      |<body>| )
      |  <p>Helloworld!</p>| )
      |  <a href="SAPEVENT:Hyperlink">Request SAP AS</a>| )
      |  <div onclick="onClick(this)" style="width: 120px; height: 120px; margin: 8px; background-color:#ef0000">red</div>| )
      |  <div onclick="onClick(this)" style="width: 120px; height: 120px; margin: 8px; background-color:#ffdd00">yellow</div>| )
      |  <div onclick="onClick(this)" style="width: 120px; height: 120px; margin: 8px; background-color:#00ee00">green</div>| )
      |</body></html>| )
    ).
    mo_cc NEW #'CC' ).
    mo_html NEW #mo_cc ).

    " setup event handler for SAPEVENT from HTML control
    INSERT VALUE #eventid mo_html->m_id_sapevent  appl_event abap_true INTO TABLE lt_event.
    mo_html->set_registered_eventslt_event ).
    SET HANDLER on_sapevent FOR mo_html.

    " populate HTML control with HTML page
    mo_html->load_data(
      IMPORTING assigned_url lv_url
      CHANGING data_table lt_html
    ).
    mo_html->show_urllv_url ).

  ENDMETHOD.


  METHOD user_command.
    CASE sy-ucomm.
      WHEN 'BACK' OR 'EXIT'leave_screen)LEAVE TO SCREEN 0.
      WHEN 'BACK' OR 'EXIT'leave_screen)LEAVE PROGRAM.
    ENDCASE.
  ENDMETHOD.


  METHOD leave_screen.
    IF mo_cc IS BOUND.
      mo_cc->free).
    ENDIF.
  ENDMETHOD.

  METHOD on_sapevent.
    MESSAGE |onClick { action }| TYPE 'I'.
    " check contents of { postdata } and { query_table } in debugger
  ENDMETHOD.

ENDCLASS.

Tuesday, May 9, 2017

Update IDoc Status

    DATA ls_edi_ds TYPE edi_ds.

    CLEAR es_edidc.

    CALL FUNCTION 'EDI_DOCUMENT_OPEN_FOR_PROCESS'
      EXPORTING
        document_number          iv_docnum
      IMPORTING
        idoc_control             es_edidc
      EXCEPTIONS
        document_foreign_lock    1
        document_not_exist       2
        document_number_invalid  3
        document_is_already_open 4
        OTHERS                   5.
    IF sy-subrc <> 0.
      CLEAR es_edidc.
      RETURN.
    ENDIF.

    ls_edi_ds VALUE #(
      docnum iv_docnum
      status iv_status
      uname  sy-uname
      logdat sy-datum
      logtim sy-uzeit
    ).

    CALL FUNCTION 'EDI_DOCUMENT_STATUS_SET'
      EXPORTING
        document_number         iv_docnum
        idoc_status             ls_edi_ds
      IMPORTING
        idoc_control            es_edidc
      EXCEPTIONS
        document_number_invalid 1
        other_fields_invalid    2
        status_invalid          3
        OTHERS                  4.
    IF sy-subrc <> 0.
      CLEAR es_edidc.
      RETURN.
    ENDIF.

    CALL FUNCTION 'EDI_DOCUMENT_CLOSE_PROCESS'
      EXPORTING
        document_number     iv_docnum
      IMPORTING
        idoc_control        es_edidc
      EXCEPTIONS
        document_not_open   1
        failure_in_db_write 2
        parameter_error     3
        status_set_missing  4
        OTHERS              5.

    IF sy-subrc <> 0.
      CLEAR es_edidc.
      RETURN.
    ENDIF.

Monday, March 27, 2017

SAP Tables for Status Handling (in ABAP)

Some important tables concerning status:

JEST  Individual Object Status
JCDS  Change Documents for System/User Statuses (Table JEST)
JSTO  Status object information
TJ02    System Status
TJ02T System status texts
TJ20T Texts for Status Profiles
TJ30T  Texts for User Status

Wednesday, January 25, 2017

Sending emails from ABAP / E-Mail mit ABAP versenden

* https://wiki.scn.sap.com/wiki/display/Snippets/Sending+mail+with+attachment+using+Object+Oriented+Approach
report zjso_send_email.

class lcl_email definition final.
  public section.
    class-methods send
      importing
                iv_subject      type so_obj_des
                it_message_body type bcsy_text
                it_attachment   type rmps_t_post_content optional
                iv_sender_email type adr6-smtp_addr
                it_recipient    type uiyt_iusr
      raising   cx_send_req_bcs cx_document_bcs cx_address_bcs.
endclass.

start-of-selection.
  try.

      lcl_email=>send(
        iv_subject 'Betreff der E-Mail'(001)
        it_message_body value #(
          line 'Hallo,'(002)
          line '  diese E-Mail wurde aus einem SAP-System verschickt.'(003)
          line '' )
          line 'Mit freundlichen Grüßen'(004)
        )
        iv_sender_email 'marvin.maybe@p1zz4.com'
        it_recipient value #(
          mandt sy-mandt
          email 'michael.laender@deutsch.de' )
          email 'ablink@usa.com' )
        )
      ).
      write 'E-Mail erfolgreich versendet'(005).
    catch cx_send_req_bcs cx_document_bcs cx_address_bcs into data(go_x).
      write / go_x->get_text).
  endtry.

class lcl_email implementation.
  method send.
    data lo_send_request type ref to cl_bcs.
    data lo_document type ref to cl_document_bcs.
    data lo_sender type ref to if_sender_bcs.
    data lv_attachment_subject type so_obj_des.
    data lo_recipient type ref to if_recipient_bcs.

    lo_send_request cl_bcs=>create_persistent).
    lo_document cl_document_bcs=>create_document(
      i_type 'RAW'
      i_text it_message_body
      i_subject iv_subject
    ).
    loop at it_attachment into data(ls_attachment).
      lv_attachment_subject ls_attachment-subject.
      lo_document->add_attachment(
          i_attachment_type    ls_attachment-objtp
          i_attachment_subject lv_attachment_subject
          i_att_content_hex    ls_attachment-cont_hex
      ).
    endloop.
    lo_send_request->set_documentlo_document ).
    lo_sender cl_cam_address_bcs=>create_internet_addressiv_sender_email ).
    lo_send_request->set_senderlo_sender ).
    loop at it_recipient into data(ls_recipientwhere email is not initial.
      lo_recipient cl_cam_address_bcs=>create_internet_addressls_recipient-email ).
      lo_send_request->add_recipientexporting
        i_recipient lo_recipient
        i_express 'X'
      ).
    endloop.
    lo_send_request->sendabap_true ).
  endmethod.
endclass.


Check transaction SOST after sending an email. 

Thursday, December 22, 2016

concerning iDOCs

Transactions

WE05IDOC Liste
WE09IDOC(Nach IDOCS über Inhalte bzw. Felder suchen)
WE20Partnevereinbarungen(Verb. Zwischen Belegen und IDOC Generiereung)
BD87Nachverarbeitung von IDOCS
WE19Anlage und Verarbeitung von Testidocs(Als Vorlage bestehendes IDOC)
WEDIÜberblick
WE60Dokumention Idoc Struktur

Tables

TBDBEBAPI-ALE Interface for Inbound Processing
Function modules to process inbound, per message type

Function Modules

BAPI_IDOC_INPUT1Inbound BAPI IDoc: Individual Processing

Friday, December 9, 2016

function module to get list of application servers

    call function 'TH_SERVER_LIST'
      tables
        list           lt_server
      exceptions
        no_server_list 1
        others         2.

check with abap which jobs are running

select single jobname 
  from tbtco 
  into lv_jobname
  where 

    jobname like lv_jobname_pat and 
    status 'R'.

create and start background jobs from abap

    data lv_job_was_released type abap_bool.
    data lv_ret type i.
    data lv_stepcount type btcstepcnt.

    call function 'JOB_OPEN'
      exporting
        jobname          = lv_jobname
      importing
        jobcount         = lv_jobcount
      changing
        ret              lv_ret
      exceptions
        cant_create_job  1
        invalid_job_data 2
        jobname_missing  3
        others           4.

    if sy-subrc <> 0.
      " ...
      return.
    endif.

*    submit (mo_run->ms_run-client_report)
*      using selection-set mv_variant
*      user sy-uname via job mv_jobname number mv_jobcount
*      and return.
* Starting the report with submit, SM37  will display a 

* temporary variant 0.. insteat of the created variant 

    call function 'JOB_SUBMIT'
      exporting
        authcknam               sy-uname
        jobcount                = lv_jobcount
        jobname                 = lv_jobname
        report                  = lv_client_report
        variant                 = lv_variant
      importing
        step_number             lv_stepcount
      exceptions
        bad_priparams           1
        bad_xpgflags            2
        invalid_jobdata         3
        jobname_missing         4
        job_notex               5
        job_submit_failed       6
        lock_failed             7
        program_missing         8
        prog_abap_and_extpg_set 9
        others                  10.

    if sy-subrc <> 0.
      " ...
      return.
    endif.

    call function 'JOB_CLOSE'
      exporting
        jobcount             = lv_jobcount
        jobname              = lv_jobname
        targetsystem         = lv_server
        strtimmed            'X' " start immediately
      importing
        job_was_released     lv_job_was_released
      changing
        ret                  lv_ret
      exceptions
        cant_start_immediate 1
        invalid_startdate    2
        jobname_missing      3
        job_close_failed     4
        job_nosteps          5
        job_notex            6
        lock_failed          7
        invalid_target       8
        others               9.

    if sy-subrc <> 0.
      " ...
      return.
    endif.

save report variants for jobs

    data ls_varid type varid.
    data ls_varit type varit.
    data lt_varit type standard table of varit with empty key.
 
    ls_varid-mandt      sy-mandt" Mandant
    ls_varid-report     = lv_client_report
    ls_varid-variant    lv_variant
    ls_varid-flag1      ''

    ls_varid-flag2      ''
    ls_varid-transport  ''
    ls_varid-environmnt 'B'" Batch
    ls_varid-protected  ''
    ls_varid-secu       ''" Berechtigungsgruppe
    ls_varid-version    ''" Versionsnummer der Variante
    ls_varid-ename      sy-uname
    ls_varid-edat       sy-datum
    ls_varid-etime      sy-uzeit
    ls_varid-aename     sy-uname
    ls_varid-aedat      sy-datum
    ls_varid-aetime     sy-uzeit
    ls_varid-mlangu     sy-langu
    ls_varid-xflag1     ''
    ls_varid-xflag2     ''

    ls_varit-mandt sy-mandt.
    ls_varit-langu sy-langu.
    ls_varit-report = lv_client_report.
    ls_varit-variant = lv_variant.
    ls_varit-vtext |My Variant { sy-datum date iso } | ?? 

      |{ sy-uzeit time iso }|.
    insert ls_varit into table lt_varit.

    call function 'RS_CREATE_VARIANT'
      exporting
        curr_report               = lv_client_report
        curr_variant              lv_variant
        vari_desc                 ls_varid
      tables
        vari_contents             lt_rsparam
        vari_text                 lt_varit
      exceptions
        illegal_report_or_variant 1
        illegal_variantname       2
        not_authorized            3
        not_executed              4
        report_not_existent       5
        report_not_supplied       6
        variant_exists            7
        variant_locked            8
        others                    9.

    if sy-subrc 0.
      commit work.


    else.
      " s...
    endif.

Working with the session Id // ID für den Modus

Sometimes it can be helpful to know the id of the current session     CALL FUNCTION 'TH_GET_CONTEXT_ID'       IMPORTING         cont...