Interactive Reports — The SY-LISEL Way (Program 4)

Interactive Reports: The SY-LISEL Way (Program 4)
ABAP Reports Series · Blog 8 of 15

Interactive Reports: The SY-LISEL Way (Program 4)

Intermediate · 14 min read · Needs Blogs 3 and 4

1. What is an interactive report?

A normal report shows a list and ends. An interactive report lets the user act on the list. The classic pattern is drill-down: a summary list first, then a detail list when the user double-clicks a line.

ListCreated bysy-lsind
Basic listSTART-OF-SELECTION0
First detail listFirst double-click1
Second detail listDouble-click inside list 12

The user returns to the previous list with the green Back arrow (F3). A report can hold up to 20 detail lists.

Classical lists only

This blog and the next one use WRITE lists. An ALV grid handles clicks differently, which Blog 10 covers.

2. AT LINE-SELECTION: the event

When the user double-clicks a line (or presses F2 on it), ABAP triggers the event AT LINE-SELECTION. Anything you WRITE inside it becomes the next list.

START-OF-SELECTION.
  WRITE: / 'This is the basic list'.

AT LINE-SELECTION.
  WRITE: / 'You double-clicked a line'.

Output written under START-OF-SELECTION appears first. The code under AT LINE-SELECTION runs only after a click.

3. SY-LISEL: the whole line as a string

To know which line was clicked, ABAP fills a few system fields:

FieldContent
sy-liselThe full text of the clicked line, as one string (up to 255 characters)
sy-lilliThe line number that was clicked
sy-lsindThe current list level
sy-curow / sy-cucolRow and column of the cursor

With sy-lisel you cut the value you need out of the line by its position, using an offset:

" Take 10 characters, starting after the first character
lv_text = sy-lisel+1(10).

Offsets start at 0. So +1(10) means skip 1 character, take 10.

4. The fragility problem

This method works only as long as the list layout never changes. The program guesses where the value sits inside the text line.

What breaks it
  • Adding or moving a column shifts every position.
  • Changing a field length changes the offsets.
  • The same program shows different text per user setting (date format, decimals).
  • Leading zeros: WRITE shows 4970 but the database holds 0000004970.
  • A line longer than 255 characters is cut off in sy-lisel.
  • The user can click a header or separator line, which holds no data.

Every one of these fails silently: you read the wrong characters, and the next SELECT finds nothing or the wrong record. Blog 9 shows a sturdier method. Still, you will meet sy-lisel in a lot of existing code, so you should be able to read and fix it.

5. Program 4: full code

A list of sales orders. Double-click an order to see its items.

REPORT zlist_sylisel.

TYPES: BEGIN OF ty_order,
         vbeln TYPE vbak-vbeln,
         erdat TYPE vbak-erdat,
         ernam TYPE vbak-ernam,
         netwr TYPE vbak-netwr,
         waerk TYPE vbak-waerk,
       END OF ty_order.

DATA: gt_orders TYPE STANDARD TABLE OF ty_order WITH DEFAULT KEY,
      gv_erdat  TYPE vbak-erdat.

SELECT-OPTIONS s_erdat FOR gv_erdat.
PARAMETERS     p_max   TYPE i DEFAULT 50.

INITIALIZATION.
  s_erdat-sign   = 'I'.
  s_erdat-option = 'BT'.
  s_erdat-low    = sy-datum - 30.
  s_erdat-high   = sy-datum.
  APPEND s_erdat.

*---------------------------------------------------------------------*
* Basic list
*---------------------------------------------------------------------*
START-OF-SELECTION.
  SELECT vbeln, erdat, ernam, netwr, waerk
    FROM vbak
    WHERE erdat IN @s_erdat
    ORDER BY erdat DESCENDING, vbeln
    INTO TABLE @gt_orders
    UP TO @p_max ROWS.

  IF sy-subrc <> 0.
    MESSAGE 'No sales orders found for your selection'
            TYPE 'S' DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.

  PERFORM write_basic_list.

*---------------------------------------------------------------------*
* Detail list: runs when the user double-clicks a line
*---------------------------------------------------------------------*
AT LINE-SELECTION.
  PERFORM write_detail_list.

