Learn how to enhance the standard data browser functionality (transaction codes SE16 and SE11) to add calculation base columns in any table or view using implicit enhancement options. For example, you can add a column showing the number of days difference between the created-on date and billing-processed date of an invoice in the billing document header table. You can add as many fields as you want in any standard table without any modification. Every time a user browses the enhanced table, the system shows the added fields.
Key Concept
Enhancement options allow you to add your own functionality to SAP standard programs without modifying the original code. They resemble plug-ins that you can add or remove any time as per your requirement. Your functionality remains the same even after an upgrade. There are many enhancement types, but to fulfill the current requirement, the implicit enhancement is the key.
In data browser SE16 and SE11 you can see all the fields available in a database table or view. These fields physically exist at the database level. However, you can’t add any extra fields if you want to show the result based on calculations (e.g., the Column A + Column B result should be in a new Column X, but Column X is not part of a database table or view). The following examples explain the scenario in more detail.
A standard example scenario is that you have a requirement to show the difference in days between the creation of a billing document and the time that the billing is processed. To fulfill this requirement you need to add one column in table VBRK (Billing Document Header Data). This column obtains its value by subtracting the billing date [FKDAT] from the created on-date [ERDAT] (e.g., New Column = FKDAT – ERDAT).
In another scenario you have a requirement to add two columns in table VBAK (Sales Document: Header Data). The first column shows you the net value of your sales order in euros regardless of currency of your sales order, and the second column shows you the currency key (EUR).
To fulfill both these scenarios, follow these simple steps:
Step 1. Create an enhancement and add the required code
Step 2. Test the enhancement
Step 1. Create an Enhancement and Add the Required Code
Open include LSETBF03 using transaction code SE38 or SE80. Click the enhance icon or press Shift+F4 (Figure 1).

Figure 1
Display include LSETBF03
Now you can see the include in enhancement mode. The left side of the code turns white (Figure 2).

Figure 2
The include in enhancement mode
Follow menu path Edit > Enhancement Operations > Show Implicit Enhancement Options.
At the start of the include, you can see the implicit enhancement point (Figure 3) at the start of the form alv_call. The alv_call is the form that displays the data. At the start of this form you add code to display one or more extra columns as per your requirements.

Figure 3
The implicit enhancement point at the start of form alv_call
Right-click the enhancement point line and select Enhancement Operations > Create Implementation from the context menu. In the pop-up message box that appears, click the Code button (Figure 4).

Figure 4
Select an enhancement type
In the next screen, enter the Enhancement Implementation name and Short Text (Figure 5). Click the green checkmark icon to go to Figure 6.

Figure 5
Enter the Enhancement Implementation name and Short Text
Click the new request icon highlighted in Figure 6. The transport request is like a bucket in which you place all your changed or newly created objects. Later, after testing, you transport this bucket to the quality system. After your changes are applied to the quality system and tested, you transport the request to the production system.

Figure 6
Create a new transport request
Enter a Short Description and click the save icon (Figure 7). In my short description in Figure 7, CBC stands for calculation base column.

Figure 7
Enter a short description of a transport request
Add the enhancement implementation object to the request by clicking the green checkmark icon (Figure 8). This is the enhancement implementation that you are entering in the standard code for adding the custom functionality.

