Skip to Content

In the project we came across the challenge to find information within a list of objects in the debugger. in the ALV display you will only see all the objects instances.

 

Using debugger scripts (basics here Former Member ) you are able to iterate on the internal object table and work with the values. In the second example I will show you how to display object information in an ALV.

Using conditional breakpoints helps if there is a loop over all these objects in the #ABAP code. In the first example we will have the same functionality using a script, but in the end this could be much more powerful using more feature of the ABAP language if the conditions are met.

I wrote a demo Report that includes two other reports aka debugger scripts at the bottom to use with this report. It is based on the sflight table and should  compile on >NW7.10. ( if not just change these fancy modern commands ). The report selects 50 lines of sflight and creates a table of simple POAOs where the data is stored inside the objects only. These objects are defined in the top of the report.

One of the mayor issues / security features of debugger scrips is that you can not create them in a non open SAP System. If needed you should integrate them somehow in your Transports manually.

Let’s start.

1.  Copy the report at the end of the post into your system.

2. Run it and your debugger will stop:

 

3. Now we switch to the “Script” tab.

Here we can do all the scripting. Copy the local class of the first script report below and remove 3 columns of * comments.

Pay attention that “Debugger Single Step” is selected an run the script.

 

4.  The debugger stopps within the loop at sy-tabix 27 where the object contains the requested payment_sum. Great!

Ok, this is also possible using conditional breakpoints in such a simple scenario.

 

Second Example

Let’s make it a bit more complex.
Now we want to see all the information of the object before we iterate over them.

5. Run the program again, when the debugger stopps you paste the code of the second local class.

Run the script again and you will see an ALV with the listes information of the classes.

 

There is much more documentation out there but unfortunately the border to overcome to use scripting is quite his as my poll on twitter outlines

 

Thanks to Former Member for sharing an other nice example

“With this script I’m able to stop when a specific pattern occurs. E.g. ‘=.*\d{4}’ stops at every assignment or comparison where four digits occur on the right hand side.” tweet

*&---------------------------------------------------------------------*
*& Report ZTJ_DEBUGGER_SCRIPT_TEST
*&---------------------------------------------------------------------*
*& Report to demonstrate the power of ABAP debugger scripts
*& using to examples:
*& A) z_rstpda_script_obj_tab_2_alv
*&     Debugger script to list attribute values of a table of object instances in an ALV
*& B) z_rstpda_script_table_iteratio
*&    break if during loop of ABAP program a certain value within an object is found
*&
*& Report is based on the SAP flight model data.
*&
*& Created by: @Timo_Tohn 2018.
*& https://blogs.sap.com/2018/01/29/abap-debugger-script-2-use-cases/
*&---------------------------------------------------------------------*
REPORT ztj_debugger_script_test.
CLASS lcl_flight DEFINITION DEFERRED.
TYPES: " Object instance table
       tt_flights TYPE STANDARD TABLE OF REF TO lcl_flight WITH DEFAULT KEY.

CLASS lcl_flight DEFINITION CREATE PUBLIC.

  PUBLIC SECTION.
    CLASS-METHODS:
      get_list
        RETURNING VALUE(rt_flight_list) TYPE tt_flights.
    METHODS:
      constructor IMPORTING is_sflight TYPE sflight.

  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA: mv_connid     TYPE sflight-carrid,
          mv_fldate     TYPE sflight-fldate,
          mv_paymentsum TYPE sflight-paymentsum.

ENDCLASS.

CLASS lcl_flight IMPLEMENTATION.

  METHOD constructor.
    me->mv_connid     = is_sflight-connid.
    me->mv_fldate     = is_sflight-fldate.
    me->mv_paymentsum = is_sflight-paymentsum.
  ENDMETHOD.

  METHOD get_list.
    SELECT * FROM sflight INTO TABLE @DATA(lt_flights) UP TO 50 ROWS.
    " create table with object instances
    rt_flight_list = VALUE #( FOR <wa> IN lt_flights (  NEW lcl_flight( <wa> )   ) ).

  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

" Init object table.
  DATA(lt_fligt_insts) = lcl_flight=>get_list( ).


* Statements for debugging.
  WRITE 'Start Loop'.
  break-point.  " -> Now start the scripts.
  " - z_rstpda_script_table_iteratio
  " - z_rstpda_script_obj_tab_2_alv

  LOOP AT lt_fligt_insts INTO DATA(lo_flight).

    WRITE 'sy-tabix: ' && sy-tabix.

    CLEAR lo_flight. " we clear the object to test that scripts handle the occuring exceptions corretct.

    WRITE /.

  ENDLOOP.


  Exit.


**********************************************************************
* Save these two reports below as independent reports in your system to use them as Scripts.
* OR paste the local classes accordingly into the debugger script tab (only one at a time).
* then use Start "Start Script".

