Showing posts with label SAP ABAP. Show all posts
Showing posts with label SAP ABAP. Show all posts

Remove Header on Last Page in Classical Report

Posted by Krishh Webworld | 6:19 PM | , , | 1 comments »

This code provides logic to remove the Header generated by TOP-OF-PAGE from the Last Page.


CODE Snippet
*&---------------------------------------------------------------------*
*& Report ZTEST_NP_TOP_LAST *

*&---------------------------------------------------------------------*

*& Example of how to remove the header generated by TOP-OF-PAGE and *

*& Move the LIST upwards in the space of the TOP-OF-PAGE *

*& *

*&---------------------------------------------------------------------*


REPORT ZTEST_NP LINE-COUNT 10(2) NO STANDARD PAGE HEADING.


START-OF-SELECTION.
* Generating the Output
DO 30 TIMES.
WRITE: / SY-ABCDE.
ENDDO.


* Clearing the last TOP-OF-PAGE
READ LINE 1 OF PAGE SY-PAGNO.
CLEAR SY-LISEL.
MODIFY LINE 1 OF PAGE SY-PAGNO.


* Moving list upword
* Here we are moving only 2 lines, as we have only 2
* lines in our TOP-OF-PAGE
DATA: L_CNT TYPE I,
L_LINE TYPE I.
CLEAR: L_CNT, L_LINE.
L_LINE = 2.
DO.
L_CNT = L_CNT + 1.
L_LINE = L_LINE + 1.
READ LINE L_LINE OF PAGE SY-PAGNO.
IF SY-SUBRC NE 0.
EXIT.
ELSE.
MODIFY LINE L_CNT OF PAGE SY-PAGNO.
CLEAR SY-LISEL.
MODIFY LINE L_LINE OF PAGE SY-PAGNO.
ENDIF.
ENDDO.

* Top of page
TOP-OF-PAGE.
WRITE: / 'Heading from TOP OF PAGE Line 1'.
WRITE: / 'Line 2'.

Move Cursor to next Row by Pressing Enter in OO ALV

Posted by Krishh Webworld | 6:18 PM | , , | 2 comments »

I was wondering if it is possible to have the same functionality of the Excel: Press Enter and cursor will move to next row.

As OO ABAP using the class CL_GUI_ALV_GRID provides so many methods for the processing at the Cell Levels. After looking to all the methods of the CL_GUI_ALV_GRID, I found there are so many methods which can do the processing at the Cell level. I have started to give the try. After certain tries, I was able to achieve what I was looking for.


Code Snippet for the Class handler for ALV Grid Call
*&---------------------------------------------------------------------*
*& This code snippet sets the handler of the evnets for the OO ALV
*&---------------------------------------------------------------------*
* Data Declaration

DATA: g_grid type ref to cl_gui_alv_grid,
g_event_receiver type ref to lcl_event_receiver.

*
* Registering the Edit event
CALL METHOD g_grid->register_edit_event
EXPORTING
i_event_id = cl_gui_alv_grid=>mc_evt_enter.
*
* Event Handler
create object g_event_receiver.
*
* Event listner method for Edit Event
SET HANDLER g_event_receiver->handle_data_changed FOR g_grid.
*
* calling the instance of the ALV
call method g_grid->set_table_for_first_display
changing it_fieldcatalog = gt_fieldcat
it_outtab = gt_outtab[].


Code Snippet for the Class handler definition and Implementation
*&---------------------------------------------------------------------*
*& This code snippet shows the Event Handler Class's Definition
*& and implementation
*&---------------------------------------------------------------------*
* Definition

class lcl_event_receiver definition.

public section.
methods:
handle_data_changed FOR EVENT data_changed
OF cl_gui_alv_grid
IMPORTING er_data_changed.

endclass.


* Class Implementation
class lcl_event_receiver implementation.
method handle_data_changed.
*
* Local data
data: LE_ROW TYPE I,
LE_VALUE TYPE C,
LE_COL TYPE I,
LES_ROW_ID TYPE LVC_S_ROW,
LES_COL_ID TYPE LVC_S_COL,
LES_ROW_NO TYPE LVC_S_ROID.
*
* Getting Current Cell
CALL METHOD G_GRID->GET_CURRENT_CELL
IMPORTING
E_ROW = le_row
E_VALUE = le_value
E_COL = le_col
ES_ROW_ID = les_row_id
ES_COL_ID = les_col_id
ES_ROW_NO = les_row_no.
*
* Total number of tables
describe table gt_outtab lines sy-index.
*
* Getting next row
les_row_id-INDEX = les_row_id-INDEX + 1.
les_row_no-ROW_ID = les_row_no-ROW_ID + 1.
*
* Set the Next row
if les_row_id-index le sy-index.
CALL METHOD G_GRID->SET_CURRENT_CELL_VIA_ID
EXPORTING
IS_ROW_ID = les_row_id
IS_COLUMN_ID = LES_COL_ID
IS_ROW_NO = les_row_no.
endif.
endmethod.
endclass.

SAP ABAP Object Design Patterns: Singleton

Posted by Krishh Webworld | 6:13 PM | , , , | 2 comments »

Today we will try to explore the design patterns in the ABAP Objects. We will start with the Singleton design pattern, which is the simplest of its family of design patterns.


What is the concept of the Singleton design pattern?
The concpet of restricting the instantiation of the a class to only and only to one object is called Singleton. As name suggests, it will restrict to create only one instance of a class. The calss will have a logic in place which will deny if the application will ask for more than one instance.

Let's try to understand with an example:
We have an application which will bring the pay stub of an employee for current month. In a standarad system, there will be only one active salary account for the employee with the company. Because of this fact, we should only create one object of the employee's salary account. In program, we are creating this object in a loop. So, what happens if we don't have a design pattern which will restrict it to create more than one object. Application will create, rather overwrite an instance of the class.

In ABAP, generally we check if the instance is created or not, like:
Code Snippet to check instance
 
*&---------------------------------------------------------------------*
DATA: lo_application TYPE REF TO lcl_application.
IF lo_application IS INITIAL.
CREATE OBJECT lo_application.
ENDIF.

But, if we take another reference to the class and create a instance of that, it will definatly allow. So, we need to have Singleton design pattern implemented.

