‎2014 Nov 25 1:35 AM
I have a requirement with which on entering the table name, i got to check if any data exists or not.
I have to return OK if table has data and return NG if it doesnt.
I am querying the table using Select stmt. The question is how to check the sy-subrc count inside the At selection screen event and then display the OK and NG? If I keep the sy-subrc check within END-OF-SELECTION, the write o/p doesnt display. If i put it outside the event, sy-subrc value gets changed after coming out of the event. How to resolve this? Any ideas please?
AT SELECTION-SCREEN.
SELECT COUNT(*) FROM dd02l INTO v_cnt WHERE TABNAME = p_tabnam.
END-OF-SELECTION.
IF SY-SUBRC EQ 0.
IF v_cnt <> 0.
WRITE: 'OK'.
ELSE.
WRITE: 'NG'.
ENDIF.
ELSE.
MESSAGE 'Invalid Table Name' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
Thanks.
‎2014 Nov 25 3:56 AM
Hi Gita,
I think you need something like this:
PARAMETERS p_tabnam TYPE string.
AT SELECTION-SCREEN ON p_tabnam.
* All this can be replaced by the select from table DD02L. I just think it's nicer this way.
DATA ddic_table TYPE REF TO cl_abap_structdescr.
TRY.
ddic_table ?= cl_abap_tabledescr=>describe_by_name( p_tabnam ).
CATCH cx_root. "if there's an exception, table does not exist
MESSAGE 'Table does not exist' TYPE 'E'.
ENDTRY.
FIELD-SYMBOLS <fs> TYPE any.
DATA ref_table TYPE REF TO data.
CREATE DATA ref_table TYPE (p_tabnam).
ASSIGN ref_table->* TO <fs>.
SELECT SINGLE * FROM (p_tabnam) INTO <fs>.
IF sy-subrc EQ 0. "there's data
MESSAGE 'OK' TYPE 'I'.
ELSE. "there's no data
MESSAGE 'NG' TYPE 'I'.
ENDIF.
Regards,
Custodio
‎2014 Nov 25 1:59 AM
I used something like below. Assign SY-SUBRC to a local variable.
Though it works fine, I am not sure if its quite the appropriate method.
Any other ideas would be highly appreciated.
AT SELECTION-SCREEN.
SELECT COUNT(*) FROM dd02l INTO v_cnt WHERE TABNAME = p_tabnam.
F_SUBRC = SY-SUBRC.
END-OF-SELECTION.
IF F_SUBRC EQ 0.
IF v_cnt <> 0.
WRITE: 'OK'.
ELSE.
WRITE: 'NG'.
ENDIF.
ELSE.
MESSAGE 'Invalid Table Name' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
‎2014 Nov 25 2:56 AM
‎2014 Nov 25 3:14 AM
Hi Gita,
'At selection-screen' even is like a PAI and 'At selection-screen output' is like a PBO if you see the anology in screen programming. The second way that you have done should be fine. If you want the output in the same screen you could try putting the condition in 'At selection-screen output' event.
You can initialize F_SUBRC = 8(or any thing other than 0 ) and not display anything initially and then based on sy-subrc value provide the appropriate output(NG,OK,error).
Best regards,
Saurabh
‎2014 Nov 25 3:33 AM
Just realized your write statement will not work in what I told earlier, you will have to use messages only. So the program will be something like this -
data f_subrc type sy-subrc.
data v_cnt type int2.
PARAMETERS : p_tabnam type char30.
INITIALIZATION.
f_subrc = 8.
AT SELECTION-SCREEN.
SELECT COUNT(*) FROM dd02l INTO v_cnt WHERE TABNAME = p_tabnam.
f_subrc = sy-subrc.
AT SELECTION-SCREEN OUTPUT.
IF f_subrc EQ 0.
IF v_cnt <> 0.
MESSAGE 'OK' TYPE 'S'.
ELSE.
MESSAGE 'NG' TYPE 'S'.
ENDIF.
ELSEif f_subrc = 4.
MESSAGE 'Invalid Table Name' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
‎2014 Nov 25 4:20 AM
Thank you, but i cannot change the requirement to status message instead of write.
Also, since the check is done at AT SELECTION-SCREEN OUTPUT, the message is always NG.
‎2014 Nov 25 4:32 AM
I tried with a database table which had some entries and it shows OK. I tried with an invalid table then it throws an error message.
Check if you used the INITIALIZATION event as I told.
‎2014 Nov 25 3:03 AM
Hi gita,
Maybe you should use below statements:
SELECT COUNT(*) FROM dd02l INTO v_cnt WHERE TABNAME = p_tabnam
AND AS4VERS = 'A'.
Thanks.
‎2014 Nov 25 4:21 AM
Thanks Li, this doesnt seem to change the selection screen display. I still donot get the expected o/p of displaying OK/NG in the sel screen.
‎2014 Nov 25 3:56 AM
Hi Gita,
I think you need something like this:
PARAMETERS p_tabnam TYPE string.
AT SELECTION-SCREEN ON p_tabnam.
* All this can be replaced by the select from table DD02L. I just think it's nicer this way.
DATA ddic_table TYPE REF TO cl_abap_structdescr.
TRY.
ddic_table ?= cl_abap_tabledescr=>describe_by_name( p_tabnam ).
CATCH cx_root. "if there's an exception, table does not exist
MESSAGE 'Table does not exist' TYPE 'E'.
ENDTRY.
FIELD-SYMBOLS <fs> TYPE any.
DATA ref_table TYPE REF TO data.
CREATE DATA ref_table TYPE (p_tabnam).
ASSIGN ref_table->* TO <fs>.
SELECT SINGLE * FROM (p_tabnam) INTO <fs>.
IF sy-subrc EQ 0. "there's data
MESSAGE 'OK' TYPE 'I'.
ELSE. "there's no data
MESSAGE 'NG' TYPE 'I'.
ENDIF.
Regards,
Custodio
‎2014 Nov 25 4:22 AM
Thank you Custodio. I am still not clear on what is being done here but it throws an exception at
ddic_table ?= cl_abap_tabledescr=>describe_by_name( p_tabnam ) statement.
‎2014 Nov 25 4:33 AM
Hi Gita,
It will give you an exception if the table name you entered does not exist. It may also throw an exception if the parameter p_tabnam is not the type string. But probably you want to replace all this with your select to DD02L:
PARAMETERS p_tabnam TYPE string.
DATA v_cnt TYPE i.
AT SELECTION-SCREEN ON p_tabnam.
SELECT COUNT(*) FROM dd02l INTO v_cnt UP TO 1 ROWS WHERE tabname = p_tabnam AND as4vers = 'A'.
IF sy-subrc NE 0.
MESSAGE 'Table does not exist' TYPE 'E'.
ELSE.
FIELD-SYMBOLS <fs> TYPE any.
DATA ref_table TYPE REF TO data.
CREATE DATA ref_table TYPE (p_tabnam).
ASSIGN ref_table->* TO <fs>.
SELECT SINGLE * FROM (p_tabnam) INTO <fs>.
IF sy-subrc EQ 0. "there's data
MESSAGE 'OK' TYPE 'I'.
ELSE. "there's no data
MESSAGE 'NG' TYPE 'I'.
ENDIF.
ENDIF.
‎2014 Nov 25 4:40 AM
Thank you Custodio. That works perfectly.
Now, since I have two methods with which this works (your method & using Flag variable), which do you suggest is the appropriate way to do this?
‎2014 Nov 25 4:48 AM
Both are appropriate, just use the one which is easier for you and your team to maintain.
‎2014 Nov 25 6:04 AM
Just to add.
SELECT COUNT(*) to check the existence of a record is not good pracice- if the table is of any appreciable size, it can take quite a while. Use select single instead.
‎2014 Nov 25 7:17 AM
Yep, that's why I added UP TO 1 ROWS. Pretty sure it does not make any difference performance wise, plus I can select the result of count in an variable type I, instead of having to select any field from the table and dynamically declaring its type.
‎2014 Nov 25 7:56 AM
‎2014 Nov 25 7:58 AM
Thanks Custodio.
Meanwhile, how about using Start-of-selection instead of At Selection-screen like below.
Is it appropriate to do so?
************************************************
START-OF-SELECTION.
SELECT COUNT(*) FROM dd02l INTO v_cnt UP TO 1 ROWS WHERE TABNAME = p_tabnam.
IF SY-SUBRC EQ 0.
IF v_cnt <> 0.
WRITE: 'OK'.
ELSE.
WRITE: 'NG'.
ENDIF.
ELSE.
MESSAGE 'Invalid Table Name' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
END-OF-SELECTION.
**************************************************
Thanks.
‎2014 Nov 25 8:46 AM
I was really commenting on Gita's code, and yes, you're right. UP TO 1 ROWS produces identically the same SQL on the database as SELECT SINGLE. However, I think SELECT SINGLE is to be used in preference, as it is more obvious than UP TO 1 ROWS.
‎2014 Nov 25 4:19 AM
Hi Gita,
You can store the value of SY-SUBRC in a FLAG variable and then display the message at the END-OF-SELECTION event as the SY-SUBRC stores the state of last executed statement and the END-OF-SELECTION statement would always trigger it to 0.
for e.g.
AT SELECTION-SCREEN.
SELECT COUNT(*) FROM dd02l INTO v_cnt WHERE TABNAME = p_tabnam.
FLAG = SY-SUBRC.
END-OF-SELECTION.
IF FLAG EQ 0.
MESSAGE 'Valid Table Name ' TYPE 'S'.
ELSE.
MESSAGE 'Invalid Table Name' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
‎2014 Nov 25 4:26 AM
Thank you Anish, but isn't it the same that I am doing above (in my second set of code)?
‎2014 Nov 25 4:26 AM
My only doubt is with the At selection-screen and End-of-selection. I am not sure if i am putting it in the right place.
‎2014 Nov 25 4:36 AM
Hi gita..
try this
PARAMETERS: tab TYPE dd02l-TABNAME.
data: c TYPE i,
v_cnt TYPE i.
AT SELECTION-SCREEN.
SELECT COUNT(*) FROM dd02l INTO v_cnt WHERE TABNAME = tab.
IF sy-subrc = 0.
c = c + 1.
ENDIF.
END-OF-SELECTION.
* IF SY-SUBRC EQ 0.
IF v_cnt <> 0.
WRITE: 'OK'.
* ELSE.
* WRITE: 'NG'.
* ENDIF.
ELSE.
MESSAGE 'Invalid Table Name' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
regards
laxman
‎2014 Nov 25 4:43 AM
Hi Gita,
There was no need to check if v_cnt is 0 or not, as the else statement would not be executed at all.
As for the AT SELECTION-SCREEN and END-OF-SELECTION screen is concerned it depends on whether you want the at selection screen to be ready for input again or not.
the AT SELECTION-SCREEN event only makes sense in reports, i.e. in programs set to type 1 in the attributes. Type 1 programs are started via a logical database and always have a selection screen where the user can specify the database selections.
The event is processed when the selection screen has been processed (at the end of PAI).
If an error message (MESSAGE Emnr ) is sent during the event, all fields on the selection screen become ready for input.
After further user input, AT SELECTION-SCREEN is executed again.