Skip to Content

Encouraged by the feedback I received in the Coffee Corner, here is a 2nd Q&A turned into a blog post. I decided to do this in this particular case because I didn’t just get a very simple solution to my question but because it also examplifies how helpful the SAP community can be – and even in possibly record time!

About a year ago and in preparation for our upgrade to the SAP HANA database I started to look into the SCI/ATC options and how to make good use of them. One thing which was bugging me was that I wasn’t able to find anything about how to call the ATC from a report program and provide the results in one go for multiple objects/transports. So, I posted a question about just that in Answers on Feb. 22, 2017 at 8:06 in the morning my time In Germany. Imagine my surprise, when I got a notification about a response from Former Member  within an hour – at 8:48 to be precise! – which was short and to the point:

Hi,

There is an object-oriented API which you can use to create an own program based on class CL_SATC_API_FACTORY. Please check out the example program RSATC_API_USAGE_EXAMPLE. There is a remote-enabled API and example program, too. See program RSATC_API_REMOTE_USAGE_EXAMPLE.

Hope it helps!

This turned out to be exactly what I was looking for and it was easy to implement as well! I checked out the sample code, copied it into a test-program, tweaked some of the hard-coded values to fit our own data (i.e. the program name or transport ID) and checked the results of this prototyping.

The next step was to add the logic – with some more tweaks – into a program I already had which lets me select transport-requests by various criteria. I basically just needed to add another routine to call the API from within a loop through the table with the already selected transports. I also decided to ignore any errors along the way (apart from a wrong check-variant) as I’m mainly using this for spot checks. I already had the program running each morning to send an email with a list of currently open transport-requests so I added the ATC-summary to that email. The ATC-information just includes the transport-ID and the number of findings encountered, but the details can be looked at as needed via Tcode ATC in the dev-system. So, as time allows, I can now use that email to do some spot checks on e.g. transports showing many findings. I had this up and running around noon.

Here is how the tweaked code looks like:

METHOD trigger_atc.

  "Local definitions for ATC API calls
  DATA:
    l_factory            TYPE REF TO cl_satc_api_factory,
    l_object_set         TYPE REF TO if_satc_object_set,
    l_variant            TYPE REF TO if_satc_check_variant,
    l_configuration      TYPE REF TO if_satc_run_configuration,
    l_controller         TYPE REF TO if_satc_run_controller,
    l_result_access      TYPE REF TO if_satc_result_access,
    l_findings           TYPE scit_rest,
    l_findings_extension TYPE satc_ci_findings_extension,
    l_ext_field_list     TYPE satc_ci_finding_ext_field_list,
    l_msg                TYPE string,
    l_cx                 TYPE REF TO cx_root,
    l_description(128)   TYPE c.

  "Table for transport numbers
  DATA: BEGIN OF ls_transp,
          strkorr LIKE e070ctv-strkorr,
          as4user     LIKE e070ctv-as4user,
          name_last   LIKE user_addr-name_last,
        END   OF ls_transp.

  DATA: lt_transp LIKE TABLE OF ls_transp.

  DATA: ls_dl_objects LIKE LINE OF gt_dl_objects.

  "Restrict to relevant ABAP-objects (via sel-screen input)
  LOOP AT gt_dl_objects INTO ls_dl_objects WHERE pgmid  IN s_pgmid
                                             AND object IN s_obj_em
                                             AND trkorr IN s_cts.
    "Add transport-ID to internal table for summary listing in email
    ls_transp-strkorr = ls_dl_objects-strkorr.
    ls_transp-as4user = ls_dl_objects-as4user.
    ls_transp-name_last = ls_dl_objects-name_last.
    COLLECT ls_transp INTO lt_transp.
  ENDLOOP.

  LOOP AT lt_transp INTO ls_transp.

    CREATE OBJECT l_factory.
    TRY.
        l_object_set = cl_satc_object_set_factory=>create_for_transport( i_transport = ls_transp-strkorr ).
      CATCH cx_satc_empty_object_set INTO l_cx.
        IF sy-batch EQ gc_x.
          MESSAGE i000(38) WITH 'Processing of transport'(E03) ls_transp-strkorr 'ended with error:'(e04).
          MESSAGE l_cx TYPE 'I'. " Object set contains no checkable objects
        ENDIF.
        CONTINUE.
      CATCH cx_satc_not_found INTO l_cx.
        IF sy-batch EQ gc_x.
          MESSAGE i000(38) WITH 'Processing of transport'(E03) ls_transp-strkorr 'ended with error:'(e04).
          MESSAGE l_cx TYPE 'I'. " Object set contains no checkable objects
        ENDIF.
        CONTINUE.
      CATCH cx_satc_invalid_argument INTO l_cx.
        IF sy-batch EQ gc_x.
          MESSAGE i000(38) WITH 'Processing of transport'(E03) ls_transp-strkorr 'ended with error:'(e04).
          MESSAGE l_cx TYPE 'I'. " Object set contains no checkable objects
        ENDIF.
        CONTINUE.
      CATCH cx_satc_failure INTO l_cx.
        IF sy-batch EQ gc_x.
          MESSAGE i000(38) WITH 'Processing of transport'(E03) ls_transp-strkorr 'ended with error:'(e04).
          MESSAGE l_cx TYPE 'I'. " Object set contains no checkable objects
        ENDIF.
        CONTINUE.
    ENDTRY.

    TRY.
        l_variant = l_factory->get_repository( )->load_ci_check_variant( i_name = p_chkv ).
      CATCH cx_satc_not_found INTO l_cx.
        MESSAGE l_cx TYPE 'E'. " Specified Code Inspector variant was not found
    ENDTRY.

    CONCATENATE p_chkv
                ls_transp-strkorr
                sy-datum
                sy-uzeit
                ls_transp-as4user
                ls_transp-name_last
           INTO l_description
      SEPARATED BY ' - '.


    l_configuration = l_factory->create_run_config_with_chk_var(
      i_object_set    = l_object_set
      i_check_variant = l_variant
      i_description   = l_description ).

    l_configuration->set_pragma_option( i_option = if_satc_ac_project_constants=>c_mode_fndng_xmptd_in_code-show_as_open ).

    l_controller = l_factory->create_run_controller( l_configuration ).

    TRY.
        l_controller->run( IMPORTING e_result_access = l_result_access ).
      CATCH cx_satc_failure INTO l_cx.
        MESSAGE l_cx TYPE 'E'. " ATC check run failed (no authorization, etc.)
    ENDTRY.

    l_ext_field_list-package_name = abap_true.
    l_ext_field_list-exc_validity = abap_true.

    TRY.
        l_result_access->get_findings(
          EXPORTING
            i_ext_field_list     = l_ext_field_list
          IMPORTING
            e_findings           = l_findings
            e_findings_extension = l_findings_extension ).
      CATCH cx_satc_failure INTO l_cx.
        MESSAGE l_cx TYPE 'E'. " Result access failed (no authorization, etc.)
    ENDTRY.

    l_msg = 'Number of Findings / Extensions: &1 / &2'(I01).
    REPLACE ALL OCCURRENCES OF '&1' IN l_msg WITH |{ lines( l_findings ) }|.
    REPLACE ALL OCCURRENCES OF '&2' IN l_msg WITH |{ lines( l_findings_extension ) }|.

    CONCATENATE l_msg
                ls_transp-strkorr
                ls_transp-as4user
                ls_transp-name_last
           INTO l_msg
      SEPARATED BY space.

    gs_atc_msg-msg = l_msg.
    APPEND gs_atc_msg TO gt_atc_msg.

  ENDLOOP.


  "Add the ATC-summary to the simple list
  SKIP 1.
  WRITE: / 'Summary of ATC-findings:'(i02).

  LOOP AT gt_atc_msg INTO gs_atc_msg.
    WRITE: / gs_atc_msg-msg.
  ENDLOOP.

ENDMETHOD.

So, from asking the question to having a working solution implemented took not even 5 hours in this case. Which is quite a quick turnaround as far as I can tell!

Do you have similar examples of where the community came through this quickly?

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

  1. Jelena Perfiljeva

    I’m pretty sure I have a similar example of fast “customer service” on SCN 🙂 but it’s somewhere in the archives under the previous profile. Most of my new “questions” these days are the complaints about the website. 🙂

    Thank you for posting this! We’re just starting to look at better ways to organize our work and I’m pretty sure ATC check will be a part of it. So this will be very useful.

    (1) 

Leave a Reply