How to implement Singleton design Pattern in ABAP?
We can use the CLASS-DATA(static data) to save the created instance within the class and check with that instance, if application asks for a new instance.

We will look at this example.

UML diagrm for the example:



Code Snippet for Design Patterns: Singleton
  
*&---------------------------------------------------------------------*
*& Report shows how to use the static data of the class to
*& implement the design patterns.
*&---------------------------------------------------------------------*
REPORT ztest_singleton_pattern.
*
*----------------------------------------------------------------------*
* CLASS lcl_application DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_application DEFINITION.
*
PUBLIC SECTION.
* Static Method which will return us the object reference
CLASS-METHODS:
get_apps_instance
EXPORTING
eo_apps TYPE REF TO lcl_application.
*
PRIVATE SECTION.
* static class reference to hold the existing object reference
CLASS-DATA: lo_apps TYPE REF TO lcl_application.
*
ENDCLASS. "lcl_application DEFINITION
*
*
*----------------------------------------------------------------------*
* CLASS lcl_application IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_application IMPLEMENTATION.
*
* This method will return the object reference to the calling application
METHOD get_apps_instance.
IF lo_apps IS INITIAL.
* creation of the object
CREATE OBJECT lo_apps.
* assigning reference back to exporting parameter
eo_apps = lo_apps.
ENDIF.
ENDMETHOD. "get_apps_instance
ENDCLASS. "lcl_application IMPLEMENTATION
*
*
START-OF-SELECTION.
*
*.Reference: 1 .........................................
DATA: lo_application TYPE REF TO lcl_application.
WRITE: / 'LO_APPLICATION: '.
* calling the method which gets us the instance
CALL METHOD lcl_application=>get_apps_instance
IMPORTING
eo_apps = lo_application.
IF lo_application IS NOT INITIAL.
WRITE: / 'Object has been created..!'.
ELSE.
WRITE: / 'Error: Object has not been created..!'.
ENDIF.
*
*.Reference: 2............................................
DATA: lo_2nd_apps TYPE REF TO lcl_application.
SKIP 2.
WRITE: / 'LO_2ND_APPS : '.
* calling the method which gets us the instance
* Our instance will be initial here because the STATIC calss
* reference LO_APPS in the calss LCL_APPLICATION will prevent
* this call to create a new instance.
CALL METHOD lcl_application=>get_apps_instance
IMPORTING
eo_apps = lo_2nd_apps.
IF lo_2nd_apps IS NOT INITIAL.
WRITE: / 'Object has been created..!'.
ELSE.
WRITE: / 'Error: Object has not been created..!'.
ENDIF.



This will generate the output like this:

SAP Classical ALV: Change Subtotal

Posted by Krishh Webworld | 6:11 PM | , , | 1 comments »

Sometimes we need to modify the subtotals on the ALV, specially when we have to give the average of the percentages or something like that. To change the subtotal we need to follow certain steps:

1. we need to get the ALV object form the ALV function module. We can use the FM GET_GLOBALS_FROM_SLVC_FULLSCR to get the Global data of the ALV. From this FM we will get the ALV object.

2. After getting the ALV object, we need to get the subtotal using the method GET_SUBTOTALS of the ALV object. We will get the first level subtotal using the parameter EP_COLLECT01.

3. Now, we need to modify the subtotal. Here we need to take help of Field-symbols since the EP_COLLECT01 is reference to data.

4. We need to refresh the Table display. For this purpose we can use the method REFRESH_TABLE_DISPLAY.

Here is the code snippet which performs all the steps mentioned above:


Code Snippet to change the Subtotal
  
DATA: lo_grid TYPE REF TO cl_gui_alv_grid.
*
* get the global reference
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = lo_grid.
*
* get the subtotal
DATA: it_01 TYPE REF TO data.
*
CALL METHOD lo_grid->get_subtotals
IMPORTING
ep_collect01 = it_01.
*
* change the data
FIELD-SYMBOLS: TYPE ANY TABLE,
TYPE ANY,
TYPE ANY.
ASSIGN it_01->* TO .
*
LOOP AT ASSIGNING .
ASSIGN COMPONENT 'PER' OF STRUCTURE TO .
= '100'.
ENDLOOP.
*
* Refresh the table display
CALL METHOD lo_grid->refresh_table_display
EXPORTING
i_soft_refresh = 'X'.



To be able to use the FM GET_GLOBALS_FROM_SLVC_FULLSCR, we need to find a spot in our program which is being called after the ALV's main FM e.g. REUSE_ALV_GRID_DISPLAY. For this purpose, I have implemented the TOP_OF_PAGE event because it will always be called after the FM. In the subroutine for the TOP_OF_PAGE, I used the code snippet to change the Subtotal.

You can download the entire source code of my test program from here --> http://smartform.googlecode.com/files/ZALV_SUBTOT_CHANGE.txt .

Add Custom Button on Maintianence View (SM30)

Posted by Krishh Webworld | 12:45 PM | , , | 0 comments »

Whenever we generate the table maintianence, SAP generates some new code and use the Shared code for the Table maintainence generator. Since long time, I was wondering how can I add my own custom PF buttons in the table maintainence screen which comes in SM30. Today, this discussion in the SDN form raised this point in my mind again - Adding Custon button on Maintainance View.

I have started searching the GUI status in the Function Group which I have provided in the Table maintainence generator, but I didn't find it in the object browser (SE80) of the Function group. So, I thought this must be taken care by the Events in the Table maintainence. I searched the list and I found suitable one - ST (GUI Menu Main Program Name). Follow this link for mor information on Table maintenace events - Extended Table Maintenance Events

To add a custom button we need to follow couple of steps:
1. Create Table Maintainence.
Obviously today's discussion is based on the Table maintaince, we must have that before we start it. For a information purpose, I will attach a screen shot of the Table maintaince.


2. Copy user Interface of program SAPLSVIM to our FG
We will copy all the user interface of the main table maintainence program to our Fuction Group. Table maintainence runtime uses the user interface from the program SAPLSVIM. So, we are unable to find any user interface in our FG.


There will be one popup of language compatability, which you can pass it on by pressing Enter.