****<SCRIPT:PERSISTENT>
***REPORT z_rstpda_script_table_iteratio.
***
****<SCRIPT:HEADER>
****<SCRIPTNAME>Z_RSTPDA_SCRIPT_TABLE_ITERATIO</SCRIPTNAME>
****<SCRIPT_CLASS>LCL_DEBUGGER_SCRIPT</SCRIPT_CLASS>
****<SCRIPT_COMMENT>Anhalen bei komplexem Wert innerhalb einer Tabelleniteration</SCRIPT_COMMENT>
****<SINGLE_STEP>X</SINGLE_STEP>
***
****</SCRIPT:HEADER>
***
****<SCRIPT:PRESETTINGS>
***
****</SCRIPT:PRESETTINGS>
***
****<SCRIPT:SCRIPT_CLASS>
****---------------------------------------------------------------------*
****       CLASS lcl_debugger_script DEFINITION
****---------------------------------------------------------------------*
**** Debugger script to break if during loop of ABAP program a certain
**** value within an object is found.
****
**** Created by: @Timo_Tohn 2018.
****---------------------------------------------------------------------*
***CLASS lcl_debugger_script DEFINITION INHERITING FROM  cl_tpda_script_class_super  .
***
***  PUBLIC SECTION.
***    METHODS: script  REDEFINITION.
***ENDCLASS.                    "lcl_debugger_script DEFINITION
****---------------------------------------------------------------------*
****       CLASS lcl_debugger_script IMPLEMENTATION
****---------------------------------------------------------------------*
****
****---------------------------------------------------------------------*
***CLASS lcl_debugger_script IMPLEMENTATION.
***
***  METHOD script.
***    " Place the name of the variable that changes with each iteration and that is to be checked
***    " in this case we wait for a certain vbeln.
***    DATA: searched_sum TYPE sflight-paymentsum VALUE '486336.03'.
***
***    TRY.
***        DATA(lv_paymentsum) = cl_tpda_script_data_descr=>get_simple_value( 'lo_flight->mv_PAYMENTSUM' ).
***        "  BREAK-POINT.
***        IF lv_paymentsum = searched_sum.
***          " We want to stop if the flight with the specific payment value is found.
***          me->break( ).
***        ENDIF.
***      CATCH cx_tpda_varname
***            cx_tpda_script_no_simple_type.
***            " no need to react on these exceptions here, we just want to continue.
***    ENDTRY.
***
***  ENDMETHOD.                    "script
***ENDCLASS.                    "lcl_debugger_script IMPLEMENTATION
****</SCRIPT:SCRIPT_CLASS>
***
****</SCRIPT:PERSISTENT>





**********************************************************************


