Search transaction for user-exit and BADI

As ABAP developer you need to search for a user-exit and/or BADI for a certain transaction.

The helper program below can help you here. Copy and paste the source code and run the program:

Enter the transaction code and let the program search. Results will show:

You can click on the exit or badi name to jump to the definition.

The program to search for BADI or user-exit

*& Enter the transaction code that you want to search through in order *
*& to find which Standard SAP User Exits exists. *

TABLES : tstc, "SAP Transaction Codes
         tadir, "Directory of Repository Objects
         modsapt, "SAP Enhancements - Short Texts
         modact, "Modifications
         trdir, "System table TRDIR
         tfdir, "Function Module
         enlfdir, "Additional Attributes for Function Modules
         tstct, "Transaction Code Texts
*& Definition of Types *
TYPES: BEGIN OF t_badi_list,
         obj_name TYPE sobj_name,
         devclass TYPE devi_class,
         dlvunit  TYPE dlvunit,
         imp_name TYPE exit_imp,
         packname TYPE devclass,
         dlvunit2 TYPE dlvunit,
         text     TYPE sxc_attrt-text,
       END OF t_badi_list.
TYPES: BEGIN OF t_badi_list2,
         obj_name TYPE sobj_name,
         devclass TYPE devi_class,
         dlvunit  TYPE dlvunit,
       END OF t_badi_list2.
*& Data Declaration *
DATA: lt_badi_list  TYPE TABLE OF t_badi_list,
      lt_badi_list2 TYPE TABLE OF t_badi_list2,
      ls_badi_list  TYPE t_badi_list OCCURS 0 WITH HEADER LINE,
      ls_badi_list2 TYPE t_badi_list2.
RANGES: r_badi FOR tadir-obj_name ,
rt_badi FOR tadir-obj_name .
*& Variables *
       p_trkey LIKE trkey.
DATA : field1(30),
count TYPE p.
DATA : v_devclass  LIKE tadir-devclass,
       p_devclass  LIKE tadir-devclass,
       p_old_langu LIKE sy-langu,
       p_mod_langu LIKE sy-langu.
*& Selection Screen Parameters *
PARAMETERS : p_tcode LIKE tstc-tcode OBLIGATORY.
*& Start of report *
* Validate Transaction Code
  SELECT SINGLE * FROM tstc WHERE tcode EQ p_tcode.
*Find Repository Objects for transaction code
  IF sy-subrc EQ 0.
    SELECT SINGLE * FROM tadir WHERE pgmid = 'R3TR'
    AND object = 'PROG'
    AND obj_name = tstc-pgmna.
    MOVE: tadir-devclass TO v_devclass.
    IF sy-subrc NE 0.
* This section is used if a FGR is involved\!
          global_lock             = 'X'
          object                  = p_tcode
          object_class            = 'TRAN'
          mode                    = 'SHOW'
          language_upd_exit       = 'RS_TRANSACTION_LANGUAGE_EXIT'
          suppress_language_check = space
          new_master_language     = p_old_langu
          modification_language   = p_mod_langu
          transport_key           = p_trkey
          devclass                = p_devclass
          canceled_in_corr        = 1
          OTHERS                  = 2.
      IF sy-subrc = 0. " Success
        MOVE: p_devclass TO v_devclass.
      ELSE. " For the case that nothing is found\!
        SELECT SINGLE * FROM trdir WHERE name = tstc-pgmna.
        IF trdir-subc EQ 'F'.
          SELECT SINGLE * FROM tfdir WHERE pname = tstc-pgmna.
          SELECT SINGLE * FROM enlfdir WHERE funcname = tfdir-funcname.
          SELECT SINGLE * FROM tadir WHERE pgmid = 'R3TR'
          AND object = 'FUGR'
          AND obj_name = p_devclass.
          MOVE: tadir-devclass TO v_devclass.
