ABAP Developers: Have you ever encountered the situation in which the output of a standard SAPGUI ALV report could help meet a certain requirement but the report program is not written in a way that makes its data extraction and data processing code easily reusable? Frustrating, isn’t it?!
If a report is built using correct layers of abstraction, there is an opportunity to reuse the data processing logic in a totally different user interface technology or output medium (such as a batch interface?). Unfortunately though, most standard SAP reports were born before the Separation of Concerns (SoC) and Model-View-Controller (MVC) concepts became popular in the SAP world and, with the prolific use of things like logical databases in standard report programs, you’ll find that there are very few standard Models (refer to the MVC concept) that can be reused easily. Yes, there are plenty of lower-level BAPIs and function modules that can be called however reports often add so much logic on top of these that fully replicating it would require great swathes of copied code.
If you do find a report that contains logic you want to use there might be another way to reuse it without resorting to cloning whole programs or copying-and-pasting code… you can try “wrapping” the report program in your own custom program and treat the original report somewhat like a simple subroutine.
In some cases, standard report programs specifically cater for this scenario and allow custom wrapper programs to gain access to their data. These report programs will, after extraction and processing, put their data into a globally accessible area of memory and allow the wrapper to import it after submitting the report. Often this is done using the EXPORT TO MEMORY/IMPORT FROM MEMORY technique. Transaction IA09/program RIPLKO10, which is used for reporting and managing Tasklists, is an example of this:
* Execute transaction IA09 to get all Functional Location Tasklists
WITH SELECTION-TABLE lt_selscreen
WITH pn_iflo = abap_true "Select Func Loc Tasklists
WITH dy_tcode = 'IA09'
WITH dy_selm = 'D' "Dark mode
IMPORT sel_tab FROM MEMORY ID 'RIPLKO10'.
This can be a very useful way of reusing report logic and I have even seen instances of Developers creating modifications or enhancements to add this functionality to standard reports where it doesn’t already exist. While it is a practical solution in some situations, a downfall is that it relies on the original Developer of the report programs to enable the export to memory or it means you, the custom Developer, need to enhance each and every report you want to reuse.
Quite recently, though, I discovered something that provides access to the data of any SAPGUI ALV report without modification or enhancement.
Introducing Class CL_SALV_BS_RUNTIME_INFO
When an ALV report is executed, the ALV runtime information (the layout, field catalog, key fields, filters, etc. plus the data table) is stored away by methods of class CL_SALV_BS_RUNTIME_INFO for later use. (Incidentally, the class uses the same EXPORT TO MEMORY mechanism to store the runtime info however the class handles all this internally and provides API methods to access the information, meaning we don’t have to care how it is actually stored.) Now, with a submit statement and a few simple method calls, we can gain direct access to the data table of a report without making any changes to it.
FIELD-SYMBOLS <lt_pay_data> TYPE ANY TABLE.
DATA lr_pay_data TYPE REF TO data.
EXPORTING display = abap_false
metadata = abap_false
data = abap_true ).
* Submit Wage Type Reporter
WITH SELECTION-TABLE lt_selscreen
IMPORTING r_data = lr_pay_data ).
ASSIGN lr_pay_data->* TO <lt_pay_data>.
MESSAGE `Unable to retrieve ALV data` TYPE 'E'.
Whilst there are nearly twenty methods in CL_SALV_BS_RUNTIME_INFO there are only three or four of interest in the retrieval of data from an ALV report:
SET( ) – this method initialises the class (clears its memory areas) and then allows the setting of flags to tell any subsequent ALV objects how to behave. It should be called in your wrapper program before submitting the wrapped ALV report program.
- DISPLAY – set this to abap_false to force all subsequent ALV reports to run in “dark mode”, that is, the ALV will not be output to the GUI.
- METADATA – set this to abap_false to prevent the metadata (layout, field catalog, etc) being exported to memory… we don’t need it in this scenario.
- DATA – set this to abap_true to force the data table to be exported to memory
You would normally only need one of the next two methods. Call it after the wrapped ALV report program has been submitted.
GET_DATA_REF( ) – by far the most flexible of the two GET_DATA* methods, this method can be used to access a reference to the data table variable. It is useful when the structure of the data table is not known, not of importance in the wrapper program or is dynamic so a variable cannot be statically typed in the wrapper program.
- R_DATA – exporting parameter for the reference to the data table variable.
- R_DATA_LINE – if the ALV report executed is a hierarchical list report this exporting parameter will hold the reference to the item data table variable.
GET_DATA( ) – this method can be used to access the data table when the structure is known by the wrapper program. Note: If the wrapper program doesn’t know the structure of the data table because it is dynamic or it just doesn’t need to know the structure then use method GET_DATA_REF( ) instead.
- T_DATA – exporting parameter for the data table.
- T_DATA_LINE – if the ALV report executed is a hierarchical list report this exporting parameter will hold the item data table.
CLEAR_ALL( ) – this method clears all memory areas thus resetting any of the flags that may have been set in the SET( ) method. Calling this method is especially important if you have set the DISPLAY flag to false but you want to display your own SAPGUI ALV report after submitting the wrapped one – if the DISPLAY flag is not reset to its initial value of true before executing your own ALV, then your ALV will not be displayed either.
Things to Note
- The technique described above can be used to access the data of any report program that uses SAPGUI ALV, regardless of the type of ALV. It will work for ALV Grid, ALV List and even Hierarchical ALV List reports but it will obviously not work for reports that output to the GUI using WRITE statements, dynpro table controls or anything other than SAPGUI ALV.
- I don’t think there are many (if any) situations where this technique would be more efficient than a well coded method or function module to extract and process data – the benefits really lie in the reduction of development effort and reuse of existing development objects. So if you require a high performing solution then this technique might not be the one for you.
- The class is simple but powerful which could lead to overuse or use in inappropriate situations. I encourage all developers to use it where it is needed (don’t go looking for a problem for this solution!) and to discuss this technique with colleagues and development managers before implementing.
Wrap Up (pun intended!)
That’s all there is to it, really. It’s so simple that I was sure that it must have been documented or discussed on SDN somewhere but I was very surprised that nothing turned up in a search. This blog should fix that...
I hope that others can share their innovative uses of this simple technique as I want to do in my next blog… “A framework to create quick POWL front-ends to SAPGUI ALV reports” (when I find some time to write it!)