****<SCRIPT:PERSISTENT>
***REPORT  z_rstpda_script_obj_tab_2_alv.
***
****<SCRIPT:HEADER>
****<SCRIPTNAME>Z_RSTPDA_SCRIPT_OBJ_TAB_2_ALV</SCRIPTNAME>
****<SCRIPT_CLASS>LCL_DEBUGGER_SCRIPT</SCRIPT_CLASS>
****<SINGLE_STEP>X</SINGLE_STEP>
***
****</SCRIPT:HEADER>
***
****<SCRIPT:PRESETTINGS>
***
****</SCRIPT:PRESETTINGS>
***
****<SCRIPT:SCRIPT_CLASS>
****---------------------------------------------------------------------*
****       CLASS lcl_debugger_script DEFINITION
****---------------------------------------------------------------------*
**** Debugger script to list attribute values of a table of object
**** instances in an ALV.
****
**** Created by: @Timo_Tohn 2018.
****---------------------------------------------------------------------*
***CLASS lcl_debugger_script DEFINITION INHERITING FROM  cl_tpda_script_class_super  .
***
***  PUBLIC SECTION.
***    METHODS: script  REDEFINITION.
***
***  PRIVATE SECTION.
***    TYPES: BEGIN OF ts_alv_data,
***             "! like ->{O:10*\PROGRAM=ZTJ_DEBUGGER_SCRIPT_TEST\CLASS=LCL_FLIGHT}
***             instance_reference TYPE char100,
***             connid             TYPE sflight-connid,
***             fldate             TYPE  sflight-fldate,
***             paymentsum         TYPE  sflight-paymentsum,
***           END OF ts_alv_data.
***
***    DATA:
***      "! ALV display table
***      mt_alv_data  TYPE STANDARD TABLE OF ts_alv_data,
***      "! Name of the with objekt instances of the program.
***      mv_tablename TYPE string.
***
***
***ENDCLASS.                    "lcl_debugger_script DEFINITION
****---------------------------------------------------------------------*
****       CLASS lcl_debugger_script IMPLEMENTATION
****---------------------------------------------------------------------*
****
****---------------------------------------------------------------------*
***CLASS lcl_debugger_script IMPLEMENTATION.
***
***  METHOD script.
***    DATA: lo_table_descr TYPE REF TO cl_tpda_script_tabledescr,
***          table_clone    TYPE REF TO data.
***
***    FIELD-SYMBOLS: <table_clone> TYPE table,
***                   <l_clone>     TYPE any.
***
***    "BREAK-POINT. " if you want to debug the script use this.
***
***    FREE mt_alv_data. " to clean it for every run.
***    mv_tablename = 'LT_FLIGT_INSTS'.
***
***    lo_table_descr ?= cl_tpda_script_data_descr=>factory( mv_tablename ).
***    table_clone =  lo_table_descr->elem_clone( ).
***    ASSIGN table_clone->* TO <table_clone>.
***
***    "Loop over cloned table from program. unfortunately the objects are not cloned, only the names of references are in there.
***    LOOP AT <table_clone> ASSIGNING <l_clone>.
***      APPEND INITIAL LINE TO mt_alv_data ASSIGNING FIELD-SYMBOL(<s_alv_data>).
***
***      " disply the instance number as well
***      <s_alv_data>-instance_reference = <l_clone>+2 . "+2 to eliminate the "->"
***
***      "Now we concatenate the specific name of the variable as we would type it in the debugger variables
***      "and query the information from the object instances to put it into ALV-table.
***      <s_alv_data>-connid = cl_tpda_script_data_descr=>get_simple_value( <s_alv_data>-instance_reference && '-mv_connid' ).
***      <s_alv_data>-paymentsum = cl_tpda_script_data_descr=>get_simple_value( <s_alv_data>-instance_reference && '-mv_paymentsum' ).
***      <s_alv_data>-fldate = cl_tpda_script_data_descr=>get_simple_value( <s_alv_data>-instance_reference && '-mv_fldate' ).
***    ENDLOOP.
****   With the collected ALV Table we can do what ever is interesting for us in that moment.
****   Set up the ALV table for displaying the data.
***    cl_tpda_script_data_display=>data_display( CHANGING  p_data_it = mt_alv_data ).
***    me->break( ).
***
***  ENDMETHOD.                    "script
***ENDCLASS.                    "lcl_debugger_script IMPLEMENTATION
****</SCRIPT:SCRIPT_CLASS>
***
****</SCRIPT:PERSISTENT>
To report this post you need to login first.

5 Comments

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

  1. Michelle Crapo

    So cool. I learned something – I can go home. Creating a blog from a twitter poll – genius.  Pulling it all together with screen shots and solid explanations is a great idea.

    I’m still not using Twitter at all. Sometimes all the social media we have at our fingertips is crazy.

    Michelle

    (1) 
    1. Timo John Post author

      Former Member   you should start reading #TwitterRadio on SAP Topics it really helps a lot to find relevant information, events, news etc.
      If you mind you don’t have to post yourself to have big bennefits

      (1) 
      1. Michelle Crapo

        That’s true. It’s always a time thing for me. And with limited characters I never think that people can give a lot of relevant information.

        So what I check in the morning:

        • SAP Community
        • Facebook – skim this. There is no way to read everything.
        • Work E-mail

        These if I have time:

        • Linkediin
        • 2 different e-mail addresses

        So now I should add #Twitter Radio to the list under if I have time…

        I work on a computer for a living. Then when I’m not working, I still spend time on the computer. It really goes down in the summer when I can get outside and ride my horse. And, yes, I play games on the computer too!

        Thank you for the suggestion – I will check it out,

        Michelle

        (1) 
        1. Jelena Perfiljeva

          I feel that limited number of characters is actually Twitter’s advantage (they did increase it from 140 to 280 recently though). And it’s really helpful exactly for the things that Timo mentioned: quick notifications on what’s happening, what’s out there worthy reading. It’s also handy for the local traffic / construction and school closing updates. Not to mention you don’t need a police radio scanner anymore as there are Twitter accounts streaming all the emergency service communications. Feels like I’m running my own covert ops sometimes. 🙂

          I believe some discussions we would have on SCN before moved to Twitter instead. Not to mention you’ll find many old SCN friends there, even those who moved away from the SAP world (gasp!).

          Of course, it can quickly become a time sink if you let it. Everything is good in moderation. 🙂

          (1) 
  2. Jelena Perfiljeva

    Thanks for sharing and for the link to the other blog! I keep finding stuff from as far back as 2009 that was still too advanced for me until just a couple of years ago. 🙂

    This is very interesting, need to try this out soon.

     

    (0) 

Leave a Reply