Clean Code Guidelines in the SAPABAP environment – do I really care?

A contribution by Alexander Vogel

In 2008, Robert C. Martin wrote his book on clean code “Clean Code: Refactoring, Patterns, Testing and Techniques for Clean Code” and thus coined this term.

In April 2019, SAP introduced a Clean Code style guide for ABAP developers to use as a guide for developers and teams. This style guide is an adaptation of Robert C. Martin’s book and covers all the important points in the ABAP environment.

Today, over 2 years later we are now asking ourselves the questions “what exactly is clean code?”, “should we rebuild legacy code?” and most importantly “do we need clean code?”. We will now address these questions here and look at small examples. So …

What is Clean Code?

Clean Code is not a strict set of rules, rather a philosophy guided by the following principles:

/ KISS (Keep it simple, stupid)
Keep your code simple. One method should do one thing at a time.

/ DRY (Don’t repeat yourself)
Do not repeat your code. Store it in a method to use it again.

/ YAGNI (You aren’t gonna need it)
Do not introduce additional functionality until you need it.

/ Readability before conciseness (Readability before conciseness)
Others should be able to understand your code – as soon as possible!

It is advisable to start with simple points, such as applying the KISS principle and breaking down methods to individual activities. Reduce the complexity and check if the code is not easier to present.

Nice… is there also an example?

We look at two code snippets with ultimately the same effect. The second snippet shows the clean code approach, which is much easier to read – most clearly illustrated in the “add_mail” method.

What do we change in the legacy code, apart from the above rules, to get to Clean Code:

Hungarian notation

In the 1990s, Charles Simonyi invented the Hungarian notation in which variables were prefixed to show their origin and data type. In addition, variables were kept as short as possible to be efficient for the compilers. Declarations of variables were mostly provided with comments to express what the variable does.

Since we have access to more efficient, faster and better compilers nowadays, we can do without this and name the variables directly after what they are supposed to do.

Naming – basic rules


Small scope -> Short variable name

Large scope -> Long variable name


Small scope -> Long name & Private

Large scope -> Short name & if applicable Public

IF statements

The nesting of IF-statements should be kept as small as possible to keep the overview. If several cases of “IF / IFELSE / ELSE” should be used, one should fall back to the KISS rule and if necessary extract several methods from it.

Field symbols or references?

This point is currently still under discussion, the guidelines suggest a syntax à la LOOP … REFERENCE INTO DATA(…). before. However, if you use field symbols (à la LOOP … ASSIGNING FIELD-SYMBOL().) this benefits the runtime. Here there is an improvement of up to 13%!

Avoid loops

Loops – especially loop in loop – should be avoided as much as possible, as they result in extreme running times. If only one entry is required, the line can be selected directly.


Better than looping to get a single row is READ TABLE. However, direct access to the row of the table is even better. Here is an example:

    DATA(row) = my_table[ key = input ].
CATCH cx_sy_itab_line_not_found.
    " Do something 

Example Legacy Code

Here is finally some code, but legacy code is not really “pretty”, well readable and not maintainable:

DATA: gt_pernr_tab TYPE TABLE OF pernr_d,
      gs_pernr     TYPE pernr_d,
      gs_pa0001    TYPE pa0001,
      gt_pa0001    TYPE TABLE OF pa0001,
      gs_pa0002    TYPE pa0002,
      gs_pa0105    TYPE pa0105.

LOOP AT gt_pernr_tab INTO gs_pernr.

  SELECT * FROM pa0001
    APPENDING TABLE gt_pa0001
    WHERE pernr EQ gs_pernr
      AND begda LE sy-datum
      AND endda GE sy-datum.


SORT gt_pa0001 BY pernr begda.

LOOP AT gt_pa0001 INTO gs_pa0001.

    INTO gs_pa0002
    WHERE pernr EQ gs_pa0001-pernr
      AND begda LE sy-datum
      AND endda GE sy-datum.

  IF sy-subrc EQ 0.

      INTO gs_pa0105
      WHERE pernr EQ gs_pa0001-pernr
        AND subty EQ '0010'
        AND begda LE sy-datum
        AND endda GE sy-datum.

    IF sy-subrc NE 0.
      MOVE-CORRESPONDING gs_pa0001 TO gs_pa0105.
      CONCATENATE gs_pa0002-vorna '.' gs_pa0002-nachn '@mail.test' INTO gs_pa0105-usrid_long.

      INSERT pa0105 FROM gs_pa0105.