Figure 8
Add the object to this request
Add the code in Figure 9 inside the enhancement and activate it (Figures 10 to 12). In Figure 10 you click the Enhancements button for activation. In this code using the name of a table or view, I am creating one field catalog, appending the new required fields in this field catalog, and finally creating a dynamic internal table. The internal table has all the fields of the original table or view and also has some additional fields that I am going to add in the table or view.
IF ( sy-tcode = 'SE16' OR sy-tcode = 'SE11' )
AND ( p_structure_name = 'VBRK' or p_structure_name = 'VBAK' ) " Add Table or View Name in this condition, in this example I am using VBRK and VBAK
.
DATA: zz_l_fieldcat TYPE slis_t_fieldcat_alv,
zz_l_fieldcat_line TYPE slis_fieldcat_alv,
zz_l_layout TYPE slis_layout_alv.
DATA: zz_l_it_event_exit TYPE slis_t_event_exit, "vjb note 1378529
zz_l_event_exit TYPE slis_event_exit,
zz_l_alv_settings TYPE type_alv_settings,
zz_l_first_alv_call,
zz_l_new_fields_exist.
DATA: zz_ref_new_table TYPE REF TO data,
zz_ref_new_line TYPE REF TO data.
DATA: zz_it1_fieldcat TYPE lvc_t_fcat,
zz_wa1_fieldcat LIKE LINE OF zz_it1_fieldcat.
FIELD-SYMBOLS: <zz_fcat> TYPE slis_fieldcat_alv,
<zz_it1> TYPE table,
<zz_wa1> TYPE any,
<zz_wa2> TYPE any,
<zz_day_diff> TYPE i,
<zz_fkdat> TYPE datum,
<zz_erdat> TYPE datum,
<zz_netwr1> TYPE any,
<zz_netwr2> TYPE any,
<zz_waerk1> TYPE any,
<zz_waerk2> TYPE any.
DATA: zz_ls_variant LIKE disvariant. "vjb note 1130222/1300475
CONCATENATE '/1BCDWB/DB_' p_structure_name '_' INTO zz_ls_variant-report. "vjb note 1130222/1300475
* ls_variant-report = p_structure_name.
IMPORT dd02l-mainflag dd02l-viewgrant global_auth
FROM MEMORY ID mem_id.
zz_l_event_exit-before = 'X'. "vjb note 1378529
zz_l_event_exit-ucomm = '&F03'.
APPEND zz_l_event_exit TO zz_l_it_event_exit.
zz_l_event_exit-ucomm = '&F12'.
APPEND zz_l_event_exit TO zz_l_it_event_exit.
zz_l_event_exit-ucomm = '&F15'.
APPEND zz_l_event_exit TO zz_l_it_event_exit.
CONCATENATE mem_id g_alv_table_name INTO g_alv_settings_id. "vjb note 1378529
IMPORT g_alv_settings FROM MEMORY ID g_alv_settings_id.
IF sy-subrc = 0.
"repeated ALV call for that table: use saved settings
zz_l_first_alv_call = ' '.
ELSE.
"first ALV call for that table: settings have to be defined completely
zz_l_first_alv_call = 'X'.
ENDIF.
* always initialize ALV fieldcat in table l_fieldcat
LOOP AT tab2.
IF tab2-tabname <> '*'.
CLEAR zz_l_fieldcat_line.
MOVE-CORRESPONDING tab2 TO zz_l_fieldcat_line.
CLEAR zz_l_fieldcat_line-tabname.
zz_l_fieldcat_line-ref_tabname = tab2-tabname.
IF rseumod-tbmode IS INITIAL.
zz_l_fieldcat_line-seltext_s =
zz_l_fieldcat_line-seltext_m =
zz_l_fieldcat_line-seltext_l =
zz_l_fieldcat_line-reptext_ddic = "vjb note 1132078
tab2-fieldname.
zz_l_fieldcat_line-ddictxt = 'L'.
ELSE.
READ TABLE g_field_names WITH KEY fieldname = tab2-fieldname.
IF NOT g_field_names-scrtext_s IS INITIAL.
zz_l_fieldcat_line-seltext_s = g_field_names-scrtext_s.
ELSE.
zz_l_fieldcat_line-seltext_s = tab2-fieldname.
ENDIF.
IF NOT g_field_names-scrtext_m IS INITIAL.
zz_l_fieldcat_line-seltext_m = g_field_names-scrtext_m.
ELSE.
zz_l_fieldcat_line-seltext_m = tab2-fieldname.
ENDIF.
IF NOT g_field_names-scrtext_l IS INITIAL.
zz_l_fieldcat_line-seltext_l = g_field_names-scrtext_l.
ELSE.
zz_l_fieldcat_line-seltext_l = tab2-fieldname.
ENDIF.
IF g_field_names-scrtext_s IS INITIAL AND
g_field_names-scrtext_m IS INITIAL AND
g_field_names-scrtext_l IS INITIAL AND
NOT g_field_names-fieldtext IS INITIAL.
zz_l_fieldcat_line-reptext_ddic = g_field_names-fieldtext.
CLEAR: zz_l_fieldcat_line-seltext_s, "vjb note 1633416
zz_l_fieldcat_line-seltext_m,
zz_l_fieldcat_line-seltext_l.
ENDIF.
zz_l_fieldcat_line-ddictxt = 'R'. "vjb note 1633416
ENDIF.
IF rseumod-tbconvert IS INITIAL.
zz_l_fieldcat_line-no_convext = 'X'.
ENDIF.
IF NOT ( tab2-flag1 O fkey ) .
* Kein Key-feld
IF tab2-checktable IS INITIAL.
* Keine Prüftabelle
ELSE.
* Nicht Schlüsselfeld mit Prüftabelle
zz_l_fieldcat_line-emphasize = 'X'.
ENDIF.
ELSE.
* Key-feld.
IF tab2-checktable IS INITIAL.
* Keine Prüftabelle
zz_l_fieldcat_line-key = 'X'.
ELSE.
* Schlüsselfeld mit Prüftabelle
zz_l_fieldcat_line-emphasize = 'X'.
zz_l_fieldcat_line-key = 'X'.
ENDIF.
ENDIF.
CLEAR zz_l_fieldcat_line-offset.
IF tab2-tabname <> p_structure_name.
CONCATENATE '%_' zz_l_fieldcat_line-fieldname
INTO zz_l_fieldcat_line-fieldname.
ENDIF.
* Set decfload if needed
IF tab2-dtyp = 'D16R' OR tab2-dtyp = 'D16D' OR tab2-dtyp = 'D16S'
OR tab2-dtyp = 'D34R' OR tab2-dtyp = 'D34D' OR tab2-dtyp = 'D34S'.
zz_l_fieldcat_line-decfloat_style = cl_abap_math=>scale_preserving.
ENDIF.
zz_l_fieldcat_line-ref_fieldname = tab2-fieldname.
IF tab2-reftable IS NOT INITIAL "note 1571782 v 2
AND tab2-reffield IS NOT INITIAL.
IF tab2-reftable = tab2-tabname.
"reffield belongs to the current table, too:
" check if user has excluded reffield from list output
READ TABLE tab2 WITH KEY fieldname = tab2-reffield TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
"reffield was not excluded from list output: cfieldname resp. qfieldname can be filled
CASE tab2-dtyp.
WHEN 'CURR'.
zz_l_fieldcat_line-cfieldname = tab2-reffield.
WHEN 'QUAN'.
zz_l_fieldcat_line-qfieldname = tab2-reffield.
ENDCASE.
ENDIF.
ENDIF.
ENDIF.
APPEND zz_l_fieldcat_line TO zz_l_fieldcat.
ENDIF.
ENDLOOP.
IF zz_l_first_alv_call = 'X'. "vjb note 1378529
"first ALV call for that table: define all needed ALV settings
zz_l_layout-box_fieldname = '%_BOX'.
zz_l_layout-detail_initial_lines = 'X'.
zz_l_layout-colwidth_optimize = 'X'.
zz_l_layout-f2code = '&ETA'.
CLEAR zz_l_alv_settings.
zz_l_alv_settings-s_layout = zz_l_layout.
zz_l_alv_settings-t_fieldcat = zz_l_fieldcat.
ELSE.
"repeated ALV call for that table:
"use as much saved ALV settings as possible ...
zz_l_alv_settings = g_alv_settings.
" ... but for all current fieldcat elements:
" actualize those fieldcat values that depend on rseumod-tbmode and rseumod-tbconvert
LOOP AT zz_l_fieldcat INTO zz_l_fieldcat_line.
READ TABLE zz_l_alv_settings-t_fieldcat ASSIGNING <zz_fcat>
WITH KEY fieldname = zz_l_fieldcat_line-fieldname.
IF sy-subrc = 0.
<zz_fcat>-seltext_s = zz_l_fieldcat_line-seltext_s.
<zz_fcat>-seltext_m = zz_l_fieldcat_line-seltext_m.
<zz_fcat>-seltext_l = zz_l_fieldcat_line-seltext_l.
<zz_fcat>-reptext_ddic = zz_l_fieldcat_line-reptext_ddic.
<zz_fcat>-ddictxt = zz_l_fieldcat_line-ddictxt.
<zz_fcat>-no_convext = zz_l_fieldcat_line-no_convext.
<zz_fcat>-cfieldname = zz_l_fieldcat_line-cfieldname. "note 1571782
<zz_fcat>-qfieldname = zz_l_fieldcat_line-qfieldname. "note 1571782 v 2
MODIFY zz_l_fieldcat FROM <zz_fcat>.
ELSE.
"a new field was added to fieldcat:
" invalidate current sort order (otherwise the ALV places the new fields
" automatically at first position)
zz_l_new_fields_exist = 'X'.
ENDIF.
ENDLOOP.
IF zz_l_new_fields_exist IS NOT INITIAL.
LOOP AT zz_l_fieldcat ASSIGNING <zz_fcat>.
<zz_fcat>-row_pos = 0.
<zz_fcat>-col_pos = 0.
ENDLOOP.
ENDIF.
zz_l_alv_settings-t_fieldcat[] = zz_l_fieldcat[].
ENDIF. "vjb note 1378529
CASE p_structure_name.
WHEN 'VBRK'. " Add Field to Field Catalog for Table VBRK
CLEAR: zz_l_fieldcat_line.
zz_l_fieldcat_line-fieldname = 'ZZ_DAY_DIFF'.
zz_l_fieldcat_line-inttype = 'I'.
zz_l_fieldcat_line-seltext_s = 'Days Diff.'.
zz_l_fieldcat_line-seltext_m = 'Days Diffrence'.
zz_l_fieldcat_line-seltext_l = 'Days Diffrence'.
APPEND zz_l_fieldcat_line TO zz_l_fieldcat.
WHEN 'VBAK'.
CLEAR: zz_l_fieldcat_line.
zz_l_fieldcat_line-fieldname = 'ZZ_EUR_NETWR'.
zz_l_fieldcat_line-inttype = 'I'.
zz_l_fieldcat_line-seltext_s = 'Z Net.V.'.
zz_l_fieldcat_line-seltext_m = 'Z Net Value'.
zz_l_fieldcat_line-seltext_l = 'Z Net Value'.
APPEND zz_l_fieldcat_line TO zz_l_fieldcat.
CLEAR: zz_l_fieldcat_line.
zz_l_fieldcat_line-fieldname = 'ZZ_EUR_WAERK'.
zz_l_fieldcat_line-inttype = 'C'.
zz_l_fieldcat_line-seltext_s = 'Z Curr.'.
zz_l_fieldcat_line-seltext_m = 'Z Currency'.
zz_l_fieldcat_line-seltext_l = 'Z Currency'.
APPEND zz_l_fieldcat_line TO zz_l_fieldcat.
* WHEN ''. " Add as Many fields as you want for any Table or View, Add Table or View name in this Condition
WHEN OTHERS.
ENDCASE.
zz_l_alv_settings-t_fieldcat[] = zz_l_fieldcat[].
CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
EXPORTING
i_structure_name = p_structure_name
CHANGING
ct_fieldcat = zz_it1_fieldcat
EXCEPTIONS
inconsistent_interface = 1
program_error = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CASE p_structure_name.
WHEN 'VBRK'.
zz_wa1_fieldcat-fieldname = 'ZZ_DAY_DIFF'.
zz_wa1_fieldcat-inttype = 'I'.
APPEND zz_wa1_fieldcat TO zz_it1_fieldcat.
WHEN 'VBAK'.
zz_wa1_fieldcat-fieldname = 'ZZ_EUR_NETWR'.
zz_wa1_fieldcat-inttype = 'I'.
APPEND zz_wa1_fieldcat TO zz_it1_fieldcat.
zz_wa1_fieldcat-fieldname = 'ZZ_EUR_WAERK'.
zz_wa1_fieldcat-inttype = 'C'.
APPEND zz_wa1_fieldcat TO zz_it1_fieldcat.
* WHEN .
WHEN OTHERS.
ENDCASE.
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
it_fieldcatalog = zz_it1_fieldcat
IMPORTING
ep_table = zz_ref_new_table
EXCEPTIONS
generate_subpool_dir_full = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ASSIGN zz_ref_new_table->* TO <zz_it1>.
CREATE DATA zz_ref_new_line LIKE LINE OF <zz_it1>.
ASSIGN zz_ref_new_line->* TO <zz_wa1>.
CASE p_structure_name.
WHEN 'VBRK'.
LOOP AT complete_table ASSIGNING <zz_wa2>.
MOVE-CORRESPONDING <zz_wa2> TO <zz_wa1>.
ASSIGN COMPONENT 'FKDAT' OF STRUCTURE <zz_wa1> TO <zz_fkdat>.
ASSIGN COMPONENT 'ERDAT' OF STRUCTURE <zz_wa1> TO <zz_erdat>.
ASSIGN COMPONENT 'ZZ_DAY_DIFF' OF STRUCTURE <zz_wa1> TO <zz_day_diff>.
<zz_day_diff> = <zz_fkdat> - <zz_erdat>.
APPEND <zz_wa1> TO <zz_it1>.
ENDLOOP.
WHEN 'VBAK'.
LOOP AT complete_table ASSIGNING <zz_wa2>.
MOVE-CORRESPONDING <zz_wa2> TO <zz_wa1>.
ASSIGN COMPONENT 'NETWR' OF STRUCTURE <zz_wa1> TO <zz_netwr1>.
ASSIGN COMPONENT 'ZZ_EUR_NETWR' OF STRUCTURE <zz_wa1> TO <zz_netwr2>.
ASSIGN COMPONENT 'WAERK' OF STRUCTURE <zz_wa1> TO <zz_waerk1>.
ASSIGN COMPONENT 'ZZ_EUR_WAERK' OF STRUCTURE <zz_wa1> TO <zz_waerk2>.
<zz_waerk2> = 'EUR'.
CALL FUNCTION 'CONVERT_AMOUNT_TO_CURRENCY'
EXPORTING
date = sy-datum
foreign_currency = <zz_WAERK2>
foreign_amount = <zz_netwr1>
local_currency = <zz_waerk1>
IMPORTING
local_amount = <zz_netwr2>
EXCEPTIONS
error = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
APPEND <zz_wa1> TO <zz_it1>.
ENDLOOP.
* WHEN .
WHEN OTHERS.
ENDCASE.
IF NOT rseumod-tbalv_grid IS INITIAL.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = 'SAPLSETB'
i_callback_pf_status_set = 'ALV_PF_STATUS'
i_callback_user_command = 'ALV_USER_COMMAND'
i_buffer_active = ' '
it_fieldcat = zz_l_alv_settings-t_fieldcat
it_sort = zz_l_alv_settings-t_sort
i_save = 'A'
is_variant = zz_ls_variant
TABLES
t_outtab = <zz_it1>
EXCEPTIONS
program_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ELSEIF NOT rseumod-tbalv_stan IS INITIAL.
CALL FUNCTION 'REUSE_ALV_LIST_DISPLAY'
EXPORTING
i_callback_program = 'SAPLSETB'
i_callback_pf_status_set = 'ALV_PF_STATUS'
i_callback_user_command = 'ALV_USER_COMMAND'
it_fieldcat = zz_l_alv_settings-t_fieldcat
it_sort = zz_l_alv_settings-t_sort
it_filter = zz_l_alv_settings-t_filter
i_save = 'A'
is_variant = zz_ls_variant
it_event_exit = zz_l_it_event_exit
TABLES
t_outtab = <zz_it1>
EXCEPTIONS
program_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDIF.
LEAVE TO SCREEN 0.
ENDIF.
Figure 9
Code for enhancement Z_CBC_DB_SE16_SE11
After adding code in the enhancement, you need to activate it by clicking the Enhancements button in Figure 10 or by using the shortcut key (Ctrl+F3).