*Find SAP Modifactions
    SELECT * FROM tadir INTO TABLE jtab
    WHERE pgmid = 'R3TR'
    AND object = 'SMOD'
    AND devclass = v_devclass.
    SELECT SINGLE * FROM tstct WHERE sprsl EQ sy-langu
    AND tcode EQ p_tcode.
    WRITE:/(19) 'Transaction Code - ', 20(20) p_tcode, 45(50) tstct-ttext.
    WRITE:/1 'The application area is:', v_devclass.
    IF NOT jtab[] IS INITIAL.
      WRITE:/(95) sy-uline.
      WRITE:/1 sy-vline, 2 'Exit Name', 21 sy-vline, 22 'Description', 95 sy-vline.
      WRITE:/(95) sy-uline.
      LOOP AT jtab.
        SELECT SINGLE * FROM modsapt
        WHERE sprsl = sy-langu
        AND name = jtab-obj_name.
        WRITE:/1 sy-vline, 2 jtab-obj_name HOTSPOT ON, 21 sy-vline , 22 modsapt-modtext,
        95 sy-vline.
      WRITE:/(95) sy-uline.
      DESCRIBE TABLE jtab.
      WRITE:/ 'No of Exits:' , sy-tfill.
      WRITE:/(83) sy-uline.
      WRITE:/1 sy-vline, 2 'Badi Name', 22 sy-vline, 23 'Description', 83 sy-vline.
      WRITE:/(83) sy-uline.
* select the BAdI Definitions from the tables sxc_exit and sxc_attr
      SELECT t~obj_name t~devclass tc~dlvunit sx~imp_name sat~text
      FROM ( ( ( ( tadir AS t
      tdevc AS tc ON t~devclass = tc~devclass )
      sxc_exit AS sx ON sx~exit_name = t~obj_name )
      sxc_attr AS sa ON sx~imp_name = sa~imp_name )
      sxc_attrt AS sat ON sx~imp_name = sat~imp_name )
      WHERE t~pgmid = 'R3TR'
      AND t~object = 'SXSD' "means BAdI
      AND t~devclass = v_devclass "narrow down seach with Dev.Class
      AND sat~sprsl = sy-langu.
      SORT lt_badi_list.
* create Ranges
      LOOP AT lt_badi_list INTO ls_badi_list .
        r_badi-sign = 'I' .
        r_badi-option ='EQ' .
        r_badi-low = ls_badi_list-imp_name .
        r_badi-high = ls_badi_list-imp_name .
        APPEND r_badi TO rt_badi .
* select the implementations
      SELECT t~obj_name t~devclass tc~dlvunit
      FROM tadir AS t
      tdevc AS tc ON t~devclass = tc~devclass
      FOR ALL ENTRIES IN rt_badi
      WHERE t~obj_name = rt_badi-low
      AND t~pgmid = 'R3TR'
      AND t~object = 'SXCI'.
      WRITE:/(83) sy-uline.
      count = '0'.
      LOOP AT lt_badi_list INTO ls_badi_list .
        WRITE:/1 sy-vline, 2 ls_badi_list-obj_name HOTSPOT ON, 22 sy-vline,
        23 ls_badi_list-text, 83 sy-vline.
        count = count + 1.
      WRITE:/(83) sy-uline.
      DESCRIBE TABLE ls_badi_list.
      WRITE:/ 'No of BADIs:' , count.
      WRITE:/(95) 'No User Exit exists'.
    WRITE:/(95) 'Transaction Code Does Not Exist'.
*& Call SMOD or SE18 to lead the user to the selected exit or badi *
  IF field1(4) EQ 'JTAB'.
    SET PARAMETER ID 'MON' FIELD sy-lisel+1(10).
  ELSEIF field1(12) EQ 'LS_BADI_LIST'.
        exit_name = sy-lisel+1(20)

Code and table generation

In some cases you need to regenerate specific coding and tables. An SGEN is too extensive for your situation.

Regenerate programs

Use program TOUCHSRC:

Or worst case program TOUCHALL:

Regenerate tables

For table regeneration run program TOUCHTAB:

And TOUCHINC for includes in table structures:


Background OSS notes:

Best practice notes:

TRDIR and TADIR: tables behind programs and tables

TRDIR and TADIR are the tables behind programs and table data.

The below section is for experts only. Sometimes direct interception in TRDIR or TADIR is needed to solve nasty upgrade and support package issues. But if you don't know what you are doing: don't touch and raise message to SAP.

