Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
Showing results for 
Search instead for 
Did you mean: 
0 Kudos

I have two table controls on my dynpro screen and in one of them there is a field which, upon F4, should check the value of another field and then execute one of two possible search helps, depending on the value of the other field.

In addition, another field in that table control contains a pushbutton, that displays information regarding the row in which the button was clicked.

In both cases I need to have to selected line as a local structure that I can work with. The first case happens in event Process on Value-Request ('POV') and the second one happens in event Process After Input ('PAI').

I decided to create a fully generic code which returns the selected line in any given TableCtrl object, at any given screen event. I checked class CL_TABLECONTROL but couldn't find any similar method to do so.

Unfortunately, it seems that it cannot be implemented as an external Method (in my Utilities class) because the table control object (of type CXTAB_CONTROL) does not exist in this OO context. So the logic must be implemented as a Form in the dynpro program.

I would be glad to hear your thoughts on this!

Edit: it occurred to me that this logic actually needs to return different results according to the event during which it is called. In POV it should return the currently selected visible line, but in PAI it should return the absolute index of the row in the local table, and thus should always be executed only AFTER the end of the wizard-generated table-control loop.

I will try to find the time to update this logic to match all possible table-control events and cases. In the meantime please use it either in POV event or at the end of PAI event.

Here is the logic:
*& Form tc_get_curr_line
* This FORM returns the currently selected line in a desired TableCtrl.
* It uses system field SY_STEPL and CXTAB_CONTROL, and so cannot be used
* in Object Oriented programming (e.g. inside a class method).
* -->IS_STRUCTURE Structure of identical type as a TableCtrl's line
* -->IV_STRUCTURE_NAME Name of the given structure, as defined on the Dynpro Screen / in DEF include / etc.
* -->IV_TC_NAME Name of the desired TableCtrl, as defined on the Dynpro Screen / in DEF include / etc.
* -->IV_SCREEN_EVENT Used to determine if it's Process on Value-Request ('POV') or Process After Input ('PAI') (two different ways to get selected line's index)
* <--ES_CURR_TC_LINE The selected line, returned in the matching type for the given structure
* <--EV_SELECTED_INDEX Absolute index of the selected line in the global table it is linked to
FORM tc_get_curr_line USING is_structure TYPE any
iv_structure_name TYPE dynfnam
iv_tc_name TYPE dynfnam
iv_screen_event TYPE char10
CHANGING es_curr_tc_line TYPE any
ev_selected_index TYPE i.

DATA: lv_selected_index TYPE sy-stepl,

lo_struct_descr TYPE REF TO cl_abap_structdescr,
lv_struct_dynp_name TYPE dynfnam,

ls_tc_column TYPE LINE OF cxtab_control-cols,

lt_dynpfields TYPE dynpread_tabtype,
ls_dynpfield LIKE LINE OF lt_dynpfields[],

ls_selected_line TYPE REF TO data.

FIELD-SYMBOLS: <ls_tc_attr> TYPE cxtab_control,
<ls_selected_line> TYPE ANY,
<lv_line_field_value> TYPE ANY,
<ls_tc_line_to_return> TYPE ANY.

" Getting the relevant TableControl structure with all attributes of the TableCtrl itself:
ASSIGN (iv_tc_name) TO <ls_tc_attr>.

IF sy-subrc <> 0.
" Replace this statement with an appropriate statement using a message from a message-class:
MESSAGE 'Error getting the desired TableControl screen component' TYPE 'E'.

" Getting the index of the currently selected line in the TableCtrl:
CASE iv_screen_event.
" When pressing F4, using this function to get the selected line's index:
povstepl = ev_selected_index
stepl_not_found = 1

IF sy-subrc <> 0.
MESSAGE ID sy-msgid
TYPE sy-msgty
NUMBER sy-msgno
WITH sy-msgv1


" When any process after input, using this keyword to get the selected line's index:
GET CURSOR LINE ev_selected_index.