Figure 10
Activate the enhanced code
You then see the enhancement object selected in the next window (Figure 11). Click the green checkmark icon.

Figure 11
Click the green checkmark
Now you can see that the enhancement is activated (Figure 12).

Figure 12
Enhancement activated
Step 2. Test the Enhancement
Now you are ready to test the enhancement for tables VBRK and VBAK. Execute transaction code SE16 or SE11. If you use SE16 enter the table or view name. Click the Table Contents button or press F7 (Figure 13). The system displays the Table VBRK: Selection Screen shown in Figure 14.

Figure 13
Enter the name of the table or view

Figure 14
The Table VBRK: Selection Screen
If you execute transaction code SE11, enter the table name in the Database table field or view name in View field of the screen that appears. Click the Display button (Figure 15).

Figure 15
Click the Display button
In the next window click the contents icon (highlighted) or press Ctrl+Shift+F10 (Figure 16). This action returns you to Figure 14.

Figure 16
Click the contents icon or press Ctrl+Shift+F10
After you click the execute icon in Figure 14, you notice that a new column is added with the heading Days Diff. (Figure 17).

Figure 17
One new column added in table VBRK
Using same method you can check table VBAK, to which you added two columns (Figure 18).

Figure 18
Two new columns added in table VBAK
Faisal Altaf
Faisal Altaf is a certified development consultant. He has more than seven years of experience and currently is working with Al Yamamah Steel Industries Co., Saudi Arabia, as the SAP technical division head. He completed his MS in software engineering and intends to complete his Ph.D. in the field of SAP.
You may contact the author at faisalatsap@gmail.com.
If you have comments about this article or publication, or would like to submit an article idea, please contact the editor.