Populate a screen field without triggering PAI using FM DYNP_VALUES_UPDATE

This program demonstrates how to populate a screen field depending upon another field without triggering PAI using FM DYNP_VALUES_UPDATE.






The Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
*&---------------------------------------------------------------------*
*&Program: Z_TEST_PROGRAM
*&Creation Date: 26.07.2008 12:54:08
*&---------------------------------------------------------------------*
*& Test program for blog http://abap-explorer.blogspot.com/
*&---------------------------------------------------------------------*
REPORT z_test_program1.

PARAMETERS:
p_name TYPE uname,
p_ctry TYPE char2.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_name.

PERFORM sub_populate_f4_help USING 'P_NAME'.

START-OF-SELECTION.

END-OF-SELECTION.

*&---------------------------------------------------------------------*
*& Form sub_populate_f4_help
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_RETFIELD text
*----------------------------------------------------------------------*
FORM sub_populate_f4_help USING p_retfield TYPE dynfnam.
TYPES:
BEGIN OF l_x_names,
uname TYPE uname,
END OF l_x_names.

DATA:
l_i_names TYPE STANDARD TABLE OF l_x_names INITIAL SIZE 0,
l_wa_names TYPE l_x_names,
l_i_field_tab TYPE STANDARD TABLE OF dfies INITIAL SIZE 0,
l_i_return_tab TYPE STANDARD TABLE OF ddshretval INITIAL SIZE 0,
l_wa_return_tab TYPE ddshretval,
l_i_dynpfld_mapping TYPE STANDARD TABLE OF dselc INITIAL SIZE 0.

l_wa_names-uname = 'TEST1'.
APPEND l_wa_names TO l_i_names.
l_wa_names-uname = 'TEST2'.
APPEND l_wa_names TO l_i_names.
l_wa_names-uname = 'TEST3'.
APPEND l_wa_names TO l_i_names.
l_wa_names-uname = 'TEST4'.
APPEND l_wa_names TO l_i_names.


CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
retfield = 'UNAME'
dynpprog = sy-repid
dynpnr = sy-dynnr
dynprofield = p_retfield
value_org = 'S'
TABLES
value_tab = l_i_names
field_tab = l_i_field_tab
return_tab = l_i_return_tab
dynpfld_mapping = l_i_dynpfld_mapping
EXCEPTIONS
parameter_error = 1
no_values_found = 2
OTHERS = 3.
IF sy-subrc = 0.
READ TABLE l_i_return_tab INTO l_wa_return_tab INDEX 1.
p_name = l_wa_return_tab-fieldval.
ELSE.
MESSAGE e001(00) WITH 'Error while displaying F4 help'.
ENDIF.

DATA: l_i_dynpfields TYPE STANDARD TABLE OF dynpread INITIAL SIZE 0,
l_wa_dynpfields TYPE dynpread.
IF p_name = 'TEST1'.
l_wa_dynpfields-fieldname = 'P_CTRY'.
l_wa_dynpfields-fieldvalue = 'IN'.
APPEND l_wa_dynpfields TO l_i_dynpfields.
ELSE.
l_wa_dynpfields-fieldname = 'P_CTRY'.
CLEAR l_wa_dynpfields-fieldvalue.
APPEND l_wa_dynpfields TO l_i_dynpfields.
ENDIF.

CALL FUNCTION 'DYNP_VALUES_UPDATE'
EXPORTING
dyname = sy-repid
dynumb = sy-dynnr
TABLES
dynpfields = l_i_dynpfields
EXCEPTIONS
invalid_abapworkarea = 1
invalid_dynprofield = 2
invalid_dynproname = 3
invalid_dynpronummer = 4
invalid_request = 5
no_fielddescription = 6
undefind_error = 7
OTHERS = 8.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDFORM. "sub_populate_f4_help

Get the entered value from a field on POV of another field using FM DYNP_VALUES_READ

Demo code on how to populate search help values dynamically depending upon values of another parameter on F4 button press. We have to use FM "DYNP_VALUES_READ".






The Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
*&---------------------------------------------------------------------*
*& Program : Z_TEST_PROGRAM
*& Created on : 23.07.2008 22:55:41
*&---------------------------------------------------------------------*
*& Test program for blog http://abap-explorer.blogspot.com/
*&---------------------------------------------------------------------*
REPORT z_test_program.

*Data Declaration
TYPES :
BEGIN OF x_spfli,
carrid TYPE s_carr_id,
connid TYPE s_conn_id,
END OF x_spfli.

