Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

The delivered process type ABAP has the disadvantage that it does not return a defined state if execution was successful or not. But often you want to react properly at the end of the ABAP program and continue with loading or in case of error do some cleanup or at least stop the chain.

I want to show you step by step how you can create easily your own process type for ABAP that returns either successful or not for use in process chains. All code is below. All you need is the excellent Howto-Paper for creating your own process type: http://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/509f3ae6-e36e-2910-48a8-ab43dc167... 

Download i. It's really highly recommended to implement your own process types.

Step 1.) Create a return value table
Go to table maintenance, e.g SE 11 and create table ZABAP_STATUS.
Enter a short description for this table, e.g. Table for use in process type ZCL_ABAP_RC. Enter delivery type A. Create fields as described below:
 

Set the technical settings described below:

Save and activate. Ignore the warnings at activation.

Step 2.) Create your own process type class
Open Class builder (SE24) and enter name of new class for process type e.g. ZCL_ABAP_RC.

In the popup choose class.

Now switch to properties tab and enter type group RS under forward declarations.

Switch to the ‘Interface’ tab strip, and specify the following interfaces:
- IF_RSPC_EXECUTE Mandatory interface, which is called on the execution of the
process type
- IF_RSPC_GET_VARIANT Optional interface for the selection of the variants
- IF_RSPC_MAINTAIN Optional interface for the maintenance of the variants (in our
case call of the Process Chain maintenance)

Switch to the ‘Methods’ tab strip. To satisfy the minimum requirements implement the following methods, e.g. press redefine button and enter code:

- IF_RSPC_GET_VARIANT~GET_VARIANT Pick Process Chain from custom table

      CALL METHOD cl_rspc_variant=>f4
            EXPORTING
              i_type         = 'ABAP'
              i_variant      = i_variant
              i_objvers      = i_objvers
              i_t_select     = i_t_select
              i_allow_new    = rs_c_false
            IMPORTING
              e_variant      = e_variant
              e_variant_text = e_variant_text
            EXCEPTIONS
              aborted        = 1
              nothing_found  = 2
              internal_error = 3
              OTHERS         = 4.
          IF sy-subrc <> 0.
            MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                       WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
                       RAISING nothing_selected.
          ENDIF.

- IF_RSPC_GET_VARIANT ~EXISTS Indicate variant exist (for syntax check of whole Process Chain)

          CALL METHOD cl_rspc_variant=>exists
            EXPORTING
              i_type    = 'ABAP'
              i_variant = i_variant
            RECEIVING
              r_exists  = r_exists.

- IF_RSPC_EXECUTE~GIVE_CHAIN

return = rs_c_false.

- IF_RSPC_MAINTAIN~GET_HEADER Define title for variant

        DATA: l_r_variant TYPE REF TO cl_rspc_variant,
                l_s_attrib  TYPE rspcvariantattr,
                l_s_text    TYPE rspcvariantt.
          CALL METHOD cl_rspc_variant=>create
            EXPORTING
              i_type      = 'ABAP'
              i_variant   = i_variant
              i_objvers   = i_objvers
              i_no_transport = rs_c_true

- IF_RSPC_MAINTAIN~MAINTAIN

       PERFORM displaymode_set IN PROGRAM saplrspc_processes USING i_display_only.
          CALL FUNCTION 'RSPC_VARIANT_MAINTAIN'
            EXPORTING
              i_type             = 'ABAP'
              i_objvers          = 'A'
              i_dynnr            = '0200'
              i_repid            = 'SAPLRSPC_PROCESSES'
              i_callback_at_exit = 'ABAP_CHANGED'
              i_variant          = i_variant
              i_display_only     = i_display_only
            EXCEPTIONS
              aborted            = 1
              OTHERS             = 2.
          IF sy-subrc <> 0.
            MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
                    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
            EXIT.
          ENDIF.
          CALL FUNCTION 'RSPC_VARIANT_GET'
            IMPORTING
              e_variant      = e_variant
              e_variant_text = e_variant_text.

- IF_RSPC_GET_VARIANT~WILDCARD_ENABLED returns just ‘X’

         result = 'X'.

