Skip to Content

Hello,

I often met ABAP developers with different opinions about using macros. Almost everyone uses the BREAK macro (defined in table TRMAC), but when it is about writing and using their own macros positions sometimes differ.

Let me discuss some of the advantages and disadvantages macros have and what my conclusions are.

Pro: Code Less

When using macros the most obvious advantage is that you have to code less, for phrases often used in some code can be put into the macro. But compared to other activities in the software cycle this is not really a big advantage.

Con: No Debugging

Once you tried to debug the code of a macro you realised that this was not possible. Because of this I never put complex logic into a macro. While in the development system you still have the chance to replace the macro with the actual code if something strange happens you will not get that chance in the acceptance or production system. So even if you are not a member of production support we should have some  sympathy with those in production support.

Pro: Better Readability of Code 

Using Macros can make your program code more readable, which is, to me, the main reason for using macros. I want to show this in a small example.

Consider we want to display a small tree using the simple tree control (CL_GUI_SIMPLE_TREE). In order to easily add entries to the nodes table we have to build we create a small method ADD_NODE having this interface:

image

and this is the code of the method:

method add_node.

data: node type mtreesnode.

node-node_key = node_key.
node-relatkey = relatkey.
node-relatship = relatship.
node-isfolder = isfolder.
node-text = text.
insert node into table nodes.

endmethod.

We call this method several times to create our node table.

This is the coding without using macros:

method create_tree_folders.

data: nodes type svmcrt_tree_node_tab.

add_node( exporting node_key = 'ROOT'
             relatkey = space
                    relatship = 0
                    isfolder = abap_true
                    text = 'All entries'(001)
          changing nodes = nodes ).
add_node( exporting node_key = 'ITEMTYPE1'
                    relatkey = 'ROOT'
                    relatship = cl_gui_simple_tree=>relat_first_child
                    isfolder = abap_true
                    text = 'Type 1 entries'(002)
          changing nodes = nodes ).
add_node( exporting node_key = 'ITEMTYPE2'
                    relatkey = 'ITEMTYPE1'
                    relatship = cl_gui_simple_tree=>relat_first_sibling
                    isfolder = abap_true
                    text = 'Type 2 entries'(003)
          changing nodes = nodes ).
tree->add_nodes( exporting table_structure_name = 'MTREESNODE'
                           node_table = nodes
                 exceptions error_in_node_table = 1
                            failed = 2
                            dp_error = 3
                            table_structure_name_not_found = 4
                            others = 5 ).
if sy-subrc <> 0.
        " too bad, do some error handling
endif.

endmethod.

And this is the method using a macro:

method create_tree_folders.

data: nodes type svmcrt_tree_node_tab.

" node key rel. key relationship
" folder? text
add_node: 'ROOT' space 0
abap_true 'All entries'(001),
'ITEMTYPE1' 'ROOT' cl_gui_simple_tree=>relat_first_child
abap_true 'Type 1 entries'(002),
'ITEMTYPE2' 'ITEMTYPE1' cl_gui_simple_tree=>relat_first_sibling
abap_true 'Type 2 entries'(003).
tree->add_nodes( exporting table_structure_name = 'MTREESNODE'
node_table = nodes
exceptions error_in_node_table = 1
failed = 2
dp_error = 3
table_structure_name_not_found = 4
others = 5 ).
if sy-subrc <> 0.
" too bad, do some error handling
endif.

endmethod.

The used macro is:

define add_node.
add_node( exporting node_key = &1
relatkey = &2
relatship = &3
isfolder = &4
text = &5
changing nodes = nodes ).
end-of-definition.

You might wonder why I need the method ADD_NODE if I could easily put the methods code into the macro. The answer is: today the code to add a line into the nodes table is quite simple. But maybe later you want to add some logic when adding a node line – perhaps some special nodes should be hidden (e. g. depending on the text). Then the logic can become more complex (remember the debugging issue) or you might need some local variables. By that time it is good to have that method already.

Some macros I often use

Over the years I collected a set of macros I frequently use. They are quite easy to understand so I list them here without any explanation.

Actually they are the sort of ‘code less’ macros and do not provide that much readability to the program, but since the code pieces are used so many times I thought it to be worth having them.

*-----------------------------------------------------------------------
define inc.
        &1 = &1 + 1.
end-of-definition.

*-----------------------------------------------------------------------
define dec.
        &1 = &1 - 1.
end-of-definition.

*-----------------------------------------------------------------------
define plus.
        &1 = &1 + &2.
end-of-definition.

*-----------------------------------------------------------------------
define minus.
        &1 = &1 - &2.
end-of-definition.

*-----------------------------------------------------------------------
define mult.
        &1 = &1 * &2.
end-of-definition.

*-----------------------------------------------------------------------
define divd.
        &1 = &1 / &2.
end-of-definition.

*-----------------------------------------------------------------------
define min.
        if &2 < &3.
                &1 = &2.
        else.
                &1 = &3.
        endif.
end-of-definition.