DATA :
i_spfli TYPE STANDARD TABLE OF x_spfli INITIAL SIZE 0.
*Parameters
PARAMETERS:
p_carrid TYPE x_spfli-carrid OBLIGATORY,
p_connid TYPE x_spfli-connid.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_connid.

PERFORM sub_get_f4.

START-OF-SELECTION.

WRITE: / ' this is for testing'.
*&---------------------------------------------------------------------*
*& Form sub_get_f4
*&---------------------------------------------------------------------*
* Subroutine to populate F$ help
*----------------------------------------------------------------------*
FORM sub_get_f4 .
DATA:
l_i_dynpfields TYPE STANDARD TABLE OF dynpread INITIAL SIZE 0,
l_wa_dynpfields TYPE dynpread,
l_carrid TYPE s_carr_id.
*Populate the Parameter Name whoso value is required

l_wa_dynpfields-fieldname = 'P_CARRID'.
APPEND l_wa_dynpfields TO l_i_dynpfields.

*Call the FM to read that value
CALL FUNCTION 'DYNP_VALUES_READ'
EXPORTING
dyname = sy-repid
dynumb = sy-dynnr
* TRANSLATE_TO_UPPER = ' '
* REQUEST = ' '
* PERFORM_CONVERSION_EXITS = ' '
* PERFORM_INPUT_CONVERSION = ' '
* DETERMINE_LOOP_INDEX = ' '
TABLES
dynpfields = l_i_dynpfields
EXCEPTIONS
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
OTHERS = 11
.
IF sy-subrc = 0.
*Get the value
READ TABLE l_i_dynpfields INTO l_wa_dynpfields
WITH KEY fieldname = 'P_CARRID'.
IF sy-subrc = 0.
l_carrid = l_wa_dynpfields-fieldvalue.

SELECT
carrid " Airline Code
connid " Flight Connection Number
FROM spfli " Flight schedule
INTO TABLE i_spfli WHERE carrid = l_carrid.

CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
retfield = 'CONNID'
dynpprog = sy-repid
dynpnr = sy-dynnr
dynprofield = 'P_CONNID'
value_org = 'S'
TABLES
value_tab = i_spfli.
ENDIF.
ENDIF.
ENDFORM. " sub_get_f4

Call Maintenance View from a program using FM VIEW_MAINTENANCE_CALL

This code demonstrates how to call function module VIEW_MAINTENANCE_CALL to call a table maintenance view from any program.







The Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
*&---------------------------------------------------------------------*
*& Report Z_TEST_PROGRAM
*&---------------------------------------------------------------------*
*& Demo program for blog http://abap-explorer.blogspot.com/
*&---------------------------------------------------------------------*
REPORT z_test_program.
DATA:
i_sellist TYPE STANDARD TABLE OF vimsellist INITIAL SIZE 0,
i_header TYPE STANDARD TABLE OF vimdesc INITIAL SIZE 0,
i_namtab TYPE STANDARD TABLE OF vimnamtab INITIAL SIZE 0.

PARAMETERS: p_view TYPE viewname MATCHCODE OBJECT viewmaint OBLIGATORY.

AT SELECTION-SCREEN.

CALL FUNCTION 'VIEW_GET_DDIC_INFO'
EXPORTING
viewname = p_view
* VARIANT_FOR_SELECTION = ' '
TABLES
sellist = i_sellist
x_header = i_header
x_namtab = i_namtab
EXCEPTIONS
no_tvdir_entry = 1
table_not_found = 2
OTHERS = 3
.
IF sy-subrc <> 0.
data: l_message type NATXT.
CONCATENATE 'Table/View' p_view
INTO l_message SEPARATED BY space.
MESSAGE e001(00) WITH l_message ' not in the Dictonary'.
ENDIF.

START-OF-SELECTION.

CALL FUNCTION 'VIEW_MAINTENANCE_CALL'
EXPORTING
action = 'S'
view_name = p_view
EXCEPTIONS
client_reference = 1
foreign_lock = 2
invalid_action = 3
no_clientindependent_auth = 4
no_database_function = 5
no_editor_function = 6
no_show_auth = 7
no_tvdir_entry = 8
no_upd_auth = 9
only_show_allowed = 10
system_failure = 11
unknown_field_in_dba_sellist = 12
view_not_found = 13
maintenance_prohibited = 14
OTHERS = 15
.

IF sy-subrc <> 0.
MESSAGE i001(00) WITH 'Error while calling the view'.
LEAVE LIST-PROCESSING.
ENDIF.

Checking Syntax a program at runtime

