how to leave program with f12 after write - abap

Once I leave the selection screen in ABAP e.g. by write: How to rewrite cancel button behavior? In my shortened code below, each time I click execute and then cancel, I'm back at the selection screen :( Instead of this behavior I want to leave the program entirely when clicking in write output the red button.
PARAMETERS p_output AS CHECKBOX DEFAULT ' '.
SELECTION-SCREEN BEGIN OF SCREEN 101 AS SUBSCREEN.
SELECTION-SCREEN BEGIN OF BLOCK such WITH FRAME TITLE text-001.
"...
SELECTION-SCREEN END OF BLOCK such.
SELECTION-SCREEN END OF SCREEN 101.
SELECTION-SCREEN BEGIN OF SCREEN 102 AS SUBSCREEN.
SELECTION-SCREEN BEGIN OF BLOCK such2 WITH FRAME TITLE text-002.
"...
SELECTION-SCREEN END OF BLOCK such2.
SELECTION-SCREEN END OF SCREEN 102.
SELECTION-SCREEN BEGIN OF TABBED BLOCK searchtab FOR 20 LINES.
SELECTION-SCREEN TAB (15) expert USER-COMMAND ucomm1
DEFAULT SCREEN 101.
SELECTION-SCREEN TAB (17) common USER-COMMAND ucomm2
DEFAULT SCREEN 102.
SELECTION-SCREEN END OF BLOCK searchtab.
INITIALIZATION.
expert = text-001.
common = text-002.
searchtab-prog = sy-repid.
searchtab-dynnr = 101.
searchtab-activetab = 'EXPERT_SEARCH'.
"...
AT SELECTION-SCREEN ON EXIT-COMMAND.
CASE sy-dynnr.
WHEN 1000."main screen number
CASE sy-ucomm.
WHEN 'ECAN'.
LEAVE PROGRAM.
WHEN 'DBAC' OR 'ENDE'. "execute go back
LEAVE TO SCREEN 1000." SELECTION-SCREEN 1000.
WHEN 'UCOMM1'.
searchtab-dynnr = 101."subscreen number 1
searchtab-activetab = 'EXPERT'.
WHEN 'UCOMM2'.
searchtab-dynnr = 102."subscreen number 2
searchtab-activetab = 'COMMON'.
ENDCASE.
WHEN Others.
CASE sy-ucomm.
WHEN 'ECAN'.
LEAVE PROGRAM.
WHEN 'DBAC' OR 'ENDE'. "execute go back
LEAVE TO SCREEN 1000." SELECTION-SCREEN 1000.
ENDCASE.
ENDCASE.
START-OF-SELECTION.
PERFORM say_hello.
FORM say_hello .
WRITE: 'from the write output screen I want to navigate by Cancel button or key f12',
'not back to selection screen but leave the program entirely.'.
ENDFORM. " SAY_HELLO

Here is what works, it's not pretty.
Copy GUI status INLI from program SAPMSSY0 to your own program
Change the OK code for the cancel button. To work with your example code, change it to ECAN. Also change the one in the Edit menu to be complete
As the first command in your START-OF-SELECTION use
SET PF-STATUS 'INLI'. This is assuming you named it the same
Change the AT SELECTION-SCREEN to AT USER-COMMAND
Activate, test and be amazed
This works because it removes the standard behavior for lists and replaces it with your own, only for the cancel button mind you. Without changing the OK code for cancel the standard SAP code will take over and you have no control over the behavior.

Related

Transaction type for a program with Dialog and report type program

I have a program with a selection screen that produces an alv grid. The ALV grid has a hotspot which sends the user to a new screen which allows users to edit data based on their selection in the alv grid.
This program has a report type screen (selection screen) and dialog screen (the third screen), which type of transaction should i create (report or dialog). Since my starting screen is a default selection screen, should it be a report transaction? Or should i create a screen and make the selection screen a sub screen (if yes, can you please suggest how i do this and create an alv grid with this).
This program "has a report type", you mean it's an "executable program" AKA "report", so use a "report" transaction, so as you probably tried, what happens?
Only the first screen is of some interest for choosing the type of a transaction.
If it's a selection screen, use a "report" transaction.
If it's a general screen, use a "dialog" transaction.
First Program Report Type
It should be report transaction. You can also create dialog transaction.
If you write dialog transaction for the first ABAP program then you can declare selection screen as subscreen.
Following is the example of selection screen as subscreen.
SELECTION-SCREEN : BEGIN OF SCREEN 1010 AS SUBSCREEN.
SELECTION-SCREEN : BEGIN OF BLOCK a WITH FRAME TITLE text-001.
PARAMETERS: rdb1 RADIOBUTTON GROUP rad1 DEFAULT 'X'.
SELECTION-SCREEN BEGIN OF LINE.
PARAMETERS: rdb2 RADIOBUTTON GROUP rad1,
p_data TYPE c LENGTH 35 DEFAULT 'Reporting / Maintenance Data'.
SELECTION-SCREEN END OF LINE.
PARAMETERS rdb3 RADIOBUTTON GROUP rad1.
PARAMETERS rdb4 RADIOBUTTON GROUP rad1. " Membership Expiry Report
SELECTION-SCREEN :END OF BLOCK a.
SELECTION-SCREEN: END OF SCREEN 1010.
Second ABAP Program Dialog/Report
Second ABAP program can be dialog program or report program for editable ALV.If you create dialog program then you have to create transaction.Report ABAP program you can call directly.
regards,
Umar Abdullah
To keep it simple:
if the first line of code in your program logic starts with 'REPORT' go for a "Report" transaction; if not choose a dialog transaction type.
The type of transaction you create should not really matter in this case as long as the screen number of the transaction refers to the selection screen (this is '1000' by default).
As far as the type of program (module pool/dialog or report) goes, both are possible options for your requirement.
I suggest you use a dialog program if you haven't already since they allow for more flexibility and it's generally best practice and easier to stick with these for more complex programs with multiple screens.
Reports vs. Module Pools/Dialog Programs
Reports are generally used for displaying/analyzing data from the database, whilst dialog programs are used when data has to be updated.
Another difference is that reports can be run directly and dialog programs can only be executed via a transaction code.