*-----------------------------------------------------------------------
define max.
        if &2 > &3.
                &1 = &2.
        else.
                &1 = &3.
        endif.
end-of-definition.

*-----------------------------------------------------------------------
define free_object.
        if &1 is bound.
                &1->free( ).
        endif.
end-of-definition.

*-----------------------------------------------------------------------
define line.
        selection-screen begin of line.
end-of-definition.

*-----------------------------------------------------------------------
define endline.
        selection-screen end of line.
end-of-definition.

*-----------------------------------------------------------------------
define block.
        selection-screen begin of block &1 with frame title &2.
end-of-definition.

*-----------------------------------------------------------------------
define endblock.
        selection-screen end of block &1.
end-of-definition.
To report this post you need to login first.

18 Comments

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

  1. Thomas Jung
    Its funny but your example you use to show that Macros make your code more readable actually seems to me that it is less readable.

    add_node: ‘ROOT’       space        0                       abap_true       ‘All entries'(001),

    In this case what are the importing parameters?  What are they mapped to?  What are the expected parameters?  Someone looking at this without knowing the inner coding of the Macro will have no idea what is going on in this code. 

    The lack of an interface to the macro leads to less readable code in my opinion.

    To me Macros are something that date back to the days before ABAP OO.  Today I would much rather use a functional static method – particularly now that we have code completion and statement chaining in ABAP 7.02/7.10+ – something not supported by macros.

    (0) 
    1. Gerd Rother Post author
      Hi Thomas,

      Thank you for your comment.

      For knowing what the actual parameters mean I put a comment right before the macro usage:
      ”         node key     rel. key     relationship
      ”                      folder?         text

      Writing this in a more compact way let the reader see what nodes are added here and what their attributes are. Without the macro the text to read is more chatty which in my humble opinion makes it harder to extract the code’s essence.
      But I do agree – without knowing the content of the macro it is hard to follow the code (therefore it is good to have descriptive macro names).
      Once you know that the macro just adds the node with the listed attributes to the node table I still think the shorter code is the clearer one.
      By the way, when writing C++ or Java programs you also just pass the parameters without naming the (internal) function parameters and the mapping to them. Of course, showing the JavaDoc in Eclipse is actually a big help here.

      This statement chaining you mentioned sounds promising.
      Now that I heard of it I looked for it in SDN and had a quick view into your presentation. That all really looks good; I will have a closer look into that.

      Cheers, Gerd

      (0) 
      1. Alejandro Bindi
        I agree with Thomas regarding readability on your particular example, plus as you said you wouldn’t be able to debug.

        Yet I think the best usage for macros is for repetitive appending to tables, for example in building a layout for an ALV. You avoid having the workarea name and APPEND/CLEAR sentences repeated all along the routine code, enhancing readability. So, I think macros are still useful in certain, specific cases.

        Even then, an OO alternative would be to encapsulate the internal table as an object attribute and create an “APPEND” method with a local workarea (but not everyone is confortable enough with OO yet)

        (0) 
        1. Gerd Rother Post author
          Thank you for your comment.

          Actually my example is such a repetitive appending to a table – in the method nothing else is done. The actual resulting code using a macro which directly appends into the internal table would be exactly the same as my example – just the macro would not contain a method call but some MOVEs and the APPEND/INSERT.

          Cheers, Gerd

          (0) 
    2. SAP Questions
      I agree with Thomas.

      In my opinion, in ABAP OO macros would be replaced by methods which make the coding more elegant and easy to understand/debug. I don’t see why people insists in the idea of using the old ABAP style instead of moving to ABAP OO.

      The only “benefit” (if it can be considered a benefit) I can see in a macro is the fact you could make life miserable for a developer that tries to debug your code but the question is “why would you like to do something like that?”.

      Cheers.

      (0) 
  2. Martin Voros
    Hi,

    I guess that everyone will agree that code readability is partly subjective thing. But my question is different. Does it really matter to increase readability using macros? Good developers split logic into small chunks. In your example you have methods add_node and create_tree_folders. How often are you going to read/modify method create_tree_folders? I guess almost never. So I don’t see any value. I used to use macros in reports but don’t do it anymore in OO.

    I am really looking forward to command chaining. Especially in web dynpro, it will significantly reduce boilerplate.

    Cheers

    (0) 
    1. Gerd Rother Post author
      Martin,

      Thank you for your comment.

      Yes, readability surely is subjective.

      To me it is not just about later changes of the code, it is also important for maintenance. When you hunt a bug through the jungle of foreign source code it is good to have code which is easy to read.

      But perhaps my opinion of using macros is a bit old-fashioned and I have to re-think it. Using other languages not having this feature I actually do not miss it (like in Java).
      Functional methods made a lot to get rid of the necessity of using such language features – statement chaining will definitely help on this way.

      Cheers, Gerd

      (0) 
      1. Martin Voros
        I agree that code readability is really important for maintainability. But again I think that more important is to split your code into smaller chunks. If your code is well structured, splitted into smaller chhunks and you avoid code duplication then you don’t need to go trough whole code. Let say that users reported error in your program. It does not perform posting anymore. Probably, you won’t look at the methods related to UI with names like create_tree_folders. 

        Cheers

        (0) 
  3. Paul Hardy
    I notice in the official ABAP Programming Guidelines Horst Keller says that Macros are Ok to use in some circumstances. I tend to avoid them unless there are dozens of almost identical patterns which just obscure the purpose of the routine. In your example you could do the method in full once so a reader could see the paramater names and then use a macro for subsequent additions to the table.
    I have always wondered, since developers are bound to encounter macros sooner or later, they are even in some standard SAP programs, why SAP doesn’t change the runtime environment so that you CAN debug macros? I don’t expect that to ever happen, but that would change the equation. This is rather like the “FOR ALL ENTRIES” with an mepty table bug – most developers know not to pass an empty table to a FOR ALL ENTRIES statement because the ABAP runtime treats this incorrectly, but SAP are never going to fix what is clearly an error but instead use the ever popular “don;t fix the problem – document it” technique. That was a bit of a diversion from macros.
    (0) 
  4. Vijay Vijayasankar
    That is the most fun I had with macros in my early ABAP days. I used to have a Z include with many common utilities that I had macros for. And you can drive the lesser experienced ABAPers go nuts thinking WIPE (refresh/free/clear combo for an internal table) is an actual ABAP command.

    I forgot how exactly I did it – but I also remember using macros to mask some of the RFC interfaces to legacy systems.

    But all said and done – in hind sight, I think I should not have used macros at all. It is a production support nightmare. And at some point, I had explicitly asked my team to not use any macros.

    (0) 
  5. Harald Boeing
    I agree with all the previous posters who indicate it’s better not to use macros…

    In the end the code should be correct, efficient and maintainable. ABAP is by design a verbose language and ideally one structures the code into smaller parts (be it forms or methods). By choosing macros for structuring your code, you loose the strong static typing, which aids in more than just preventing on big class of errors. I.e. in modern IDE’s the code completion often relies heavily in being able to have knowledge on types (admittedly we always seem behind in ABAP)…

    Furthermore I fail to see how your macros increase readability. To me a macro call like “minus a b c” is counter-intuitive. Polish notation like “minus b c” makes sense, but I’ve yet to see a programming language that combines assignments and arithmetic expressions the way you define them.

    ABAP does not have the features to easily introduce new DSLs or extend the language itself; I don’t think anybody would consider macro usage appropriate for that.

    So I have yet to see a compelling reason for use of macros. No offense, but my general recommendation is “don’t use them” as one step for creating better programs.

    (0) 
    1. Gerd Rother Post author
      Harald,

      Thank you for your supply.
      Sure – the minus is a strange thing while inc (increment) is pretty common. I wonder if SAP will add operators like ++ and += to their language.

      One objection, though: by using macros you do not lose static typing for it is just a text replacement before the compile step – any type errors are reported as usual – they just might be harder to find.

      Regards, Gerd

      (0) 
  6. Chris Paine
    Hi,

    strangely enough I would look at your pros – call them all cons, and the con – call it a pro.

    The ONLY time I’ve considered using a macro is to encapsulate some code that I’ve not wanted people to get around using debug ( code for checking if the installation of SAP that the code was running on was licenced for the system it was running on for example). (Obviously if you’re good enough, you can get around anything – but it stops some unauthorised use).

    In every other case, I think macros confuse code, make it harder to read, organise and check.

    If I see a standard macro used in code it’s usually my first hint that there is a newer and better way of writing that code that I should be looking for…

    However, an interesting and provoking blog 🙂

    Cheers,

    Chris

    (0) 
    1. Gerd Rother Post author
      Hi Chris,

      Thank you.
      Pretty funny how opinions differ at this topic. And I guess if you ask one of the developers of the business object repository (package SWO) you might hear one more opinion.

      Regards, Gerd Rother

      (0) 
  7. Rainer Hübenthal
    Hi Gerd,

    thanks for your blog, i agree on your opinion, but i have some problems with some of your macros.

    inc and dec might be ok, but i cant see any advantage of this. I have more problems with your plus and minus macros, cause i cant see really any advantage, plus a b c is being typed as fast as a = b + c. And with the new editor and the type-ahead there is no need for abbreviations. If this is common in a company, ok, but when someone comes in out company with something like this i’m not letting pass this report through the quality assurance step.

    i’m limiting down macros when it comes to fill internal tables. first you have to clear the workarea, then you have to fill all the comnponents and finally append the workarea to an internal table.

    Here a macro makes life easier and the code becomes more readable.

    (0) 
    1. Gerd Rother Post author
      Hi Rainer,

      Those macros came more from the C/Java experience where you have a += and -=.
      BTW, it is not ‘plus a b c’ vs. ‘a = b + c’ (this indeed would be stupid), it is ‘plus a b’ vs. ‘a = a + b’.

      Regards, Gerd

      (0) 

Leave a Reply