- IF_RSPC_EXECUTE~EXECUTE Performs the check against custom table
This method is executed when the process chain runs. The coding is taken from the ABAP process type. You can find all the coding in class CL_RSPC_ABAP. In this method you find the part where the hand-over of the ABAP program to the process chain takes place:

       DATA: l_uid       TYPE sysuuid_25,
                l_r_variant TYPE REF TO cl_rspc_variant,
                l_t_info    TYPE TABLE OF rspcvariant,
                l_s_info    TYPE rspcvariant,
                l_program   TYPE programm,
                l_progvari  TYPE raldb_vari,
                l_event     TYPE btceventid,
                l_param     TYPE btcevtparm,
                l_dest      TYPE rfcdest,
                l_msg(100)  TYPE c,
                l_s_log     TYPE rspcabapasync,
                l_chainid   TYPE rspc_chain,
                l_pripar    TYPE pri_params,
                l_t_values  type table of RSPARAMS,
                l_s_value   type RSPARAMS,
                l_arcpar    TYPE arc_params.

* ==== Makro for abnormal ending ====
          DEFINE log_abort.
            call function 'RSSM_GET_TIME'
              importing
                e_timestamps = l_s_log-timestamp.
            l_s_log-state = 'X'.
            modify rspcabapasync from l_s_log.
            call function 'DB_COMMIT'.
         END-OF-DEFINITION.
* ==== Get Instance ====
          CALL FUNCTION 'RSSM_UNIQUE_ID'
            IMPORTING
              e_uni_idc25 = l_uid.
          e_instance = l_uid.
* ==== get variant ====
          CALL METHOD cl_rspc_variant=>create
            EXPORTING
              i_type      = 'ABAP'
              i_variant   = i_variant
              i_no_transport = rs_c_true
            RECEIVING
              r_r_variant = l_r_variant
            EXCEPTIONS
              locked      = 1
              OTHERS      = 2.
          IF sy-subrc <> 0.
            MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                       WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
            EXIT.
          ENDIF.
          CALL METHOD l_r_variant->get_info
            IMPORTING
              e_t_rspcvariant = l_t_info.
          CALL METHOD l_r_variant->free.
* ==== Check if run allowed ====
          READ TABLE l_t_info INTO l_s_info
               WITH KEY fnam = 'X_ASYNCHRON'.
          IF sy-subrc = 0.
            SELECT SINGLE * FROM rspcabapasync INTO l_s_log
                   WHERE variante = i_variant
                   AND   state   = 'A'.
            IF sy-subrc = 0.
              MESSAGE e052(rspc) WITH
                      i_variant l_s_log-instance l_s_log-log_id.
              EXIT.
            ENDIF.
          ENDIF.
* ==== Log start ====
          CALL FUNCTION 'GET_JOB_RUNTIME_INFO'
            IMPORTING
              jobcount        = l_s_log-jobcount
            EXCEPTIONS
              no_runtime_info = 1
              OTHERS          = 2.
          CALL FUNCTION 'RSSM_GET_TIME'
            IMPORTING
              e_timestamps = l_s_log-timestamp.
          l_s_log-variante = i_variant.
          l_s_log-log_id   = i_logid.
          l_s_log-instance = e_instance.
          l_s_log-state    = 'A'.
          INSERT rspcabapasync FROM l_s_log.
        CALL FUNCTION 'DB_COMMIT'.
* ==== Datenübergabe an Programm ====
          SELECT SINGLE chain_id FROM rspclogchain INTO l_chainid
                 WHERE log_id = l_s_log-log_id.
          EXPORT instance FROM l_s_log-instance
                 log_id   FROM l_s_log-log_id
                 chain_id FROM l_chainid
                 TO DATABASE rspc_buffer(ab)
                 ID l_s_log-variante.
          CALL FUNCTION 'DB_COMMIT'.
* ==== Start ====
          READ TABLE l_t_info INTO l_s_info
               WITH KEY fnam = 'X_PROGRAM'.
          IF sy-subrc = 0.