3. Add Custom Button in the PF-Status
Here we need to identify the proper PF-Status from all the statues. We will use the EULG pf-status which is being called when you enter in SM30 with Change mode. We will add the button with code "0POPUP" We can simply check which pf-status is being used in the each screen of the SM30 by going System > Status > GUI status. We will activate the changed status.

4. Add Event ST in the Table modification Events
Open the table maintainence generator screen and follow: Environment -> Modification -> Events. Select ST from the values and enter the FG main program name. For this example SAPLZTEST_TABLES.


5. Add PAI module in the Screen
Now, we need to create a new PAI module in the Screen flow. We will create the module 0CUSTOM_PF_BUTTON in the Screen. We will create this module in a New Custom include by selecting it from the popup.

In this code snippet, I am showing how to handle our user command. Here I am just giving information popup when user interact with the button in the change mode.

Code Snippet for Handling custom button
  *----------------------------------------------------------------------*
***INCLUDE LZTEST_TABLESI01 .

*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Module CUSTOM_PF_BUTTON INPUT
*&---------------------------------------------------------------------*
* Custom Button Handling
* Here TOTAL table is avliable with all the data.
* User command is stored in the field FUNCTION
*----------------------------------------------------------------------*
MODULE 0custom_pf_button INPUT.
*
DATA: l_count TYPE i.
* Table of the same structure of the TOTAL which can be exported
DATA: BEGIN OF itab OCCURS 0.
INCLUDE STRUCTURE ztest_pf_status.
INCLUDE STRUCTURE vimflagtab.
DATA: END OF itab.
*
CASE function.
WHEN '0POPUP'.
itab[] = total[].
*
DELETE itab WHERE mark IS INITIAL.
DESCRIBE TABLE itab LINES l_count.

*
CALL FUNCTION 'POPUP_TO_INFORM'
EXPORTING
titel = 'Information'
txt1 = 'Selected number of entries'
txt2 = l_count.
*
CLEAR l_count.
*
ENDCASE.
*
ENDMODULE. " CUSTOM_PF_BUTTON INPUT


Don't forget to activate the Function Group, since we have created a new include in it.

6. Custom button on the SM30
Here is the screenshot of the SM30 with our new added custom button.

After pressing button, it will react like this:

Posted by Krishh Webworld | 12:43 PM | , , | 0 comments »

The requirement is to capture the changed contents – updated, deleted or inserted – after the table maintenance call using the FM VIEW_MAINTENANCE_CALL.

The simple solution to handle this requirement is:
1. Get all the data from the database table for which we will call the FM VIEW_MAINTENANCE_CALL.
2. Call FM VIEW_MAINTENANCE_CALL
3. Get all the data from the database table again in separate internal table Compare the contents of the data using some utility.

This kind of generic solution would be possible, but the performance of the report would be slow. I thought of having something which can tell us directly just after the FM call, which line was changed: update or deleted or inserted. Suddenly, I thought of implementing the Event and use the same data which are there in the global tables of the Maintenance Function.

Based on the thought, new steps to achieve this solution would be:
1. Implement Event in the Maintenance. Export the Main internal table to ABAP memory, which can be accessed later from the calling program.
2. Call the FM VIEW_MAINTENANCE_CALL
3. Import the data from the ABAP memory

In this later approach, we can get the data instantly from the memory. Since we will have the indicators (ACTION field in the table) which will help us to identify the type of change made to table entries.

You can find more information on the Events of the Table Maintenance at: Extended Table Maintenance Events

To implement the solution, I have used the Event 01 - Before Saving the data into Database. We need to create the subroutine which can be called when the event gets hit. When we create a subroutine, it will be created in the same Function group in which we have created the Table mainteinance. Hence, it will provide us the access to all the global tabbles. From all of these tables, we will export the internal table TOTAL to the memory.

TOTAL table contains the fields: ACTION and MARK.

Content of the ACTION field would help us to indetify the type of change:
D – Delete
U – Update
N – New Entry



Code Snippet to Export data in Event 01
 
*&---------------------------------------------------------------------*
*& Form EXPORT_TOTAL_TABLE
*&---------------------------------------------------------------------*
* This form is called in the Event 01 of the table maintainence
* events
*----------------------------------------------------------------------*
FORM EXPORT_TOTAL_TABLE.
*
* Table of the same structure of the TOTAL which can be exported
DATA: BEGIN OF ITAB OCCURS 0.
INCLUDE STRUCTURE ZTEST_NP_EVENT.
INCLUDE STRUCTURE VIMFLAGTAB.
DATA: END OF ITAB.
*
* Moving data to ITAB from total
ITAB[] = TOTAL[].
*
* Clearing memory
FREE MEMORY ID 'ZTEST_EVENT'.
*
* Exporting data to Memory
EXPORT ITAB = ITAB TO MEMORY ID 'ZTEST_EVENT'.
*
ENDFORM. "EXPORT_TOTAL_TABLE



Code Snippet of the Report
 
*&---------------------------------------------------------------------*
*& Report ZTEST_NP_EVENT
*&---------------------------------------------------------------------*
*& This Report will start the Table Maintainence and after saving the
*& data in the table maintinence, it will generate a list which will
*& what data has been newly added, updated or deleted
*&---------------------------------------------------------------------*
REPORT ZTEST_NP_EVENT.
*
* Table with the Same structure of the table which is exported.
DATA: BEGIN OF ITAB OCCURS 0.
INCLUDE STRUCTURE ZTEST_NP_EVENT.
INCLUDE STRUCTURE VIMFLAGTAB.
DATA: END OF ITAB.
*
* Output table
TYPES: BEGIN OF TY_OUT.
INCLUDE TYPE ZTEST_NP_EVENT.
INCLUDE TYPE VIMFLAGTAB.
TYPES: END OF TY_OUT.
*
DATA: IT_OUTPUT TYPE STANDARD TABLE OF TY_OUT.
*
* Output ALV reference
DATA: O_ALV TYPE REF TO CL_SALV_TABLE.
*
*
START-OF-SELECTION.
* Start the Table maintainence
CALL FUNCTION 'VIEW_MAINTENANCE_CALL'
EXPORTING
ACTION = 'U'
VIEW_NAME = 'ZTEST_NP_EVENT'
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.
ENDIF.
*
* Importing the memory from the Memory ID
* Table has been exported in the Event 01 of the Table
* maintenance events.
IMPORT ITAB TO ITAB FROM MEMORY ID 'ZTEST_EVENT'.
*
* Clear the memory id
FREE MEMORY ID 'ZTEST_EVENT'.
*
* Moving data to output
IT_OUTPUT = ITAB[].
DELETE IT_OUTPUT WHERE ACTION IS INITIAL.
*
* New ALV Instance
TRY.
CL_SALV_TABLE=>FACTORY(
EXPORTING
LIST_DISPLAY = ABAP_FALSE
IMPORTING
R_SALV_TABLE = O_ALV
CHANGING
T_TABLE = IT_OUTPUT ).
CATCH CX_SALV_MSG. "#EC NO_HANDLER
ENDTRY.
*
* Display the ALV
O_ALV->DISPLAY( ).

Dynamic Internal Table Creation

Posted by Krishh Webworld | 12:35 PM | , , | 1 comments »

Shows how to use the RTTS to create a dynamic internal table


From the ABAP release 6.40, SAP has provided RTTS - Run Time Type Services to create types, internal tables at run-time. This RTTS can also be used to describe the properties of the types as well as the fields, internal tables etc.

Sometimes, when we write a program, we don't have all the information of the fields of the internal table. For example: we are accessing the cost element Actul posting data from the table COSP. Now, we have a requirement to generate an output which will have some specified columns - like amount of period 4 to 8 or Amount of period 1 to 3 or some other combination. This kind of secnarioes are perfect examples of the RTTS. We will see how to create a dynamic internal table using this example.

To create a dynamic internal table, we need to:
1. Gather all the Components
2. Generate a Type from this components
3. Generate a Table Type from this created type
4. Create a Data reference of this Table Type
5. Assign this data reference to the Field-Symbol of table type. This Field-symbol will act as our dyanmic internal table

In today's example we will see how to:
1. Create Dynamic internal table
2. Write dynamic select query to data into this dynamic table
3. Change the contents of this dynamic internal table
4. Generate the ALV display using SALV model for this dynamic internal table. Explore how to create ALV using SALV from Tutorials > SALV Table

We will provide the selection of the period for which user wants to generate an output. Based on the entered periods we will create a dynamic type containg the KSTAR (Costing Element) and Amount fields for the month. After creating the dynamic type, we will create a dynamic table type. Using this table type we will create a reference of the data. From this data reference we will assign the internal table to field-symbols.

So, let's see the code snippet:
Code Snippet to create Dynamic ITAB
  
*&---------------------------------------------------------------------*
*& This Code snippet shows how to
*& Create Dynamic Internal Table
*& Dynamic Selection of data
*& Accessing Dynamic data selection
*& Displaying Dynamic internal table in ALV
*&---------------------------------------------------------------------*
report zdynamic_itab.
*
* Exisiting Table type
TYPES: BEGIN OF ty_kstar,
kstar TYPE kstar,
END OF ty_kstar.
*
* Dynamic Table creation
DATA: lo_struct TYPE REF TO cl_abap_structdescr,
lo_element TYPE REF TO cl_abap_elemdescr,
lo_new_type TYPE REF TO cl_abap_structdescr,
lo_new_tab TYPE REF TO cl_abap_tabledescr,
lo_data TYPE REF TO data,
lt_comp TYPE cl_abap_structdescr=>component_table,
lt_tot_comp TYPE cl_abap_structdescr=>component_table,
la_comp LIKE LINE OF lt_comp,
lf_months TYPE monat,
lf_run_mon TYPE monat.
*
* Dynamic Selection fields
TYPES: BEGIN OF ty_fields,
field TYPE char30,
END OF ty_fields.
*
DATA: lt_fields TYPE STANDARD TABLE OF ty_fields,
la_fields TYPE ty_fields.
*
* field symbols to access the dynamic table
FIELD-SYMBOLS: TYPE ANY TABLE,
TYPE ANY,
TYPE ANY.
*
* Selection Screen
PARAMETERS: p_mon_fr TYPE monat,
p_mon_to TYPE monat.
*
START-OF-SELECTION.
*
*$*$*...............Dynamic Internal Table........................*$*$*
* 1. Getting Compoents from existing type
lo_struct ?= cl_abap_typedescr=>describe_by_name( 'TY_KSTAR' ).
lt_comp = lo_struct->get_components( ).
APPEND LINES OF lt_comp TO lt_tot_comp.
*
* 2. Adding required fields based on the single data element
* Determining Number of fields
lf_months = ( p_mon_to - p_mon_fr ) + 1.
lf_run_mon = p_mon_fr.
*
DO lf_months TIMES.
*
* Element Description
lo_element ?= cl_abap_elemdescr=>describe_by_name( 'WTGXXX' ).
*
* Field name
CONCATENATE 'WTG0' lf_run_mon INTO la_comp-name.
*
* Field type
la_comp-type = cl_abap_elemdescr=>get_p(
p_length = lo_element->length
p_decimals = lo_element->decimals ).
*
* Filling the component table
APPEND la_comp TO lt_tot_comp.
CLEAR: la_comp.
*
lf_run_mon = lf_run_mon + 1.
ENDDO.
*
* 3. Create a New Type
lo_new_type = cl_abap_structdescr=>create( lt_tot_comp ).
*
* 4. New Table type
lo_new_tab = cl_abap_tabledescr=>create(
p_line_type = lo_new_type
p_table_kind = cl_abap_tabledescr=>tablekind_std
p_unique = abap_false ).
*
* 5. data to handle the new table type
CREATE DATA lo_data TYPE HANDLE lo_new_tab.
*
* 6. New internal table in the fieldsymbols
ASSIGN lo_data->* TO .
*
*$*$*...............Dynamic Selection.............................*$*$*
* Filling up the table for the Selection fields of Select Query
LOOP AT lt_tot_comp INTO la_comp.
la_fields-field = la_comp-name.
APPEND la_fields TO lt_fields.
CLEAR: la_comp, la_fields.
ENDLOOP.
*
* Selecting data
SELECT (lt_fields)
INTO TABLE
FROM cosp
UP TO 10 ROWS.
*
*$*$*...............Accessing dynamic table.......................*$*$*
LOOP AT ASSIGNING .
ASSIGN COMPONENT 'WTG004' OF STRUCTURE TO .
= '100.00'.
ENDLOOP.
*
*
*$*$*...............Displaying using SALV model...................*$*$*
*
DATA: lo_alv TYPE REF TO cl_salv_table.
*
TRY.
cl_salv_table=>factory(
EXPORTING
list_display = abap_false
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table = ).
CATCH cx_salv_msg .
ENDTRY.
*
lo_alv->display( ).

SALV Hierarchical Table 3 - Add Expand/Collapse Option

Posted by Krishh Webworld | 12:31 PM | , , | 0 comments »

Today in the series of the SALV Hiearchical list display, we will see how to add the Expand/Collapse button in the Hierarchical ALV. All discussion related to the Hierarchical table display can be found under Tutorials > SALV HS List.

Expand/Collapse button will provide an option to users to only see the Header List. By selecting the expand button, it will show both Header and detail List. By selecting the same button again it will collapse the list and gives only the header list.

Here is the code Snippet which provides the ADD-ON code. This ADD-ON code can be replaced with the relevent section from this code snippet in the base program. You can find the base program code snippet in the post SALV Hierarchical Table 1 : Simple table display. Adding code to base program is like adding the code correction from the OSS Note. Additionally, we will always include the default PF-status in all the code snippet.

UML diagram for the application would be like:

Code snippet to get the Expand / Collapse option in Hierarchical ALV.

Code Snippet to get Expand / Collapse option
 *$*$*.....CODE_ADD_1 - Begin..................................1..*$*$*
*
* In this section we will define the private methods which can
* be implemented to set the properties of the ALV and can be
* called in the GENERATE_OUTPUT method
*
PRIVATE SECTION.
METHODS:
set_default_pf
CHANGING

co_hs_alv TYPE REF TO cl_salv_hierseq_table.
*
METHODS:
set_expand_option
CHANGING
co_hs_alv TYPE REF TO cl_salv_hierseq_table.
*$*$*.....CODE_ADD_1 - End....................................1..*$*$*
*
*
*$*$*.....CODE_ADD_2 - Begin..................................2..*$*$*
*

* In this area we will call the methods which will set the
* different properties to the ALV
*
* Default PF status
CALL METHOD me->set_default_pf
CHANGING
co_hs_alv = o_hs_alv.
*
* Expand Option
CALL METHOD me->set_expand_option
CHANGING

co_hs_alv = o_hs_alv.
*$*$*.....CODE_ADD_2 - End....................................2..*$*$*
*
*
*$*$*.....CODE_ADD_3 - Begin..................................3..*$*$*
*
* In this area we will implement the methods which are defined in
* the class definition
*
METHOD set_default_pf.
DATA: lo_functions TYPE REF TO cl_salv_functions_list.

lo_functions = co_hs_alv->get_functions( ).
lo_functions->set_all( abap_true ).
ENDMETHOD. "set_default_pf
*
METHOD set_expand_option.
*
DATA:
lo_columns TYPE REF TO cl_salv_columns_hierseq.
*
* Get the Columns of the Master
TRY.
lo_columns = co_hs_alv->get_columns( 1 ).
CATCH cx_salv_not_found.
ENDTRY.
*
* set expand column
TRY.
lo_columns->set_expand_column( 'EXPAND' ).
CATCH cx_salv_data_error. "#EC NO_HANDLER
ENDTRY.
*
DATA: lo_level TYPE REF TO cl_salv_hierseq_level.
*
* Set items expanded by default
TRY.
lo_level = co_hs_alv->get_level( 1 ).
lo_level->set_items_expanded( ).
CATCH cx_salv_not_found.
ENDTRY.
*
ENDMETHOD. "set_expand_option
*$*$*.....CODE_ADD_3 - End....................................3..*$*$*



This code will generate output like:

SALV Hierarchical Table 2 - Adding Default PF Status

Posted by Krishh Webworld | 11:45 AM | , , | 0 comments »

Today we will discuss how easy it is to add a Default PF status. In the previous post, we have discussed how to create a simple hierarchical table: SALV Hierarchical Table 1 - Simple table display. All discussion related to hierarchical (sequential) table can be found under Tutorials > SALV HS List.

To add a default PF status in the hierarchial (sequential) list created using the reference of the class CL_SALV_HIERSEQ_TABLE, we need to get the all the default PF status functions using the method GET_FUNCTIONS of the reference of the CL_SALV_HIERSEQ_TABLE.

Here is the code Snippet which provides the ADD-ON code. This ADD-ON code can be replaced with the relevent section from this code snippet in the base program. You can find the base program code snippet in the post SALV Hierarchical Table 1 : Simple table display. Adding code to base program is like adding the code correction from the OSS Note.

UML diagram of the our test program would be like:
Code snippet to add the default pf status is as follows:


Code Snippet
  
*$*$*.....CODE_ADD_1 - Begin..................................1..*$*$*
*
* In this section we will define the private methods which can

* be implemented to set the properties of the ALV and can be
* called in the GENERATE_OUTPUT method
*
PRIVATE SECTION.
METHODS:
set_default_pf
CHANGING
co_hs_alv TYPE REF TO cl_salv_hierseq_table.
*$*$*.....CODE_ADD_1 - End....................................1..*$*$*
*

*
*$*$*.....CODE_ADD_2 - Begin..................................2..*$*$*
*
* In this area we will call the methods which will set the
* different properties to the ALV
*
CALL METHOD me->set_default_pf
CHANGING
co_hs_alv = o_hs_alv.
*$*$*.....CODE_ADD_2 - End....................................2..*$*$*
*
*

*$*$*.....CODE_ADD_3 - Begin..................................3..*$*$*
*
* In this area we will implement the methods which are defined in
* the class definition
*
METHOD set_default_pf.
DATA: lo_functions TYPE REF TO cl_salv_functions_list.
lo_functions = co_hs_alv->get_functions( ).
lo_functions->set_all( abap_true ).
ENDMETHOD. "set_default_pf
*$*$*.....CODE_ADD_3 - End....................................3..*$*$*


This code add-on will generate the default pf status like this:

SALV Table 9 - Apply Colors

Posted by Krishh Webworld | 11:31 AM | , , | 2 comments »

In the series of the SALV Model Table display, today we will see how to apply colors to the ALV Grid. In this regards, we will see how to apply colors to the Specific Cell, Specific Row or Specific Column. You can find all the Previous discussion at Tutorials > SALV Table Display.

Color plays a very important role in the formatting. It will help us to generate the a rich list which can help users to notice the exceptional data - for example, negative salary to employee or Low material availabilty.

At most colors can be applied to three levels:

  1. Perticular Cell: To apply color at perticular cell, we need to add the details about the field and color in COLOR table at each record. Than we have to set this Color Table in the object of the COLUMNS which contains the information about all our information (CL_SALV_COLUMNS_TABLE).
  2. Entire Row: To apply color to Entire row, we have to do the same thing as the applying the color to Perticular Cell, but we will not specify the FIELDNAME. This way system will understand that it has to apply the color to entire row.
  3. Entire Column: To apply color to Entire column, we have to get the specific Column from the COLUMNS object and than we need to set the Color Property of the Specific Column and we are done.


In this example I need to change the output table sturcture as compared to previous discussion in this series, so I will provide the entire code which generate the output which has all three scenario. For test purpose, We will apply: Red color to Sales Doc Type in 3rd Row, Green Color to 5th row, Yellow color to Created on Column.

UML Diagram for this application is like:
Code snippet to generate the ALV with Colors using the SALV model.
Code Snippet to Generate ALV with Colors
  
*&---------------------------------------------------------------------*
*& This code snippet will show how to use the CL_SALV_TABLE to
*& generate the ALV and COLORs for Column, Row and Specific Cell
*&---------------------------------------------------------------------*
REPORT ztest_oo_alv_color.
*
*----------------------------------------------------------------------*

* CLASS lcl_report DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_report DEFINITION.
*
PUBLIC SECTION.
*
* Final output table
TYPES: BEGIN OF ty_vbak,
vbeln TYPE vbak-vbeln,
erdat TYPE erdat,
auart TYPE auart,

kunnr TYPE kunnr,
t_color TYPE lvc_t_scol,
END OF ty_vbak.
TYPES: ty_t_vbak TYPE STANDARD TABLE OF ty_vbak.
*
DATA: t_vbak TYPE STANDARD TABLE OF ty_vbak.
*
* ALV reference
DATA: o_alv TYPE REF TO cl_salv_table.
*
METHODS:
* data selection
get_data,
*
* Generating output
generate_output.
*
*$*$*.....CODE_ADD_1 - Begin..................................1..*$*$*
*
* In this section we will define the private methods which can
* be implemented to set the properties of the ALV and can be
* called in the
*

PRIVATE SECTION.
METHODS:
set_pf_status
CHANGING
co_alv TYPE REF TO cl_salv_table.
*
METHODS:
set_colors
CHANGING
co_alv TYPE REF TO cl_salv_table
ct_vbak TYPE ty_t_vbak.
*
*$*$*.....CODE_ADD_1 - End....................................1..*$*$*
*
ENDCLASS. "lcl_report DEFINITION
*
*
START-OF-SELECTION.
DATA: lo_report TYPE REF TO lcl_report.
*
CREATE OBJECT lo_report.
*
lo_report->get_data( ).
*
lo_report->generate_output( ).
*
*----------------------------------------------------------------------*
* CLASS lcl_report IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_report IMPLEMENTATION.
*
METHOD get_data.
* data selection
SELECT vbeln erdat auart kunnr
INTO CORRESPONDING FIELDS OF TABLE t_vbak
FROM vbak

UP TO 20 ROWS.
*
ENDMETHOD. "get_data
*
*.......................................................................
METHOD generate_output.
* New ALV instance
* We are calling the static Factory method which will give back
* the ALV object reference.

*
* exception class

DATA: lx_msg TYPE REF TO cx_salv_msg.
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = o_alv
CHANGING
t_table = t_vbak ).
CATCH cx_salv_msg INTO lx_msg.
ENDTRY.

*
*$*$*.....CODE_ADD_2 - Begin..................................2..*$*$*
*

* In this area we will call the methods which will set the
* different properties to the ALV
*
* Set default PF status
CALL METHOD set_pf_status
CHANGING
co_alv = o_alv.
*
* Set the colors to ALV display
CALL METHOD set_colors
CHANGING

co_alv = o_alv
ct_vbak = t_vbak.
*$*$*.....CODE_ADD_2 - End....................................2..*$*$*
*
*
* Displaying the ALV
* Here we will call the DISPLAY method to get the output on the screen
o_alv->display( ).
*
ENDMETHOD. "generate_output
*
*$*$*.....CODE_ADD_3 - Begin..................................3..*$*$*

*
* In this area we will implement the methods which are defined in
* the class definition
*
*
METHOD set_pf_status.
*
DATA: lo_functions TYPE REF TO cl_salv_functions_list.
*
lo_functions = co_alv->get_functions( ).
lo_functions->set_default( abap_true ).

*
ENDMETHOD. "set_pf_status
*
METHOD set_colors.
*
*.....Color for COLUMN.....
DATA: lo_cols_tab TYPE REF TO cl_salv_columns_table,
lo_col_tab TYPE REF TO cl_salv_column_table.

DATA: ls_color TYPE lvc_s_colo. " Colors strucutre
*
* get Columns object
lo_cols_tab = co_alv->get_columns( ).
*
INCLUDE .
*
* Get ERDAT column & set the yellow Color fot it
TRY.
lo_col_tab ?= lo_cols_tab->get_column( 'ERDAT' ).
ls_color-col = col_total.

lo_col_tab->set_color( ls_color ).
CATCH cx_salv_not_found.
ENDTRY.
*
*.......Color for Specific Cell & Rows.................

* Applying color on the 3rd Row and Column AUART
* Applying color on the Entire 5th Row
*
DATA: lt_s_color TYPE lvc_t_scol,
ls_s_color TYPE lvc_s_scol,
la_vbak LIKE LINE OF ct_vbak,
l_count TYPE i.

*
LOOP AT ct_vbak INTO la_vbak.
l_count = l_count + 1.
CASE l_count.

* Apply RED color to the AUART Cell of the 3rd Column
WHEN 3.
ls_s_color-fname = 'AUART'.
ls_s_color-color-col = col_negative.
ls_s_color-color-int = 0.
ls_s_color-color-inv = 0.
APPEND ls_s_color TO lt_s_color.

CLEAR ls_s_color.
*
* Apply GREEN color to the entire row # 5
* For entire row, we don't pass the Fieldname

WHEN 5.
ls_s_color-color-col = col_positive.
ls_s_color-color-int = 0.
ls_s_color-color-inv = 0.
APPEND ls_s_color TO lt_s_color.
CLEAR ls_s_color.

ENDCASE.
* Modify that data back to the output table
la_vbak-t_color = lt_s_color.
MODIFY ct_vbak FROM la_vbak.
CLEAR la_vbak.
CLEAR lt_s_color.

ENDLOOP.
*
* We will set this COLOR table field name of the internal table to
* COLUMNS tab reference for the specific colors
TRY.
lo_cols_tab->set_color_column( 'T_COLOR' ).

CATCH cx_salv_data_error. "#EC NO_HANDLER
ENDTRY.
*
ENDMETHOD. "set_colors
*
*
*
*$*$*.....CODE_ADD_3 - End....................................3..*$*$*
ENDCLASS. "lcl_report IMPLEMENTATION


Without Colors it will look like:

With Colors it will look like:

ABAP Objects: Widening Cast (Down Casting)

Posted by Krishh Webworld | 11:21 AM | , , | 0 comments »

When we assign the instance of the Superclass to the Subclass, than it is called the Widening Cast, because we are moving to the "More Specific View" from the "Less specific view". Due to this reason it is also called the "Down Casting".

Everytime it is not possible to move the Superclass reference to the Subclass, because subclass will(or might) have always more functionality compare to the Superclass. So, we need to be more careful when we use the down casting.

We will use the same ANIMAL Superclass and LION subclass as per the blog post - ABAP Objects: Narrowing Cast

When this Widening Cast is used?
Widening cast can be used when we need to access the Specific functionality of the subclass from the Superclass.

In ABAP, it is necessary to catch the exception CX_SY_MOVE_CAST_ERROR while doing the widening cast to avoid the short-dump.

Code Snippet for Widening Cast (Downcasting)
  
*----------------------------------------------------------------------*
* This code shows how to use the Widening cast (downcasting)
*----------------------------------------------------------------------*
START-OF-SELECTION.
DATA: lo_animal TYPE REF TO lcl_animal,
lo_lion TYPE REF TO lcl_lion,
lo_cast_error TYPE REF TO cx_sy_move_cast_error.
*
* First We have to do Narrow casting in order to set the
* Animal reference to LION reference.

DATA: lo_tmp_lion TYPE REF TO lcl_lion.
CREATE OBJECT lo_tmp_lion.
lo_animal = lo_tmp_lion.
*
* Now, we will do the Widening cast to move the reference from the
* Animal to LION (more specific class).
TRY.
lo_lion ?= lo_animal.
CATCH cx_sy_move_cast_error INTO lo_cast_error.
WRITE: / 'Widening cast failed 1'.
ENDTRY.
IF lo_lion IS NOT INITIAL.

CALL METHOD lo_lion->hungry( ).
CALL METHOD lo_lion->fasting( ).
ENDIF.
*
* Now, we will try to do the widening cast without setting up
* the proper object reference in the Super reference.
CLEAR: lo_animal, lo_lion, lo_cast_error.
CREATE OBJECT lo_animal.
TRY.
lo_lion ?= lo_animal.
CATCH cx_sy_move_cast_error INTO lo_cast_error.
WRITE: / 'Widening cast failed 2'.

ENDTRY.
IF lo_lion IS NOT INITIAL.
CALL METHOD lo_lion->hungry( ).
CALL METHOD lo_lion->fasting( ).
ENDIF.



Output of this code snippet is:

ABAP Objects: Narrowing Cast (Upcasting)

Posted by Krishh Webworld | 11:18 AM | , , | 0 comments »

Important principal of the Inheritence is that an instance of the Subclass can be used in all the contexts where the Superclass can be used. This is possible because the Subclass contains all the attributes of the Superclass, because Subclass has been inhertied from the Super.

When we assign the instance of the Subclass back to the instance of the Superclass, than it is called the "Narrow Casting", because we are switching from a "More Specific view of an object" to "less specific view".
For example: we have a class a global class for ANIMAL. Now, we have inherited more specific class as LION from the ANIMAL. Since LION will have all the attributes from the ANIMAL, we can always refer back to ANIMAL with the reference of the LION.

When this Narrow casting is used?
An application which is interested in the details of the LION, but don't want to know about them. An application only needs to work with the ANIMAL class. In order to allow the application to access the attributes of the LION we have to do a narrow cast and assign it back to the ANIMAL, which is visible from an application.
UML diagram from the example:



Code Snippet for Class ANIMAL & LION
  
*&---------------------------------------------------------------------*
*& This code snippet implements the local calss ANIMAL and LION
*&---------------------------------------------------------------------*
REPORT ztest_narrow_casting.
*
*----------------------------------------------------------------------*
* Animal Super Class defintion
*----------------------------------------------------------------------*
CLASS lcl_animal DEFINITION.
PUBLIC SECTION.
METHODS: hungry.
ENDCLASS. "lcl_animal DEFINITION
*
*----------------------------------------------------------------------*
* Lion subclass defintion

*----------------------------------------------------------------------*
CLASS lcl_lion DEFINITION INHERITING FROM lcl_animal.
PUBLIC SECTION.
METHODS: hungry REDEFINITION,
fasting.
ENDCLASS. "lcl_lion DEFINITION
*
*
*----------------------------------------------------------------------*
* Animal Implementation
*----------------------------------------------------------------------*
CLASS lcl_animal IMPLEMENTATION.
METHOD hungry.
WRITE: / 'An animal is hungry'.
ENDMETHOD. "hungry
ENDCLASS. "lcl_animal IMPLEMENTATION
*
*----------------------------------------------------------------------*
* Lion subclass implementation
*----------------------------------------------------------------------*
CLASS lcl_lion IMPLEMENTATION.
METHOD hungry.
WRITE: / 'A Lion (King of Jungle) is hungry.',
'Run as fast as you can..!'.

ENDMETHOD. "hungry
METHOD fasting.
WRITE: / 'Stop running. Lion is on Fasting today.'.
ENDMETHOD.
ENDCLASS. "lcl_lion IMPLEMENTATION


Code Snippet
  
*----------------------------------------------------------------------*
* This code shows how to use the Narrow casting
*----------------------------------------------------------------------*
START-OF-SELECTION.
DATA: lo_animal TYPE REF TO lcl_animal,
lo_lion TYPE REF TO lcl_lion.
*
* ANIMAL object without NARROW casting
WRITE: / 'Animal - without NARROW casting'.
CREATE OBJECT lo_animal.
CALL METHOD lo_animal->hungry( ).
CLEAR lo_animal.
*
* ANIMAL object with NARROW CASTING
SKIP 2.
WRITE: / 'Animal - NARROW casting from LION'.
CREATE OBJECT lo_lion.
lo_animal = lo_lion.

CALL METHOD lo_animal->hungry( ).
*
* call the method FASTING must be a dynamic because FASTING is not
* in the Animal
CALL METHOD lo_animal->('FASTING').


Output from this code snippet:

SALV Table 8 - Add & Handle Hotspot

Posted by Krishh Webworld | 11:17 AM | , , | 0 comments »

In the series of the SALV model table display, today we will see how to add the hotspot and after adding, how to handle that hotspot. You can find all the previous discussion at Tutorials > SALV Table Display.

Hotspot is useful in most of the ALV reports to drill-down from the main list. For example, in the Sales order report, it would be great if we provide a drill-down to VA03 (Sales Order display). By this way users would have better flexibility to look into the respective document information.

To add the Hotspot, we need to get the object reference of the CL_SALV_COLUMNS_TABLE from the ALV object (reference to CL_SALV_TABLE). This object reference contains the properties related to ALL the columns. For implementing HOTSPOT, we need to change the specific column properties (i.e. Sales Order or Customer). For this purpose, we need to have an access of the object reference CL_SALV_COLUMN_TABLE - which will contain the properties of the speicific column. We will set the specific Cell type for the HOTSPOT. Here we will use the Casting concept of the Object Oriented to refer the properties of the CL_SAL_COLUMN_TABLE. Read this for casting: ABAP OBjects - Narrowing Cast & ABAP Objects: Widening Cast

Ater implementing the Hotspot, we need to implement the Event Hanlder to handle the Hotspot. Here, we will implement the event listner method for the event LINK_CLICK of the class CL_SALV_EVENTS_TABLE. We need to set the handler of this events to let the system know, where to go when the event occurs.

Note: Here we have used the class CL_SALV_COLUMNS_TABLE which is different than the class CL_SALV_COLUMNS discussed as in the previous post SALV Model 7 - Changing Column settings.

Here is the code snippet to which provides the ADD-ON code to our Base program. The base program can be found in the SALV Model 1: Normal ALV Table Display.

UML Diagram would be like:

Code Snippet for Hotspot and event handling
  
*$*$*.....CODE_ADD_1 - Begin..................................1..*$*$*
*
* In this section we will define the private methods which ca
n
* be implemented to set the properties of the ALV and can be
* called in the

*
PRIVATE SECTION.
* Set the various column properties
METHODS:
set_hotspot_vbeln
CHANGING
co_alv TYPE REF TO cl_salv_table
co_report TYPE REF TO lcl_report.

*
* Event Handler for HOTSPOT event
METHODS:
on_link_click
FOR EVENT link_click OF cl_salv_events_table
IMPORTING
row
column .
*$*$*.....CODE_ADD_1 - End....................................1..*$*$*
*
*
*$*$*.....CODE_ADD_2 - Begin..................................2..*$*$*
*

* In this area we will call the methods which will set the
* different properties to the ALV

*
* Set Up the Hotspot & Event Handler
CALL METHOD set_hotspot_vbeln
CHANGING
co_alv = o_alv
co_report = lo_report.
*$*$*.....CODE_ADD_2 - End....................................2..*$*$*
*
*
*$*$*.....CODE_ADD_3 - Begin..................................3..*$*$*

*
* In this area we will implement the methods which are defined in
* the class definition
*
METHOD set_hotspot_vbeln.
*
*...HotSpot
DATA: lo_cols_tab TYPE REF TO cl_salv_columns_table,
lo_col_tab TYPE REF TO cl_salv_column_table.
*
* get Columns object
lo_cols_tab = co_alv->get_columns( ).
*
* Get VBELN column
TRY.
lo_col_tab ?= lo_cols_tab->get_column( 'VBELN' ).
CATCH cx_salv_not_found.
ENDTRY.
*
* Set the HotSpot for VBELN Column
TRY.
CALL METHOD lo_col_tab->set_cell_type
EXPORTING

value = if_salv_c_cell_type=>hotspot.
.
CATCH cx_salv_data_error .
ENDTRY.
*
*...Events
DATA: lo_events TYPE REF TO cl_salv_events_table.
*
* all events
lo_events = o_alv->get_event( ).
*
* event handler
SET HANDLER co_report->on_link_click FOR lo_events.
*
ENDMETHOD. "set_hotspot_vbeln
*
* Handles the UI on the VBELN (HotSpot)
METHOD on_link_click.
*
DATA: la_vbak TYPE ty_vbak.
*
* Get the Sales Order number from the table
READ TABLE lo_report->t_vbak INTO la_vbak INDEX row.
IF la_vbak-vbeln IS NOT INITIAL.

MESSAGE i398(00) WITH 'You have selected' la_vbak-vbeln.
ENDIF.
*
ENDMETHOD. "on_link_click
*
*$*$*.....CODE_ADD_3 - End....................................3..*
$*$*



This code will generate output like this:

After event handling of the Hotspot:

Archives

Subscribe Now: Feed Icon