Dynamic Selection Screens with LOOP AT SCREEN (Program 3)
1. Why dynamic selection screens?
A report with many options gets crowded. If a user only wants order headers, why show filters for items? A dynamic selection screen shows only the fields that matter for the choice the user just made.
- Cleaner screen, fewer mistakes
- One report can serve several purposes
- Hidden fields cannot filter the data by accident
The tools are three: a trigger (checkbox or radio button), a group (MODIF ID), and a loop (LOOP AT SCREEN).
2. Checkboxes as mode selectors
A normal checkbox does not talk to the program when clicked. To make the screen react, add USER-COMMAND.
PARAMETERS: p_hdr AS CHECKBOX USER-COMMAND uc1 DEFAULT 'X',
p_itm AS CHECKBOX USER-COMMAND uc2.
Without USER-COMMAND, clicking the checkbox changes nothing on screen until the user presses Enter. With it, the screen refreshes at once and AT SELECTION-SCREEN OUTPUT runs.
Radio buttons work the same way: RADIOBUTTON GROUP g1 USER-COMMAND uc on the first button of the group. Use radio buttons when only one mode may be active. Use checkboxes when several can be on together, as in this blog.
3. MODIF ID: grouping fields
MODIF ID puts a field into a named group. Later, one loop can show or hide the whole group.
SELECT-OPTIONS s_erdat FOR gv_erdat MODIF ID hdr.
SELECT-OPTIONS s_matnr FOR gv_matnr MODIF ID itm.
PARAMETERS p_qty TYPE vbap-kwmeng MODIF ID itm.
- The group name has at most 3 characters, and is written in capitals in the loop.
- It covers the input boxes and the label next to them.
- For a select-option it covers both the From and To boxes.
4. AT SELECTION-SCREEN OUTPUT: the magic event
This event runs every time the selection screen is about to be shown: the first time, and after every click that triggers a user command. It is the right place to change how fields look.
| Event | Runs | Use it for |
|---|---|---|
INITIALIZATION | Once, before the first display | Default values |
AT SELECTION-SCREEN OUTPUT | Every time the screen is drawn | Show, hide, grey out fields |
AT SELECTION-SCREEN | After user input, before the report runs | Validate input |
This event runs again and again. Never read the database or do heavy work here. Only change the screen.
5. LOOP AT SCREEN: iterating screen fields
SCREEN is a built-in table that describes every element on the screen. Loop over it, check the group, change the attributes, and save with MODIFY SCREEN.
AT SELECTION-SCREEN OUTPUT.
LOOP AT SCREEN.
IF screen-group1 = 'ITM'.
IF p_itm = abap_true.
screen-active = 1.
ELSE.
screen-active = 0.
ENDIF.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
| Field | Meaning |
|---|---|
screen-name | Name of the element, for example S_MATNR-LOW |
screen-group1 | The MODIF ID group |
screen-active | 1 shown, 0 hidden completely |
screen-input | 1 editable, 0 greyed out (display only) |
screen-invisible | 1 shows the box but hides what is typed |
screen-required | 1 makes the field mandatory |
screen-intensified | 1 highlights the field |
6. SCREEN-ACTIVE vs. SCREEN-INPUT
| Setting | What the user sees | Use when |
|---|---|---|
screen-active = 0 | Field and label vanish. The space closes up. | The field is not relevant now |
screen-input = 0 | Field stays visible but cannot be edited. | The user should see the value but not change it |
screen-invisible = 1 | Box is shown, typed text appears as blanks. | Passwords and secrets |
If a hidden field has OBLIGATORY in its declaration, the user cannot run the report. Instead, leave OBLIGATORY off and set screen-required = 1 in the loop only when the field is visible.
7. Clearing hidden values
A hidden field still holds its old value. If the user typed a material, then un-ticked the item option, the material would still be in memory. Clear hidden filters so they cannot affect anything.
IF p_itm = abap_false.
CLEAR: s_matnr[], p_qty.
ENDIF.
For a select-option, clear the table body with s_matnr[]. The trade-off: when the user ticks the box again, the fields start empty.
8. Program 3: full code
REPORT zdynamic_screen.
DATA: gv_erdat TYPE vbak-erdat,
gv_auart TYPE vbak-auart,
gv_matnr TYPE vbap-matnr.
*---------------------------------------------------------------------*
* Selection screen
*---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
PARAMETERS: p_hdr AS CHECKBOX USER-COMMAND uc1 DEFAULT 'X',
p_itm AS CHECKBOX USER-COMMAND uc2.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002.
SELECT-OPTIONS: s_erdat FOR gv_erdat MODIF ID hdr,
s_auart FOR gv_auart MODIF ID hdr,
s_matnr FOR gv_matnr MODIF ID itm.
PARAMETERS: p_qty TYPE vbap-kwmeng MODIF ID itm.
SELECTION-SCREEN END OF BLOCK b2.
*---------------------------------------------------------------------*
* Events
*---------------------------------------------------------------------*
INITIALIZATION.
s_erdat-sign = 'I'.
s_erdat-option = 'BT'.
s_erdat-low = sy-datum - 30.
s_erdat-high = sy-datum.
APPEND s_erdat.
AT SELECTION-SCREEN OUTPUT.
LOOP AT SCREEN.
CASE screen-group1.
WHEN 'HDR'.
screen-active = COND #( WHEN p_hdr = abap_true THEN 1 ELSE 0 ).
MODIFY SCREEN.
WHEN 'ITM'.
screen-active = COND #( WHEN p_itm = abap_true THEN 1 ELSE 0 ).
MODIFY SCREEN.
ENDCASE.
ENDLOOP.
" Clear filters of hidden groups
IF p_hdr = abap_false.
CLEAR: s_erdat[], s_auart[].
ENDIF.
IF p_itm = abap_false.
CLEAR: s_matnr[], p_qty.
ENDIF.
AT SELECTION-SCREEN.
" Validate only when the user executes (F8), not when ticking boxes
IF sy-ucomm = 'ONLI' AND p_hdr = abap_false AND p_itm = abap_false.
MESSAGE 'Select at least one report type' TYPE 'E'.
ENDIF.
START-OF-SELECTION.
IF p_hdr = abap_true.
PERFORM show_headers.
ENDIF.
IF p_itm = abap_true.
PERFORM show_items.
ENDIF.
*---------------------------------------------------------------------*
* FORM show_headers: order headers (VBAK)
*---------------------------------------------------------------------*
FORM show_headers.
SELECT vbeln, erdat, auart, netwr, waerk
FROM vbak
WHERE erdat IN @s_erdat
AND auart IN @s_auart
ORDER BY erdat DESCENDING, vbeln
INTO TABLE @DATA(lt_headers)
UP TO 200 ROWS.
WRITE: / 'ORDER HEADERS'.
ULINE.
IF sy-subrc <> 0.
WRITE: / 'No order headers found'.
RETURN.
ENDIF.
LOOP AT lt_headers INTO DATA(ls_header).
WRITE: / ls_header-vbeln, ls_header-erdat, ls_header-auart,
ls_header-netwr, ls_header-waerk.
ENDLOOP.
SKIP.
ENDFORM.
*---------------------------------------------------------------------*
* FORM show_items: order items (VBAP)
*---------------------------------------------------------------------*
FORM show_items.
SELECT vbeln, posnr, matnr, kwmeng, netwr, waerk
FROM vbap
WHERE matnr IN @s_matnr
AND kwmeng >= @p_qty
INTO TABLE @DATA(lt_items)
UP TO 200 ROWS.
WRITE: / 'ORDER ITEMS'.
ULINE.
IF sy-subrc <> 0.
WRITE: / 'No order items found'.
RETURN.
ENDIF.
LOOP AT lt_items INTO DATA(ls_item).
WRITE: / ls_item-vbeln, ls_item-posnr, ls_item-matnr,
ls_item-kwmeng, ls_item-netwr, ls_item-waerk.
ENDLOOP.
ENDFORM.
9. Walkthrough
| Part | What it does |
|---|---|
Two checkboxes with USER-COMMAND | Let the user pick header report, item report, or both. Each click refreshes the screen. |
MODIF ID hdr and itm | Put header filters and item filters into two groups. |
AT SELECTION-SCREEN OUTPUT | Loops over the screen and shows or hides each group based on the checkboxes. |
| Clearing section | Empties the filters of any group that is hidden. |
sy-ucomm = 'ONLI' | Runs the “at least one” check only when the user presses F8. Without this, the error would block the user from ticking a box. |
START-OF-SELECTION | Calls only the forms for the ticked options. This is the conditional SELECT logic. |
IN @s_erdat etc. | An empty select-option selects everything, which is why clearing hidden ones is safe. |
What the user sees
| Choice | Fields shown |
|---|---|
| Headers only (default) | Created on, Order type |
| Items only | Material, Minimum quantity |
| Both | All four |
| Neither | No filters. Pressing F8 shows the error message. |
Remember to set selection texts for each field, as in Blog 2, so users see clear labels.
10. Try it yourself
- Replace the checkboxes with radio buttons so only one mode can be on.
- Make
s_matnrgrey (screen-input = 0) instead of hidden. - Add a third group
CSTfor customer filters (KUNNR) with its own checkbox. - Use
screen-required = 1to make the date range mandatory only when headers are selected. - Replace the
WRITEoutput with the ALV from Blog 5 or 6.
11. Common mistakes
- No
USER-COMMANDon the checkbox. The screen does not refresh when clicked. - Forgetting
MODIFY SCREEN. Changes toscreen-fields are ignored. - Group name in lowercase or longer than 3 characters. The group never matches.
- Putting the logic in
AT SELECTION-SCREENinstead ofAT SELECTION-SCREEN OUTPUT. Hiding must be set before the screen is drawn. - Error message without a
sy-ucommcheck. The user cannot even click the checkboxes. - Database access inside
AT SELECTION-SCREEN OUTPUT. It runs on every click and makes the screen slow. - Hidden fields with
OBLIGATORY. The user cannot run the report. Usescreen-required. - Forgetting to clear hidden filters, so old values silently filter the data.
Up next: Blog 8
Interactive Reports, the SY-LISEL way. Let users double-click a line and see a detail list, and learn why this method is fragile.
WhatsApp us