Obligatory field check ignored if TABBED BLOCK used

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.

Subscreen in tab not getting refreshed

I have a selection screen on which I want to change tabs dynamically. In my example tab1 should be shown if the flag p_flg1 is set otherwise tab2 is to be presented and the other one deactivated.
REPORT zzz.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE tit1.
PARAMETERS:
p_flg1 TYPE abap_bool AS CHECKBOX USER-COMMAND md DEFAULT abap_true. "Master data
SELECTION-SCREEN END OF BLOCK b2.
SELECTION-SCREEN BEGIN OF TABBED BLOCK tab FOR 20 lines.
SELECTION-SCREEN TAB (54) tab1 USER-COMMAND tab1 DEFAULT SCREEN 010.
SELECTION-SCREEN TAB (54) tab2 USER-COMMAND tab2 DEFAULT SCREEN 011.
SELECTION-SCREEN TAB (54) tab3 USER-COMMAND tab3 DEFAULT SCREEN 900.
SELECTION-SCREEN END OF BLOCK tab.
SELECTION-SCREEN BEGIN OF SCREEN 010 AS SUBSCREEN.
PARAMETERS:
p_flg2 TYPE abap_bool AS CHECKBOX.
SELECTION-SCREEN END OF SCREEN 010.
SELECTION-SCREEN BEGIN OF SCREEN 011 AS SUBSCREEN.
PARAMETERS:
p_text TYPE text.
SELECTION-SCREEN END OF SCREEN 011.
SELECTION-SCREEN BEGIN OF SCREEN 900 AS SUBSCREEN.
PARAMETERS:
p_flg3 TYPE abap_bool AS CHECKBOX.
SELECTION-SCREEN END OF SCREEN 900.
INITIALIZATION.
tit1 = 'Tit1'.
tab1 = 'Tab1'.
tab2 = 'Tab2'.
tab3 = 'Tab3'.
AT SELECTION-SCREEN OUTPUT.
LOOP AT SCREEN.
IF screen-name = 'TAB1'.
IF p_flg1 = abap_true.
screen-active = 1.
ELSE.
screen-active = 0.
ENDIF.
ELSEIF screen-name = 'TAB2'.
IF p_flg1 = abap_true.
screen-active = 0.
ELSE.
screen-active = 1.
ENDIF.
ENDIF.
MODIFY SCREEN.
ENDLOOP.
However what gets changed after unsetting the parameter p_flg1 is only the tab name and not the subscreen under it. It only gets changed if I switch to the tab3 and back.
After starting the program.
After unsetting the P_FLG1 only the tab name gets changed not the subscreen under it.
To work around it I have to switch to Tab3...
...and back
I assume that I need to call something, e.g. a function module after MODIFY SCREEN to execute some event (maybe PAI?) however I failed in finding any information on that.
What do I have to do to get the subscreen under the tab refreshed immediately after setting/unsetting the flag?
This is a common issue - if you disable/hide the first tab of a register, the subscreen of the first card stays in place until the user selects a different card. A register is essentially a subscreen area with a button bar on top, and if the included screen isn't changed by something, the default is displayed. You might get a better result using the "Dynamic Assignment" described here (approx. center of the page). If this doesn't work, you might have to emulate the card change after the checkbox has been changed. Of course, the simple solution would be to move the third (static) card to the front...

Compilation of SELECTION-SCREEN fails

What's wrong with the following ABAP code block?
Compilation of the program does causes an error, but no details are shown.
Please suggest changes in the code so it works
REPORT ZSELECTIONSCREENCOMMENTS.
SELECTION-SCREEN BEGIN OF BLOCK B1 WITH FRAME TITLE TIT1.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN POSITION 20.
PARAMETERS: P_MATNR LIKE MARA-MATNR, P_ERSDA LIKE MARA-ERSDA, P_ERNAM LIKE MARA-ERNAM.
SELECTION-SCREEN COMMENT 1(12) COM1 FOR FIELD P_MATNR.
SELECTION-SCREEN COMMENT 1(12) COM2 FOR FIELD P_ERSDA.
SELECTION-SCREEN COMMENT 1(12) COM3 FOR FIELD P_ERNAM.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF BLOCK B1.
LOAD-OF-PROGRAM.
TIT1 = 'Selection-Criteria'.
COM1 = 'Material No'.
COM2 = 'ERSDA'.
COM3 = 'ERNAM'.
You are trying to place multiple comments at the same position within a single line (BEGIN OF LINE ... END OF LINE block), and you are adding multiple parameters to that single line without specifying positions.

Dynamically fill selection-screen parameter on change

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.