TADIR: development objects

TADIR contains the development objects list.

For example you want to know how many Z classes are created in your system, search in TADIR with SE11 and count the records:

Using TADIR with a search on DEVCLASS $TMP will give you a list with all programs in the $TMP (temp) space.

TADIR also has information about the original system. To change: follow the instructions in this blog.

TADIR does not contain a program editor lock. This is stored in table PROGDIR. See more in this blog.

Background notes on TADIR:

TRDIR: source code

TRDIR is a view on table REPOSRC. REPOSRC contains the actual ABAP source codes in RAWSTRING format. In some cases inconsistencies between TRDIR and TADIR might happen (mainly during upgrades). Direct interception on TADIR or TRDIR level might be needed, if you know what you are doing.

Transaction STDR can be used to check consistency:

Background notes on TRDIR:

Clean ABAP code ATC variant

Clean ABAP is the ABAP variant of the clean code principles. All background on clean ABAP code can be read in this blog.

This blog will explain how to upload the ABAP coding for the Clean ABAP ATC variant in your system and activate it.

Load ABAP Git code

To load the ATC variant code for clean ABAP you first need to install the ABAP Git code. Follow the instructions in this blog to do so. Simplest is the offline variant.

Download the ABAP clean code package

Now go to the Github code pal site for ABAP clean code and download the package:

Select the button Code and choose the option Download ZIP.

Upload the package

Now start the ABAP git that you loaded in your first step. Choose the option New Offline:

Give the repository a name and select a package:

Then push the button Create Offline Repo.

Now select Import Zip:

Import the file you downloaded in step 2 from the code pal site.

Next step is the Pull zip:

You might get a screen with differences. Do not select anything there, only press Ok.

Then wait until all the Y objects are pulled into the system. This might take 5 to 10 minutes.

Activating the SCI checks

Now start transaction SCI. Select menu option Code Inspector, Management of, Tests. Select all the newly load Y checks for Clean ABAP code:

Important now: Save them!

Now you can create a global SCI variant:

Select all the Clean code ABAP checks and save the variant:

You might get weird issues upon saving for other items, like for example missing CL_CI_CATEGORY_TOP. In that case, go to transaction SE16 -> look for table SCITESTS -> and look for CL_CI_CATEGORY_TOP if there is no entry. Enter the table SCITESTS and click "Create Entry", add CL_CI_CATEGORY_TOP entry and save.

Test and usage

Take a program you want check. Then select menu option Program, Check, ABAP Test Cockpit with….:

Select the ZCLEAN_ABAP SCI check we created above. Run the checks.


Tip: click on the blue line to jump to the Clean Code site exactly explaining about the issue.

Clean ABAP

Clean ABAP is the ABAP implementation of Clean code. Clean code is one of the key principles to adhere to when going Agile. Clean code is part of agile software development craftmanship. Read more on clean code in the original book.

Clean ABAP reference site

Clean ABAP is published and maintained on a dedicated Clean ABAP Github site.

The site itself is excellent and also has a special chapter how to best start with Clean ABAP.

The site is extensive and might be overwhelming. If you are a more traditional person, you can also read the SAP Press book on Clean ABAP code.

Blog on SAP site on clean ABAP can be found here.

Patterns and anti-patterns

The Clean ABAP explanation on the site contains both patterns (how you should do) and anti-patterns (how you should not do).

Anyhow the Clean ABAP principles are fully built on Object Orientation. That is a must.

Introducing Clean ABAP in your organization

Regardless if your organization is doing Agile or Waterfall development, or other development methodologies, Clean ABAP can be applied anyhow.

First step is to embrace the Clean ABAP as a principle direction. It will take time to get there. Not all developers will pick up as fast as you might want to. It also takes time to refactor old code to the Clean ABAP principles.

Discuss as developers as a team which part of the principles and improvements you want to pick up first. If you master a few, you can make it mandatory. Then take the next set. Some might pick up more at a higher pace. But keep the discussion going to improve and pick up every 2 weeks (sprint) at least 1 improvement item.

For a nice overview: read this SAP blog.

Peer review or pair programming: ATC variant