Check out this test code to check syntactical errors in a code through a program. My test code will work only in unicode systems, as I have checked an unicode error.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
*&---------------------------------------------------------------------*
*& Report Z_TEST_SYNTAX_CHECK
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT z_test_syntax_check.
DATA: itab1 TYPE STANDARD TABLE OF string,
itab2 TYPE STANDARD TABLE OF string,
mess TYPE string,
lin TYPE i,
wrd TYPE string,
dir TYPE trdir.
**********************************************************************
APPEND 'PROGRAM test.' TO itab1.
APPEND 'DATA dat TYPE d.' TO itab1.
APPEND 'DATA len TYPE c.' TO itab1.
APPEND 'DESCRIBE FIELD dat LENGTH len.' TO itab1.

SELECT SINGLE *
FROM trdir
INTO dir
WHERE name = sy-repid.

SYNTAX-CHECK FOR itab1 MESSAGE mess
LINE lin WORD wrd
DIRECTORY ENTRY dir.

IF sy-subrc = 4.
WRITE: /1 'Error in first program:' , mess.
ELSE.
WRITE: /1 'No error in first program'.
ENDIF.
**********************************************************************
APPEND 'PROGRAM test.' TO itab2.
APPEND 'DATA dat TYPE d.' TO itab2.
APPEND 'DATA len TYPE i.' TO itab2.
APPEND 'DESCRIBE FIELD dat LENGTH len IN byte MODE.' TO itab2.

SYNTAX-CHECK FOR itab2 MESSAGE mess
LINE lin WORD wrd
DIRECTORY ENTRY dir.

IF sy-subrc = 4.
WRITE : /1 'Error in second program:' , mess.
ELSE.
WRITE: /1 'No error in second program'.
ENDIF.

Escape character for names in ABAP

Escape character for names.

The character “!” can be written directly before a name in order to distinguish it from an ABAP word of the same name in a statement. With the exception of the first word, each word of a statement that is preceded by the escape character is interpreted as an operand, and not as an ABAP word, in program generation. The escape character itself is not part of a name and is ignored when the statement is executed.

Note:

The escape character may be required on rare occasions in which the compiler cannot tell the difference between an operand and a reserved word of the same name. Otherwise, it can be used for the documentation of operands in the source code.

Example:

Without the escape character “!” before CHANGING after USING, the following program would be syntactically incorrect, because a formal parameter must be entered after USING. Although the second escape character is not necessary, it serves to document USING after CHANGING as a formal parameter.

We can’t activate this piece of code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
*&---------------------------------------------------------------------*
*& Report Z_TEST_PROGRAM
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT Z_TEST_PROGRAM.

data: var1 type char2,
var2 type char2.

var1 = 'TE'.
perform sub_test using var1 CHANGING var2.

FORM sub_test using changing
changing using.

using = changing.

endform.




But if we change the code to:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*&---------------------------------------------------------------------*
*& Report Z_TEST_PROGRAM
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT Z_TEST_PROGRAM.

data: var1 type char2,

var2 type char2.

var1 = 'TE'.

perform sub_test using var1 CHANGING var2.

FORM sub_test using !changing

changing !using.

using = changing.

endform.


This doesn't give any syntactical error, as shown below.

How to search for BADI's

Method 1: The BADI's can selected from the database view V_EXT_ACT and V_EXT_IMP.

Goto ST05 --> Select SQL trace and buffer trace --> Activate trace --> Now run your transaction --> Deactivate trace --> Display trace.

A pop will come as shown below:


Select following objects (Views)



Now display the trace results.
It will return all the BADI's and enhancement triggered in order of their execution.




Method 2: Using CL_EXITHANDLER=>GET_CLASS_NAME_BY_INTERFACE.

* Goto SE24, open CL_EXITHANDLER (Class).
* Goto Method, GET_INSTANCE.
* Set a BREAK-POINT.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
CALL METHOD CL_EXITHANDLER=&gt;GET_CLASS_NAME_BY_INTERFACE
EXPORTING
INSTANCE = INSTANCE
IMPORTING
CLASS_NAME = CLASS_NAME
CHANGING
EXIT_NAME = EXIT_NAME
EXCEPTIONS
NO_REFERENCE = 1
NO_INTERFACE_REFERENCE = 2
NO_EXIT_INTERFACE = 3
DATA_INCONS_IN_EXIT_MANAGEM = 4
CLASS_NOT_IMPLEMENT_INTERFACE = 5
OTHERS = 6.

CASE SY-SUBRC.

WHEN 1.
RAISE NO_REFERENCE.
WHEN 2.
RAISE NO_INTERFACE_REFERENCE.
WHEN 3.
RAISE NO_EXIT_INTERFACE.
WHEN 4.
RAISE DATA_INCONS_IN_EXIT_MANAGEM.
WHEN 5.
RAISE CLASS_NOT_IMPLEMENT_INTERFACE.
ENDCASE.


