Interactive Reports: The SY-LISEL Way (Program 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.
| List | Created by | sy-lsind |
|---|---|---|
| Basic list | START-OF-SELECTION | 0 |
| First detail list | First double-click | 1 |
| Second detail list | Double-click inside list 1 | 2 |
The user returns to the previous list with the green Back arrow (F3). A report can hold up to 20 detail lists.
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:
| Field | Content |
|---|---|
sy-lisel | The full text of the clicked line, as one string (up to 255 characters) |
sy-lilli | The line number that was clicked |
sy-lsind | The current list level |
sy-curow / sy-cucol | Row 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.
- 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:
WRITEshows4970but the database holds0000004970. - 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 database | 0000004970 |
Shown on the list (and in sy-lisel) | 4970 |
After CONVERSION_EXIT_ALPHA_INPUT | 0000004970 |
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.
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-lilliin the detail list. - Add a third level: double-click an item to show the material description from
MAKT. Checksy-lsind. - Remove the
CNcheck 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
SELECTfinds 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-SELECTIONinstead ofAT LINE-SELECTION. - Ignoring
sy-subrc. An order without items shows an empty list with no explanation. - Relying on
sy-liselfor 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.
WhatsApp us