Clean Code Example

In contrast, clean code can be read, maintained and understood very well. It’s best when you can read it like prose. For the representation as clean code I have chosen here the form of a class with methods:


    METHODS: add_mails           IMPORTING i_personnel_numbers     TYPE pernr_tab.

      add_mail                   IMPORTING i_personnel_number      TYPE pernr_d,
      read_personal_data         IMPORTING i_personnel_number      TYPE pernr_d
                                 RETURNING VALUE(r_personnel_data) TYPE pa0002,
      does_mail_already_exist    IMPORTING i_personnel_number TYPE pernr_d
                                 RETURNING VALUE(r_exists)    TYPE boolean,
      write_new_mail_to_database IMPORTING i_personnel_data        TYPE pa0002.

  METHOD add_mails.
    LOOP AT i_personnel_numbers ASSIGNING FIELD-SYMBOL(<personnel_number>).
      add_mail( <personnel_number> ).

  METHOD add_mail.
    DATA(personnel_data) = read_personal_data( i_personnel_number ).

    IF does_mail_already_exist( i_personnel_number ).
      write_new_mail_to_database( personnel_data ).

  METHOD read_personal_data.
      INTO r_personnel_data
      WHERE pernr EQ i_personnel_number
        AND begda LE sy-datum
        AND endda GE sy-datum.

  METHOD does_mail_already_exist.
    CONSTANTS: mail_subtyp TYPE subty VALUE '0010'.
    DATA: exists(1).

      INTO @exists
      WHERE pernr EQ @i_personnel_number
        AND subty EQ @mail_subtyp
        AND begda LE @sy-datum
        AND endda GE @sy-datum.

    IF sy-subrc EQ 0 AND exists EQ 'X'.
      r_exists = abap_true.
      r_exists = abap_false.

  METHOD write_new_mail_to_database.
    DATA(communication) = CORRESPONDING pa0105( i_personnel_data ).
    communication-usrid_long =
      |{ i_personnel_data-vorna }.{ i_personnel_data-nachn }@mail.test|.

    INSERT pa0105 FROM communication.

What do we do with legacy projects?

SAP recommends the following four-step plan in its style guide for legacy projects:

  1. Get the team on board. Communicate and explain the new style, and make sure every member of the project team agrees. You don’t have to write down all the policies at once. Just start with a small undisputed sub-area and develop from there.
  2. In your daily work routine, follow the Boy Scout rule of “leave the campsite cleaner than you found it.” In terms of clean code:Always leave the code better than you found it. Don’t overdo it by spending hours “cleaning up the entire campsite.” Just spend a few extra minutes and watch the improvements accumulate over time.
  3. Build clean islands from time to time: Select a small object or component and try to make it “clean” in all aspects. These islands demonstrate the utility of what you are doing and provide a reliably tested basis for further refactoring.
  4. Talk about it. Whether you’re setting up old-school Fagan code inspections, or hosting info sessions or forum discussions in your favorite chat tool: You need to talk about your experiences and what you’ve learned so that a common understanding can grow within your team.

So, when we replace old code, we should do it step by step and look for small “islands”, so that over time, all the coding can be converted to clean code.
So if you are bug fixing, you should change this place directly to clean code to avoid duplicate work. Again as a short rule of thumb: Bugfixing only in clean code.

So then… do we need clean code?

Short answer: YES!

Longer answer: Definitely! Because we make our code more readable – for us and others. The code becomes maintainable and reusable, and most importantly, more stable! A method treats, ideally only one thing and describes itself. Thus, for example, comments are invalid or a bug fix does not accidentally damage another part of the software.

Cheat Sheet & Golden Rules

Finally, here are the SAP cheat sheets for Clean Code, as well as the golden rules that SAP issues for this. They are not 100% complete, but give a very good overview of the subject. This way, each team member can quickly learn the most important points. It is best to download this directly as sources for better readability:

Clean ABAP Cheat Sheet

Clean ABAP the Golden Rules

The easiest address for good code: SAP Gold Partner

How convenient that we are one. Our SAP division is made up of highly motivated experts in consulting and development who do awesome shit with SAP SuccessFactors, HCM and 4HANA for our customers. Together, we managed to achieve the SAP Gold Partnership in just under a year.

We look forward to your ideas, questions and project suggestions. Just send us a mail to

The author