You can make the Clean ABAP code rules a part of your peer review or pair programming.

There is an ATC variant that can be uploaded that check for the clean ABAP code rules. Read this blog for instructions on how to do this.

Boy Scout rule

The boy scout rule is as follows: leave the place nicer than when you arrived, even though you didn’t make the mess. When you do this repetitively the world becomes a cleaner place.

This also applies to poor code: don’t just do your change, but take along some minor improvements as well. When you do this a couple of times, the poor code will improve every time towards good code.

But this principle you also need to embrace and explain. There might be unlucky situations where the clean up part might cause unexpected bug. This might happen in 0.01% of the cases. When it happens you might get resistance and pushback. But stand up for the principle, and simply correct the bug. It is worth it in the long run.


New input welcome, leave a comment!

What does the SAP abbreviation stand for?

  • SAP = Slow And Painful
  • SAP = Software Aus Pakistan
  • SAP = Shut up And Pay
  • SAP = Sanduhr Anschau Program
  • SAP = Schreibs Auf Papier
  • SAP = Suffer After Purchase
  • SAP = System against People
  • SAP = Start Applying Patches
  • SAP = Surrender and Pay
  • SAP = Sit and Panic
  • SAP = Severely Aged Programs
  • SAP = Submit (security bugs) and Pray
  • SAP = Sammelbecken Arbeitsloser Physiker -> German for Pool of Unemployed Physicists


Competence is limited, incompetence is unlimited
Below each level of incompetence there a next level of even worse incompetence
We don't need to remove the BigTruck button in STMS since nobody will be so stupid to start the ImportAll
Fundamental laws of stupidity:
1. Everybody underestimates the amount of stupid people
2. Stupidity is not related to any other characteristic of a person 
3. Stupid people damage others and themselves
4. Not-stupid people underestimate the damage of stupid people
5. Stupid people are more dangerous than smart criminals

Integrate SO10 text in webdynpro

This blog will explain how to integrate SO10 standard text in webdynpro. It will also show how to use this to integrate it into page on the right after logon (see also this blog).

Setup SO10 text

Start transaction SO10 and create text for logon:

Now enter the text and save it:

We have entered text (as explained in SO10 blog). Important: add the <br/> tags to create the line break.

Setup webdynpro screen

We will now setup webdynpro screen into which we will integrate SO10 text above.

Go to SE80 and create webdynpro Z_LOGON_INFO and go to the main view context and create this structure:

This is the data container for the string to show on the screen.

In the Layout View add element for logon text of type FormattedTextView:

Bind the text from the data element:

And map the data source:

In the view go to the methods and fill the WDDOINIT method:

Full code:

METHOD wddoinit .

  DATA: lt_table    TYPE TABLE OF tline,
        ls_table    TYPE tline,
        iv_textname TYPE tdobname VALUE 'Z_TEXT_FOR_LOGON', "Text created in SO10.
        lv_string   TYPE string,
        ex_lines    TYPE string.

  DATA lo_nd_data TYPE REF TO if_wd_context_node.
  DATA lo_el_data TYPE REF TO if_wd_context_element.
  DATA ls_data TYPE wd_this->element_data.

  CONSTANTS: lc_txtid(4)   TYPE c VALUE 'ST',
             lc_txtobj(10) TYPE c VALUE 'TEXT'.

      id       = lc_txtid
      name     = iv_textname
      language = sy-langu
      object   = lc_txtobj
      lines    = lt_table.

  LOOP AT lt_table INTO ls_table.
    CONCATENATE ex_lines ls_table-tdline INTO ex_lines SEPARATED BY space.

  lo_nd_data = wd_context->get_child_node( name = wd_this->wdctx_data ).
  lo_el_data = lo_nd_data->get_element( ).
    name =  'SO10TEXT'
    value = ex_lines  ).


The code calls with function module READ_TEXT the text set into Z_TEXT_FOR_LOGON and binds it to the SO10TEXT element. Remark: the formatted text in webdynpro now processes the </BR> settings.

And create the webdynpro application:

And test it:


The formatted text is processed by class CL_WD_FORMATTED_TEXT. See on this. Restrictions are listed (like no use of commands), and list of allowed tags.