It will return the names of all Enhancements and BADI


Method 3: Using FM SXV_GET_CLIF_BY_NAME.

These steps should enable you to find any BADI related to any transaction in a matter of minutes.

1) Go to the transaction SE37 to find your function module.

2) Locate the function SXV_GET_CLIF_BY_NAME.

3) Put a BREAK-POINT there.

4) Now open a new session.

5) Go to your transaction.

6) At that time, it will stop this function.

7) Double click on the function field NAME.

8) That will give you name of the BADI that is provided in your transaction.

ABAP Performance Tuning Checkpoints

Run the program and check how much time its taking depending upon data volume.

Keep the following things in mind:

  • Hit a database table only once.
  • Use full primary key for data retrieval wherever possible with the fields in the where clause in sequence as in DB
  • Retrieve data from the DB on one hit,i.e. avoid SELECT-ENDSELECT block, as shown below:

  • 1
    2
    3
    4
    5
    SELECT f1 f2 f3
    from DB_TABLE
    into table I_TAB
    where f1 = '01' and
    f2 = '03'.


  • Avoid using MOVE-CORRESPONDING statement, use MOVE instead.
  • Avoid nested selects.
  • Avoid nested loops use parallel cursor instead.
  • Use table operations instead of operations within as loop.
  • Use binary search addition in READ TABLE when more than 20 records.Don't forget to sort the internal table.

Dynamic table display using CL_SALV_TABLE

Here is a simple code to display any table data using ALV using class CL_SALV_TABLE (factory method)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
*&---------------------------------------------------------------------*
*& Report ZSB_DYNAMIC_ALV
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

report zsb_dynamic_alv.
field-symbols:
<
f_tab1> type standard table.

parameters:
p_tname type tabname16 obligatory, " DEFAULT 'MARA' ,
p_rows(5) type c default '200'.
*----------------------------------------------------------------------*
* CLASS lcl_dynamic DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class lcl_dynamic definition .
public section.
methods:
check_selection
exceptions invalid_table,
main
exceptions no_data_found,
display.

private section.

type-pools: abap.

data: tab type ref to cl_abap_structdescr,
wa_tab type ref to cl_abap_structdescr,
comp_tab type cl_abap_structdescr=>component_table,
i_tab type ref to cl_abap_tabledescr,
i_table type ref to data.
endclass. "lcl_dynamic DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_dynamic IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class lcl_dynamic implementation.
method check_selection.

select count( * )
from dd02l
where tabname = p_tname
and as4local = 'A'
and tabclass = 'TRANSP'.

if sy-subrc <> 0.
raise invalid_table.
endif.
endmethod. "check_selection

method main.
tab ?= cl_abap_typedescr=>describe_by_name( p_tname ).

comp_tab = tab->get_components( ).

wa_tab = cl_abap_structdescr=>create( comp_tab ).

i_tab = cl_abap_tabledescr=>create( wa_tab ).

create data i_table type handle i_tab.

assign i_table->* to <f_tab1>.

if p_rows is initial.

p_rows = '50000'.

endif.

*Get data

select * from (p_tname)
into table <f_tab1>
up to p_rows rows.
if sy-subrc <> 0.
raise no_data_found.
endif.

endmethod. "main

method display.

set titlebar sy-title
of program sy-cprog
with 'Display table:' p_tname.

data:

l_gr_alv type ref to cl_salv_table,
l_gr_functions type ref to cl_salv_functions.

try.

call method cl_salv_table=>factory
importing
r_salv_table = l_gr_alv
changing
t_table = <f_tab1>.
catch cx_salv_msg . "#EC NO_HANDLER

endtry.

l_gr_functions = l_gr_alv->get_functions( ).
l_gr_functions->set_all( abap_true ).
l_gr_alv->display( ).

endmethod. "display

endclass. "lcl_dynamic IMPLEMENTATION

at selection-screen.


data oref_check type ref to lcl_dynamic.
create object oref_check.
call method oref_check->check_selection
exceptions
invalid_table = 1.

if sy-subrc <> 0.
message e001(00) with
p_tname ' is not a Transparant Table'.
endif.

start-of-selection.
data oref_main type ref to lcl_dynamic.
create object oref_main.
call method oref_main->main
exceptions
no_data_found = 1.
if sy-subrc <> 0.
message i001(00) with 'No data found'.
leave list-processing.
endif.

end-of-selection.

call method oref_main->display.