" This calculation returns the absolute index of the selected line even after scrolling the TableCtrl:
ev_selected_index = <ls_tc_attr>-top_line + ev_selected_index - 1.


ls_dynpfield-stepl = ev_selected_index.

" Building a DynproFields table with the names of all the displayed fields in
" the given TableCtrl (only the ones that are OUTPUT - which means without any pushbuttons if exist)
LOOP AT <ls_tc_attr>-cols
INTO ls_tc_column
WHERE screen-output EQ 1.
ls_dynpfield-fieldname = ls_tc_column-screen-name.
APPEND ls_dynpfield TO lt_dynpfields[].


" Getting the DDIC description (fields' names and attributes) of the
" given structure that I need to return eventually:
lo_struct_descr ?= cl_abap_typedescr=>describe_by_data( is_structure ).

" Reading the values from the currently selected line in the given TableCtrl:
dyname = sy-cprog
dynumb = sy-dynnr
* translate_to_upper = ' '
* request = ' '
* perform_conversion_exits = ' '
* perform_input_conversion = ' '
* determine_loop_index = ' '
start_search_in_current_screen = abap_true
* start_search_in_main_screen = ' '
* start_search_in_stacked_screen = ' '
* start_search_on_scr_stackpos = ' '
* search_own_subscreens_first = ' '
* searchpath_of_subscreen_areas = ' '
dynpfields = lt_dynpfields[]
invalid_abapworkarea = 1
invalid_dynprofield = 2
invalid_dynproname = 3
invalid_dynpronummer = 4
invalid_request = 5
no_fielddescription = 6
invalid_parameter = 7
undefind_error = 8
double_conversion = 9
stepl_not_found = 10

IF sy-subrc <> 0.
MESSAGE ID sy-msgid
TYPE sy-msgty
NUMBER sy-msgno
WITH sy-msgv1

ELSEIF lt_dynpfields[] IS NOT INITIAL.
" Creating the structure to return:
CREATE DATA: ls_selected_line TYPE HANDLE lo_struct_descr.
ASSIGN ls_selected_line->* TO <ls_selected_line>.

" Going over the Dynpro screen fields to copy their values
LOOP AT lt_dynpfields[] INTO ls_dynpfield.
" The Dynpro Fields table contains the names of the Screen fields: The DynproStructure's name and
" a hyphen '-' (e.g. 'GS_TC_DATA-MY_LOVELY_FIELD'). I need to compare between the names of the Dynpro FIELDS themselves
" and the names of the DDIC fields in the DDIC structure. So I need only the fields' names without the structure's name.
" I'm building a string with the Dynpro Structure's name and a hyphen:
CONCATENATE iv_structure_name
INTO lv_struct_dynp_name.

" Now I'm removing the name of the Dynpro Structure (and the '-') from FIELDNAME in the DynpFields table:
REPLACE lv_struct_dynp_name
IN ls_dynpfield-fieldname
WITH space

" Now I have the name of the actual FIELD in the dynpro structure, which should correspond to
" the name of the matching field in the DDIC structure that I need to return.
" So finally I can dynamically assign that field in the returned DDIC structure and copy
" the value from the Dynpro field to it:
ASSIGN COMPONENT ls_dynpfield-fieldname
OF STRUCTURE <ls_selected_line>
TO <lv_line_field_value>.

IF sy-subrc EQ 0
AND <lv_line_field_value> IS ASSIGNED.
" Copying the value from the Dynpro Screen field to the returned DDIC structure's field:
<lv_line_field_value> = ls_dynpfield-fieldvalue.



ASSIGN es_curr_tc_line
TO <ls_tc_line_to_return>.

" Copying the complete local structure to the returned Dynpro Screen structure:
IF sy-subrc EQ 0
AND <ls_tc_line_to_return> IS ASSIGNED.
<ls_tc_line_to_return> = <ls_selected_line>.




ENDFORM. "tc_get_curr_line


Labels in this area