Adding URL

Adding a URL to the standard text and show it in webdypro is not possible (as far as known). To add a URL, add to LinkToUrl item in the webdynpro.

Insert as launch page

Now we follow the instructions from the blog on the logon text. Start transaction SM30_SSM_CUST and set the parameter SESS_URL:

Now log on again:

Sending hyperlink in email with ABAP code

This blog will explain the ABAP code you can use to send an email from SAP system which is in HTML format including hyperlink.

Questions that will be answered in this blog are:

  • Which basis settings do I need to make for HTML mail format sending?
  • What code snippets can I re-use to send a hyperlink in an email from my custom ABAP program?

Basis settings for HTML mail

In order to be able to send an mail with a hyperlink the mail must have HTML format.

First check this table entry exists in table SXCONVERT2:

If not create it.

Now go to transaction SCOT and set the output format of RAW to HTM:

Save the settings.

ABAP code to mail hyperlink

The ABAP code to mail is as follows:

*& Report zemail_cl_bcs
  REPORT  zemail_cl_bcs.

    gc_subject TYPE so_obj_des VALUE 'ABAP Email with CL_BCS',
    gc_raw     TYPE char03 VALUE 'HTM'.

    gv_mlrec         TYPE so_obj_nam,
    gv_sent_to_all   TYPE os_boolean,
    gv_email         TYPE adr6-smtp_addr,
    gv_subject       TYPE so_obj_des,
    gv_text          TYPE bcsy_text,
    zls_text         TYPE soli,
    xhtml_string     TYPE xstring,
    gr_send_request  TYPE REF TO cl_bcs,
    gr_bcs_exception TYPE REF TO cx_bcs,
    gr_recipient     TYPE REF TO if_recipient_bcs,
    gr_sender        TYPE REF TO cl_sapuser_bcs,
    t_hex            TYPE solix_tab,
    gr_document      TYPE REF TO cl_document_bcs.

  DATA: zlv_longstring_message TYPE string.
  DATA: zlt_et_soli TYPE soli_tab.
  DATA: zls_et_soli TYPE soli.

      "Create send request
      gr_send_request = cl_bcs=>create_persistent( ).

      "Email FROM...
      gr_sender = cl_sapuser_bcs=>create( sy-uname ).
      "Add sender to send request
      CALL METHOD gr_send_request->set_sender
          i_sender = gr_sender.

      "Email TO...
      gv_email = ''.
      gr_recipient = cl_cam_address_bcs=>create_internet_address( gv_email ).
      "Add recipient to send request
      CALL METHOD gr_send_request->add_recipient
          i_recipient = gr_recipient
          i_express   = 'X'.

      CONCATENATE '<html><strong>Decission needed</strong><br/><br/>'
      '<tr><th style="color:blue;">Approval item</th>'
      '<a href=https://server:port/sap/bc/ui2/flp#WorkflowTask-displayInbox?allItems'
      '=true&/detail/XXX999_PGW/000000226597/TaskCollection(SAP__Origin=&#39;XXX999_PGW&#39;,InstanceID=&#39;000000226597&#39;)> click here to decide 000000226597</a>'

                   INTO zlv_longstring_message.

      CONCATENATE zlv_longstring_message '</html>' INTO zlv_longstring_message.

          text   = zlv_longstring_message
          buffer = xhtml_string
          failed = 1
          OTHERS = 2.

          buffer     = xhtml_string
          binary_tab = t_hex.

      gr_document = cl_document_bcs=>create_document(
                      i_type    = gc_raw
                      i_hex    = t_hex
                      i_length  = '1200'
                      i_subject = gc_subject ).
      "Add document to send request
      CALL METHOD gr_send_request->set_document( gr_document ).

* set send immediately flag
      gr_send_request->set_send_immediately( 'X' ).
      "Send email
      CALL METHOD gr_send_request->send(
          i_with_error_screen = 'X'
          result              = gv_sent_to_all ).
      IF gv_sent_to_all = 'X'.
        WRITE 'Email sent!'.

      "Commit to send email

      "Exception handling
    CATCH cx_bcs INTO gr_bcs_exception.
        'Error type:',

