I have some radiobuttons and when I change between them some blocks appear/disappear.
However, if I set parameters as obligatory or required they do not hide unless I fill them. I want to make parameters required but I need to hide them when I change the radiobutton option.
I guess it's a selection screen...
then loop at your screen and check the value of "YOUR_RADIO_BUTTON"
enable or disable the blocks
AT SELECTION-SCREEN OUTPUT.
LOOP AT SCREEN.
* Radio button parameter = P_RADIO
* hide the parameter named "to_hide"
IF P_RADIO EQ 'X' AND SCREEN-NAME CS 'TO_HIDE'.
SCREEN-INPUT = 0.
MODIFY SCREEN.
ENDIF.
* display the parameter named "to_hide"
IF P_RADIO <> 'X' AND SCREEN-NAME CS 'TO_HIDE'.
SCREEN-INPUT = 1.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
If you use PARAMETERS ... OBLIGATORY, this is an unconditional statement - this parameter is required regardless of the other settings. If you need a conditional check, you have to code it for yourself:
PARAMETERS p_chkbuk AS CHECKBOX.
PARAMETERS p_bukrs TYPE bukrs.
AT SELECTION-SCREEN ON p_bukrs.
IF p_chkbuk = abap_true AND p_bukrs IS INITIAL.
MESSAGE 'You need to enter something.' TYPE 'I' DISPLAY LIKE 'E'.
ENDIF.
Related
When setting up a selection screen with dynamic visibility of the controls I ran into an unexpected runtime error DYNP_TOO_MANY_RADIOBUTTONS_ON. Reduced sample code to the following reproducible example:
REPORT ztest1.
SELECTION-SCREEN BEGIN OF BLOCK category.
PARAMETER:
rb_cata RADIOBUTTON GROUP cat USER-COMMAND selection_changed DEFAULT 'X',
rb_catb RADIOBUTTON GROUP cat.
SELECTION-SCREEN END OF BLOCK category.
SELECTION-SCREEN BEGIN OF BLOCK action.
PARAMETER:
rb_act1 RADIOBUTTON GROUP act USER-COMMAND selection_changed DEFAULT 'X' MODIF ID act,
rb_act2 RADIOBUTTON GROUP act.
SELECTION-SCREEN END OF BLOCK action.
AT SELECTION-SCREEN OUTPUT.
LOOP AT SCREEN.
CASE screen-group1.
WHEN 'ACT'.
screen-invisible = COND #( WHEN rb_cata = abap_true THEN 0 ELSE 1 ).
WHEN OTHERS.
ENDCASE.
MODIFY SCREEN.
ENDLOOP.
When selecting rb_catb and then re-selecting the first radiobuttion I get the runtime error DYNP_TOO_MANY_RADIOBUTTONS_ON with comment:
In a group of radio buttons, exactly one of the fields must be set -
meaning that must have the value 'X'. If this is not the case, one of
the following situations occurs:
- Multiple radio buttons of the group are set at the same time. This error causes the appplication to terminated and triggers the short
dump that you are currently reading.
But I'm only changing the visibility of the buttons, why am I getting an error relating to the actual active status?
The reason for this is a failure to set the exact same MODIF ID on all buttons in the radiobutton group. While the precise screen processing logic is hard to get at, it appears that all elements in the radiobutton group (RBG) need to be changed at the same time to avoid processing issues. So in the above example:
rb_act1 RADIOBUTTON GROUP act USER-COMMAND selection_changed DEFAULT 'X' MODIF ID act,
rb_act2 RADIOBUTTON GROUP act MODIF ID act.
I initially suspected issues with the ACTIVE or INVISIBLE attributes conflict but those appear unrelated. The actual reason these controls need to change in lockstep is unknown without being able to look at the screen processing logic that's likely hidden in the kernel. Note that the MODIF ID has to be the exact same, any mixing of these IDs within a single RBG will result in this runtime error.
I have the following program.
REPORT zz_tab_strip_obligatory.
SELECTION-SCREEN BEGIN OF TABBED BLOCK tab FOR 20 LINES.
SELECTION-SCREEN TAB (54) tab1 USER-COMMAND tab1 DEFAULT SCREEN 100.
SELECTION-SCREEN TAB (54) tab2 USER-COMMAND tab2 DEFAULT SCREEN 200.
SELECTION-SCREEN END OF BLOCK tab.
SELECTION-SCREEN BEGIN OF SCREEN 100 AS SUBSCREEN.
PARAMETERS:
p1 TYPE i.
SELECTION-SCREEN END OF SCREEN 100.
SELECTION-SCREEN BEGIN OF SCREEN 200 AS SUBSCREEN.
PARAMETERS:
p2 TYPE i OBLIGATORY.
SELECTION-SCREEN END OF SCREEN 200.
INITIALIZATION.
tab1 = 'Tab1'.
tab2 = 'Tab2'.
The first tab has no obligatory fields. The second one on the other hand does.
The problem I am having is that if the user does not go to the second tab and instead of it starts the program immediately with F8 then the obligatory check for the parameters p2 is not performed at all. It looks like all of the events like AT SELECTION-SCREEN are executed only for the current tab ergo for the displayed subscreen.
Is there any way to work around it? My current solution right now is sadly getting rid of OBLIGATORY keywords and making the checks after START-OF-SELECTION (my real program has many tabs).
I do not think there is a direct solution to the selection screen obligatory issue. Here is a similar topic. However, you can store all the obligatory parameters in an internal table. At the Start-of-selection, loop through them and check them.
DATA: BEGIN OF gt_obl_fields OCCURS 0,
fname TYPE char10,
ftext type char50,
END OF gt_obl_fields.
INITIALIZATION.
tab1 = 'Tab1'.
tab2 = 'Tab2'.
gt_obl_fields-fname = 'P2'.
gt_obl_fields-ftext = text-001.
APPEND gt_obl_fields.
"...
START-OF-SELECTION.
LOOP AT gt_obl_fields .
ASSIGN (gt_obl_fields-fname) TO FIELD-SYMBOL(<fs_field>).
IF <fs_field> IS ASSIGNED AND <fs_field> IS INITIAL..
CONCATENATE gt_obl_fields-ftext 'field must be filled!' INTO data(lv_message).
MESSAGE lv_message TYPE 'E'.
ENDIF.
ENDLOOP.
Suppose I have a selection-screen block with two parameters. I want to dynamically fill the second parameter based on what the user inputs in the first, for instance by querying a table to find the expected value for the key field in parameter 1.
As an example, say I have a program that does something for a combination of order number (p_aufnr) and WBS element (p_wbs). Instead of asking the user to provide both, I can determine one of them from the PSPEL field on the AUFK table. However, I still want to show this field to the user after he inputs his order number so he can verify that the WBS element is correct.
I've managed to do this by using the AT SELECTION SCREEN ON p_aufnr event to assign a value to p_wbs. This event is processed when the user presses enter. However, I can only ever get it to work once. So if the user enters an order number, realises from the retrieved WBS element that he made a mistake and changes it, the second parameter never changes. Even though the AT SELECTION SCREEN event is processed in the debugger, the parameter is not updated.
Am I not supposed to use this event for my scenario? If so, how would I then implement this sort of dynamic selection screen?
Forgot to add a code sample. The following report illustrates my issue: after entering a value in p_netw and pressing enter, p_wbs is filled with the value 1. However, if you press enter again the AT SELECTION-SCREEN ON routine is processed but the value for p_wbs is not updated, while lv_count is.
DATA: lv_count TYPE i.
SELECTION-SCREEN BEGIN OF BLOCK main.
PARAMETERS: p_netw TYPE aufnr OBLIGATORY MODIF ID auf.
PARAMETERS: p_wbs TYPE i MODIF ID psp.
SELECTION-SCREEN END OF BLOCK main.
AT SELECTION-SCREEN ON p_netw.
ADD 1 TO lv_count.
p_wbs = lv_count.
START-OF-SELECTION.
PERFORM main.
FORM main.
WRITE: 'The value reached ', lv_count.
ENDFORM.
Apparently the data is not written back to the screen if you update the field in the field-specific block. If you move the field update from AT SELECTION-SCREEN ON p_netw to the global AT SELECTION-SCREEN event, it works. Don't ask me why, though - this seems to a case of undocumented system behaviour...
DATA: lv_count TYPE i.
SELECTION-SCREEN BEGIN OF BLOCK main.
PARAMETERS: p_netw TYPE aufnr OBLIGATORY MODIF ID auf.
PARAMETERS: p_wbs TYPE i MODIF ID psp.
SELECTION-SCREEN END OF BLOCK main.
AT SELECTION-SCREEN ON p_netw.
ADD 1 TO lv_count.
AT SELECTION-SCREEN.
p_wbs = lv_count.
You need to use a PAI (process after input) module on your screen which then takes the new p_aufnr and finds the appropriate p_wbs - probably exactly like your at selection screen event. You will then CALL SCREEN ### <-- your screen number to display the data on your screen. Without any code to work off thats all i can help with.
Currently I have an ALV grid and I can double click to call transaction IE03 and pass the information in the first column (which is eqkt-equnr). However, this transaction is called regardless of what column you click on. This wouldn't be so bad, but I need to be able to call IW33 if you click on the 3rd column and pass along the equz-J_3GEIGNER value there.
My current double click code is as follows. t_report is my struct and matnr is the equnr part of it. maktx is the J_3GEIGNER part of it.
FORM user_command USING r_ucomm
wa_selrow TYPE slis_selfield.
IF r_ucomm = '&IC1'.
READ TABLE t_report INDEX wa_selrow-tabindex.
IF sy-subrc = 0.
SET PARAMETER ID 'EQN' FIELD t_report-matnr.
CALL TRANSACTION 'IE03' AND SKIP FIRST SCREEN.
ENDIF.
ENDIF.
ENDFORM.
Use the field wa_selrow-fieldname to determine which column was clicked. Be aware that you may have to switch the grid from row selection mode to cell selection mode - since you didn't show us how you created the grid in the first place, I can't tell you how to do this in your case. Take a look at the SEL_MODE property, it might help.
I'd want to be able to have multiple range selections for "Sales order no."
Problem is: when i press the button marked with green, i get the error "Fill in all required entry fields".
I put my main processing block at the START-OF-SELECTION event.
What to do to not have this happen? It seems to me that i should be able to add multiple selections without all the hassle of first filling every other mandatory field.
With parameters/select-options set to OBLIGATORY, this won't work. I had the very same problem some time ago, and had no chance to fill the OBLIGATORY input parameters with useful values by default, so I did the following:
Remove the OBLIGATORY option from all select-options and parameters
Handle the check for obligatory input yourself in cases no F4,help, F1 help or the button next to any select option is pressed:
Code:
AT SELECTION-SCREEN ON s_reswk.
IF sy-ucomm(1) <> '%' AND " sel screen action request
sy-ucomm(1) <> '_' AND " scope option
s_reswk IS INITIAL. " Obligatory input missing
MESSAGE text-e01 TYPE 'E'. " Error message
ENDIF.
Here's what i found that completely reproduces the behavior set by the OBLIGATORY addition:
1:Take OUT the "OBLIGATORY" addition.
2:at PBO:
LOOP AT SCREEN.
IF screen-name cs 'name-of-your-select-options-or-parameter'.
screen-required = 2.
MODIFY SCREEN.
ENDIF.
3: at PAI:
if sscrfields-ucomm = 'ONLI'.
if 'name of your select-option-or-parameter' is initial.
clear sscrfields.
message 'Fill in all required fields.'(009) type 'E'.
endif.
endif.
Notice the first if statement contains a 'cs' logical operator. That's cuz the name of your control will contain other weird stuff as well. For instance %_P_MATNR_%SCREEN%% (where your parameter was p_matnr).
Also, the declaration : TABLES sscrfields. is necessary.