* ---- Programm ----
            READ TABLE l_t_info INTO l_s_info
                 WITH KEY fnam = 'PROGRAM'.
            l_program = l_s_info-low.
            READ TABLE l_t_info INTO l_s_info
                 WITH KEY fnam = 'VARIANT'.
            l_progvari = l_s_info-low.
            CALL FUNCTION 'GET_PRINT_PARAMETERS'
              EXPORTING
                no_dialog              = 'X'
                line_size              = 255
              IMPORTING
                out_archive_parameters = l_arcpar
                out_parameters         = l_pripar
              EXCEPTIONS
                OTHERS                 = 1.
            IF sy-subrc <> 0.
              MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
                      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
            ENDIF.
            SUBMIT (l_program) USING SELECTION-SET l_progvari
                               TO SAP-SPOOL WITHOUT SPOOL DYNPRO
                               LINE-SIZE 255
                               SPOOL PARAMETERS l_pripar
                               ARCHIVE PARAMETERS l_arcpar
                               AND RETURN.
* read parameters of program variant
* look in Z_BAP_STATUS for status of ABAP
            data: l_subrc type ZABAP_STATUS-status.

            SELECT SINGLE status into l_subrc FROM ZABAP_STATUS WHERE report =  l_program.
            if sy-subrc <> 0.
                e_state = 'X'.
                exit.
            endif.
* set e_state accordingly
              if l_subrc <> 0.
                MESSAGE ID 'RSPC' TYPE 'I' NUMBER 051
                        WITH 'BI' l_msg(50) l_msg+50(50).
                e_state = 'X'.
                exit.
              else.
                e_state = 'F'.
                exit.
              endif.
          ELSE.
            READ TABLE l_t_info INTO l_s_info
                 WITH KEY fnam = 'X_PLANNED'.
            IF sy-subrc = 0.
* ---- Event ----
              READ TABLE l_t_info INTO l_s_info
                   WITH KEY fnam = 'EVENT'.
              l_event = l_s_info-low.
              READ TABLE l_t_info INTO l_s_info
                   WITH KEY fnam = 'PARAM'.
              l_param = l_s_info-low.
              READ TABLE l_t_info INTO l_s_info
                   WITH KEY fnam = 'X_LOCAL'.
              IF sy-subrc = 0.
*      Lokal
                CALL FUNCTION 'RSSM_EVENT_RAISE'
                  EXPORTING
                    i_eventid              = l_event
                    i_eventparm            = l_param
                  EXCEPTIONS
                    bad_eventid            = 1
                    eventid_does_not_exist = 2
                    eventid_missing        = 3
                    raise_failed           = 4
                    OTHERS                 = 5.
                IF sy-subrc <> 0.
                  log_abort.
                  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
                  EXIT.
                ENDIF.
              ELSE.
                READ TABLE l_t_info INTO l_s_info
                     WITH KEY fnam = 'X_DESTINATION'.
                IF sy-subrc = 0.
*      Remote
                  READ TABLE l_t_info INTO l_s_info
                       WITH KEY fnam = 'DESTINATION'.
                  l_dest = l_s_info-low.
                  CALL FUNCTION 'RPY_FUNCTIONMODULE_READ'
                    DESTINATION l_dest
                    EXPORTING
                      functionname          = 'ROPC_EVENT_RAISE'
                    EXCEPTIONS
                      error_message         = 1
                      function_not_found    = 2
                      invalid_name          = 3
                      system_failure        = 5  MESSAGE l_msg
                      communication_failure = 5  MESSAGE l_msg
                      OTHERS                = 4.
                  IF sy-subrc = 5.
                    log_abort.
                   MESSAGE e051(rspc) WITH l_dest l_msg(50) l_msg+50(50).
                    EXIT.
                  ELSEIF sy-subrc = 2.
                    log_abort.
                    MESSAGE e045(rspc) WITH l_dest.
                  ELSEIF sy-subrc <> 0.
                    log_abort.
                    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
                    EXIT.
                  ENDIF.
                  CALL FUNCTION 'ROPC_EVENT_RAISE'
                    DESTINATION l_dest
                    EXPORTING
                      i_eventid              = l_event
                      i_eventparm            = l_param
                    EXCEPTIONS
                      bad_eventid            = 1
                      eventid_does_not_exist = 2
                      eventid_missing        = 3
                      raise_failed           = 4
                      system_failure         = 5  MESSAGE l_msg
                      communication_failure  = 6  MESSAGE l_msg
                      OTHERS                 = 7.
                  IF sy-subrc = 5.
                    log_abort.
                    MESSAGE e051(rspc) WITH l_dest l_msg(50) l_msg+50(50).
                    EXIT.
                  ELSEIF sy-subrc <> 0.
                    log_abort.
                    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
                    EXIT.
                  ENDIF.
                ENDIF.
              ENDIF.
            ENDIF.
          ENDIF.
* ==== End ====
          READ TABLE l_t_info INTO l_s_info
               WITH KEY fnam = 'X_SYNCHRON'.
          IF sy-subrc = 0.
* ---- Synchron call ----
            CALL FUNCTION 'RSSM_GET_TIME'
              IMPORTING
                e_timestamps = l_s_log-timestamp.
* look in Z_BAP_STATUS for status of ABAP

            SELECT SINGLE status into l_subrc FROM ZABAP_STATUS WHERE report = l_program.
            if sy-subrc <> 0.
                e_state = 'X'.
                exit.
            endif.
* set e_state accordingly
              if l_subrc <> 0.
                MESSAGE ID 'RSPC' TYPE 'I' NUMBER 051
                        WITH 'BI' l_msg(50) l_msg+50(50).
                e_state = 'X'.
                exit.
              else.
                e_state = 'F'.
                exit.
              endif.
*    e_state = 'F'.
            CLEAR e_hold.
*    l_s_log-state = 'F'.
*    l_s_log-state = 'X'.
*    MODIFY rspcabapasync FROM l_s_log.
            CALL FUNCTION 'DB_COMMIT'.
          ELSE.
* ---- Asynchron call ----
            e_state = 'A'.
            e_hold = 'X'.
          ENDIF.

The other methods provided by the interfaces are not needed and can be left unimplemented.
Activate the class with all its methods.

The tricky part are following lines of code:
            data: l_subrc type ZABAP_STATUS-status.

            SELECT SINGLE status into l_subrc FROM ZABAP_STATUS
                WHERE report =  l_program.
            if sy-subrc <> 0.
                e_state = 'X'.
                exit.
            endif.
* set e_state accordingly
              if l_subrc <> 0.
                MESSAGE ID 'RSPC' TYPE 'I' NUMBER 051
                        WITH 'BI' l_msg(50) l_msg+50(50).
                e_state = 'X'.
                exit.
              else.
                e_state = 'F'.
                exit.
              endif.

The process type reads in the Z-table, if there is an entry for the executed ABAP program. That’s the only pre-condition to use this process type with your ABAP reports in process chains:
All ABAP reports have to write their execution result into this Z-table!


Step 3.) Create your new process type
Call transaction RSPC, or use the icon in the Administrator Workbench.
Open any of the existing process chains, or create a new one. Call the maintenance of the process types by choosing from menu ‘Settings -> Maintain Process Types’.

Press change button to switch from table display to table change mode. Then press button “New entries”. Create a new entry in the table, and specify the settings as shown in the picture:

For testing I wrote just a small program call ed ZABAP_TEST:
data: l_data like zabap_Status.

if sy-datum >= 20071231.
    sy-subrc = 0.
else.
    sy-subrc = 4.
endif.
l_data-report = 'ZABAP_TEST'.
l_Data-status = sy-subrc.

    insert into zabap_status values l_data.
    if sy-subrc <> 0.
       update zabap_Status from l_data.
     endif.

You can easily switch to produce true or false.
In RSPC build an easy new process chain, executing our test abap and the new process type. In case of error, chain should stop. In case of no error it should e.g. rebuild an index of an cube.

So the process chain looks like that:

Schedule and execute it.

Have fun with it!