The end result is as follows in the mail:

The hyperlink in the mail jumps to the URL, which in this case is the URL link to this specific workflow item in the FIORI inbox.

The coding explained

We use the CL_BCS class from SAP. BCS stands for Business Communication Service. This class provides all modern options to send mail. We set the sender and receiver.

We now build the mail in HTML. All is stored in zlv_longstring_message. We start with the <html> tag, and a header text in bold (strong). Then we add the text with the hyperlink (a href) in blue color.

The hyperlink towards the FIORi inbox contains ‘ characters. This does not convert well for all further on steps. So we replace ‘ instead the &#39 text. This &#39 text is the HTML character coding for an apostrophe (‘). In this way there is no misinterpretation at any browser.

At the end, we add the closing tag </html>. Now the HTML build up is ready and can be used to send.

The HTLM is converted via function modules SCMS_STRING_TO_XSTRING and SCMS_XSTRING_TO_BINARY to a binary. This binary is set as document with type HTM to the mail. The mail is then sent with immediate flag.

SO10 standard text

With transaction SO10 you can maintain standard texts. These texts can be used in SapScript, SmartForms and your own ABAP code.

Questions that will be answered in this blog are:

  • How to create a standard text in SO10?
  • How to set default editor for SO10?
  • How to transport SO10 standard texts?
  • How to call SO10 standard text in ABAP code?
  • How to insert hyperlink into SO10 text?

Create standard text

Start transaction SO10, enter the text name and press the create button:

Now enter the text in the editor and save it:

Transporting standard texts

After saving the standard text the tool just saves the text without prompting for transport. This is as designed. The text can be maintained directly in production this way. Either by IT or even by business users.

If you do want to transport the standard texts, use program RSTXTRAN to add the standard text to the transport:

Read standard text from ABAP code

You can read the standard text from your own ABAP code by calling function module READ_TEXT

Example code:

DATA: IT_TLINES type table of TLINE.


*       CLIENT                        = SY-MANDT
        ID                            = 'ST'
        LANGUAGE                      = 'E'
        NAME                          = 'Z_DEMO_TEXT'
        OBJECT                        = 'TEXT'
*       ARCHIVE_HANDLE                = 0
*       LOCAL_CAT                     = ' '
*       HEADER                        =
        LINES                         =  IT_TLINES
*       ID                            = 1
*       LANGUAGE                      = 2
*       NAME                          = 3
*       NOT_FOUND                     = 4
*       OBJECT                        = 5
*       REFERENCE_CHECK               = 6
*       WRONG_ACCESS_TO_ARCHIVE       = 7
*       OTHERS                        = 8.

Inserting graphic in SO10

Follow the instructions in OSS note 2918753 – How to insert graphic in SO10.

Inserting hyperlink in SO10

First create hypertext in transaction SO72. Select type CHAP:

In SO10 now select the menu option Insert / Text / Hypertext:

Hyperlink is now inserted into SO10:

Changing the editor

Many people don’t like the word tool as editor. It is not precise enough. You can run program RSCPSETEDITOR to change the setting for everybody:

Untick the MS word as editor and press the Activate button.

Relevant OSS notes:

Check custom code for use of unreleased SAP objects

Custom code can use standard SAP code and SAP objects. Some of these objects might technically exist, but are in an unreleased status. This might mean SAP will not give support on them, or might remove them in a future upgrade.

Also when you want to move to the BTP ABAP cloud, you cannot use the unreleased code.

Questions that will be answered in this blog are:

  • How can I scan my custom code for use of unreleased standard SAP objects?

Tool preparation

First install the program SYCM_UPLOAD_RELEASED_OBJECTS by applying OSS note 2989803 – Check Usage of Released Objects with the Latest List of Released Objects.

And download the attached file in the same note in the attachments section;

Now run program SYCM_UPLOAD_RELEASED_OBJECTS and upload the file to a new SCI variant:

After the upload, you will find this new variant in SCI:

ATC run for unreleased code

Now you can start new ATC run with this newly created variant:

Run the variant for you custom code (can take few hours).

Result can be shown as special whitelist item: