Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
gerd_rother
Active Participant

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:

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.
18 Comments