*---------------------------------------------------------------------*
FORM write_basic_list.
  FORMAT COLOR col_heading.
  WRITE: /1 sy-vline,  2(10) 'Sales Doc',  12 sy-vline,
         13(10) 'Created on', 23 sy-vline,
         24(12) 'Created by', 36 sy-vline,
         37(16) 'Net value',  53 sy-vline,
         54(5)  'Curr.',      59 sy-vline.
  FORMAT COLOR OFF.
  ULINE /1(59).

  LOOP AT gt_orders INTO DATA(ls_order).
    WRITE: /1 sy-vline,
           2(10) ls_order-vbeln COLOR col_key HOTSPOT ON,
           12 sy-vline,
           13(10) ls_order-erdat, 23 sy-vline,
           24(12) ls_order-ernam, 36 sy-vline,
           37(16) ls_order-netwr CURRENCY ls_order-waerk, 53 sy-vline,
           54(5)  ls_order-waerk, 59 sy-vline.
  ENDLOOP.
  ULINE /1(59).
ENDFORM.

*---------------------------------------------------------------------*
FORM write_detail_list.
  DATA: lv_text  TYPE c LENGTH 10,
        lv_vbeln TYPE vbak-vbeln.

  " 1. Cut the order number out of the clicked line
  lv_text = sy-lisel+1(10).

  " 2. Make sure the user clicked a data line
  IF lv_text IS INITIAL OR lv_text CN '0123456789 '.
    MESSAGE 'Double-click on an order line' TYPE 'S' DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.

  " 3. Restore the leading zeros the database expects
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING input  = lv_text
    IMPORTING output = lv_vbeln.

  " 4. Read the items of that order
  SELECT posnr, matnr, kwmeng, netwr, waerk
    FROM vbap
    WHERE vbeln = @lv_vbeln
    ORDER BY posnr
    INTO TABLE @DATA(lt_items).

  " 5. Write the secondary list
  WRITE: / 'Items of order', lv_text.
  ULINE.

  IF lt_items IS INITIAL.
    WRITE: / 'This order has no items'.
    RETURN.
  ENDIF.

  LOOP AT lt_items INTO DATA(ls_item).
    WRITE: / ls_item-posnr, ls_item-matnr,
             ls_item-kwmeng, ls_item-netwr CURRENCY ls_item-waerk,
             ls_item-waerk.
  ENDLOOP.
ENDFORM.

6. CONVERSION_EXIT_ALPHA_INPUT: why?

The order number is stored as 0000004970, but WRITE shows it without the leading zeros, as 4970. So sy-lisel contains 4970. If you search the database with that text, nothing matches.

Value
Stored in the database0000004970
Shown on the list (and in sy-lisel)4970
After CONVERSION_EXIT_ALPHA_INPUT0000004970

The function module does the reverse of the display conversion: it pads a number with zeros up to the full field length. Text values that are not purely numeric stay as they are.

Modern alternative

On ABAP 7.40 and newer you can do the same with a string template: lv_vbeln = |{ lv_text ALPHA = IN }|.

7. The secondary list

This is what the user sees. First the basic list:

|Sales Doc |Created on|Created by  |Net value       |Curr.|
-----------------------------------------------------------
|4971      |30.10.2026|SALES01     |       12,500.00|INR  |
|4970      |28.10.2026|SALES02     |        8,200.00|INR  |
|4969      |25.10.2026|SALES01     |        1,450.00|INR  |

After a double-click on the second line:

Items of order 4970
-----------------------------------------------------------
000010 MAT-100               5      4,100.00 INR
000020 MAT-250               2      4,100.00 INR

Press Back (F3) to return. Values will differ in your system.

8. Try it yourself

  • Insert a new column before Sales Doc without updating the offset. Watch the detail list break.
  • Show the clicked line number with WRITE: / sy-lilli in the detail list.
  • Add a third level: double-click an item to show the material description from MAKT. Check sy-lsind.
  • Remove the CN check and click a separator line. See what happens.
  • Change the display date format in your user settings (SU3) and re-run the report.

9. Common mistakes

  • Hard-coded offsets that no longer match after a layout change.
  • Forgetting the leading zeros. The SELECT finds nothing.
  • No check for a valid line. A click on a heading or border reads junk.
  • Counting offsets from 1. They start at 0.
  • Reading the database in the basic list for every row instead of once. Select the detail only when the user clicks.
  • Writing detail output under START-OF-SELECTION instead of AT LINE-SELECTION.
  • Ignoring sy-subrc. An order without items shows an empty list with no explanation.
  • Relying on sy-lisel for numbers that are formatted with separators or decimals.

Up next: Blog 9

Interactive Reports, the GET CURSOR way. Read the clicked field directly, by name, with no guessing about positions.

ABAP Reports: Zero to Hero · Blog 8 of 15
WhatsApp WhatsApp us
Call Now Button