Fair thee well DESCRIBE TABLE. And good riddance.

images/thumbnail.jpg - Thumbnail

For twelve long years When I wanted to count The lines of an itab I did what everyone does: DESCRIBE TABLE itab LINES linhas.

Until the other day When (my eyes didn’t deceive me) I saw something so new, You wouldn’t believe me: LINES( itab ).

It gives the same outcome And does away with declaring The damn variable.

So instead of:

DATA: linhas TYPE i.
DESCRIBE TABLE itabl LINES linhas.
IF linhas = 42.
  WRITE 'A tua tabela é a verdade'.
ENDIF.

Just do this:

The drag queen message

images/thumbnail.jpg - Thumbnail

The AT SELECTION-SCREEN modules of a report can throw error messages and send you back to the selection screen. But once you get past the START-OF-SELECTION, if you get an error message, the program ends. The solution to getting an error and returning to the selection screen, is to disguise the message:

START-OF-SELECTION.
  IF condicao_desejada.
    MESSAGE S208(00) with 'Erro!' DISPLAY LIKE 'E'.
    EXIT.
  ENDIF.
  WRITE 'Olá, eu sou o resto do programa'.

The type S message pretended to be type E. It seemed to be E - but it was joking.

The round-about routes of VALUE CHECK

images/thumbnail.jpg - Thumbnail

Have you ever come up against something in ABAP that seems to be one thing but is in fact another? The documentation says it is this and everything seems to indicate that it is, but after all it isn’t.

You’ve probably needed to, when setting a parameter in the report selection screen, check the possibilities of what the user can input to the available values in the data type of that parameter, right? VALUE CHECK exists for this. It seems simple. For example, it was assumed that the following might work:

Stand up, all victims of oppression

images/thumbnail.jpg - Thumbnail

Classes. They have always existed among people. But there are still few who take them into consideration in ABAP. While being a supporter of classes in society can result in pedantry, the only class struggle in ABAP is that some fight for them to be used more.

There are two types of classes: global and local. The global ones are created in the SE24 transaction. Local classes, which by the way I find myself using more and more, are done declaratively in SE38. If we know that our class is going to be frequently used it makes sense to create it globally. If, on the other hand, the class is specific to a program, it is not worth making it an autonomous object, it just needs to be built locally for the program that is going to use it.

SPLIT INTO TABLE

images/thumbnail.jpg - Thumbnail

I’m going to show you a creative way of filling out an internal table with constants that I learned in a standard program. Imagine you want to create an internal table with the following kinds of financial documents:

AB AF CH DG DZ EX F3 F4.

The more conventional way would be this:

DATA: t_blart TYPE STANDARD TABLE OF blart,
      wa_blart LIKE LINE OF t_blart.

wa_blart = 'AB'.
APPEND wa_blart TO t_blart.
wa_blart = 'AF'.
APPEND wa_blart TO t_blart.
wa_blart = 'CH'.
APPEND wa_blart TO t_blart.
wa_blart = 'DG'.
APPEND wa_blart TO t_blart.
wa_blart = 'DZ'.
APPEND wa_blart TO t_blart.
wa_blart = 'EX'.
APPEND wa_blart TO t_blart.
wa_blart = 'F3'.
APPEND wa_blart TO t_blart.
wa_blart = 'F4'.
APPEND wa_blart TO t_blart.

But there is a much more concise and neat way:

Unparameterisable parameters

images/thumbnail.jpg - Thumbnail

Every now and then you get a client who asks a programmer to create a write-protected parameter on the program selection screen. It’s a bit dumb given that the whole idea of parameters is that they are parameterisable.

But there you go, it takes all sorts.

Clients have so much imagination that SAP should create a cinema module, SAP CI, especially so they can screen all the films they carry around in their heads. I am sure some real sci-fi blockbusters would come out of it. And a few comedies too.

Upside down CASE

images/thumbnail.jpg - Thumbnail

What is your favourite colour?

SELECTION-SCREEN BEGIN OF BLOCK b1.
PARAMETERS: p_azul BUTTONGROUP GROUP COR DEFAULT 'X',
            p_verde BUTTONGROUP GROUP COR,
            p_roxo BUTTONGROUP GROUP COR.
SELECTION-SCREEN END OF BLOCK b1.

If you said ‘blue’ you live and can cross the bridge.

In any case, the following normally happens in ABAP to discover the colour the user chose:

IF p_azul = 'X'.
  lv_cor = 'AZUL'.
ELSE IF p_verde = 'X'.
  lv_cor = 'VERDE'.
ELSE IF p_roxo = 'X'.
  lv_cor = 'ROXO'.
ENDIF.

But there is a curious and far more elegant way to do the same thing. This is what we call upside down CASE:

The *_SINGLE_READ functions

images/thumbnail.jpg - Thumbnail

When you need to derive a single record from a database table, you normally use SELECT SINGLE, which is like this in its most basic form, as everyone knows:

SELECT SINGLE *
  FROM KNA1
  WHERE KUNNR = '1234567890'.

Of course, if you are interested in just a few fields, ideally you select them explicitly to avoid copying unnecessary data from one side to the other:

DATA: lv_name1 TYPE name1.

SELECT SINGLE name1 INTO lv_name1
  FROM KNA1
  WHERE KUNNR = '1234567890'.

But this is all obvious and I am rambling as none of this is what brings me to this subject today. Today I want to talk about the valuable standard functions that replace SELECT SINGLE. Many of SAP’s main tables have functions that replace it as their job is precisely to derive records from those tables. For example, the function to derive a record of KNA1 is called KNA1_SINGLE_READ:

Instant RANGE - just add water

images/thumbnail.jpg - Thumbnail

I’m going to teach you a magic formula for creating a RANGE that is almost as easy as just adding water.

Imagine that you want to create a RANGE from a database selection to then use it in another SELECT. Obviously you can do it like this:

DATA: lt_kunnr TYPE STANDARD TABLE OF kunnr,
        lr_kunnr TYPE RANGE OF kunnr,
        wa_kunnr LIKE LINE OF lr_kunnr.
FIELD-SYMBOLS: <kunnr> LIKE LINE OF lt_kunnr.

SELECT kunnr
  INTO TABLE lt_kunnr
  FROM kna1.

wa_kunnr-sign = 'I'.
wa_kunnr-option = 'EQ'.
LOOP AT lt_kunnr ASSIGNING <kunnr>.
  wa_kunnr-low = <kunnr>.
  APPEND wa_kunnr TO lr_kunnr.
ENDLOOP.

And here you used 15 lines of code and 4 variables. But now look at this alternative:

LOOP ASSIGNING instead of LOOP INTO

images/thumbnail.jpg - Thumbnail

In the beginning there was INTO. Actually, in the beginning it was not even INTO.