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

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.

Wrapping Reports

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
  SUBMIT riplko10
    WITH SELECTION-TABLE lt_selscreen
    WITH pn_iflo  = abap_true  "Select Func Loc Tasklists
    WITH dy_tcode = 'IA09'
    WITH dy_selm  = 'D'        "Dark mode
    AND RETURN
  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.
  cl_salv_bs_runtime_info=>set(
    EXPORTING display  = abap_false
              metadata = abap_false
              data     = abap_true ).
* Submit Wage Type Reporter
  SUBMIT h99cwtr0
    WITH SELECTION-TABLE lt_selscreen
    AND RETURN.
  TRY.
      cl_salv_bs_runtime_info=>get_data_ref(
        IMPORTING r_data = lr_pay_data ).
      ASSIGN lr_pay_data->* TO <lt_pay_data>.
    CATCH cx_salv_bs_sc_runtime_info.
      MESSAGE `Unable to retrieve ALV data` TYPE 'E'.
  ENDTRY.
  cl_salv_bs_runtime_info=>clear_all( ).

Explanation Time!

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.

Parameters:

  • 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.

Parameters:

  • 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.

Parameters:

  • 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

  1. 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.
  2. 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.
  3. 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!)

78 Comments
Former Member
0 Kudos

Hi expterts,

This is a great tool.

When I tried it, somehow the return table misses some records.

Below are the codes:


FIELD-SYMBOLS: <lt_alv_data>      TYPE ANY TABLE,
                                 <lw_bal>           TYPE ypmpro_s_balance,
                                <lw_ldg>           TYPE ypmtrack_s_rpt1.

  REFRESH: itab_bal, itab_ldg.

* Initialization
  cl_salv_bs_runtime_info=>set( EXPORTING display  = abap_false
                                          metadata = abap_false
                                          data     = abap_true ).

* Get data selection
  SUBMIT (p_rpt) WITH SELECTION-TABLE p_sel AND RETURN.

  TRY.
      cl_salv_bs_runtime_info=>get_data_ref(
         IMPORTING
           r_data      = lr_data ).

      ASSIGN lr_data->*      TO <lt_alv_data>.

    CATCH cx_salv_bs_sc_runtime_info.
      MESSAGE 'Unable to retrieve ALV data'(017) TYPE 'E'.
  ENDTRY.

  cl_salv_bs_runtime_info=>clear_all( ).


Below is the Selection Table content:

1 PA_ALTUM P
2 PA_LV P   /V001
3 PA_NOBAL P
4 S_ABTNR S
5 S_BUKRS S I EQ IT01
6 S_BUPER S I EQ 201301
7 S_KNFIX S
8 S_KNTYP S I EQ 27 00
9 S_KONTO S I EQ 27020
10 S_KONTO S I EQ 27021


The original report has two records display in ALV Grid (account 27020 & 27021).
However, in the calling program, lr_data->* points to the data with only one record.

Does anyone have the idea or it's the method issue ?

Thank you for help.

Tony

Former Member
0 Kudos

Hi glen.simpson,

Thanks for this document. It is good and learning ..

Regards

Bibek

former_member129652
Active Participant
0 Kudos

Hi,

I am excited about this solution.  I will try it with FBL3N and FAGLL03 in my next project.  Thanks a lot for providing this solution.

former_member192713
Discoverer
0 Kudos

Thanks for sharing, It is very useful !

JurijsP
Explorer
0 Kudos

Does it work for Reports that were generated from queries (SQ01)?

I tried and cl_salv_bs_runtime_info=>get_data_ref does not return any data.

Arun_Prabhu_K
Active Contributor
0 Kudos

Very useful one. Thanks for documenting it glen.simpson :smile:

vamsilakshman_pendurti
Active Participant
0 Kudos

Hi Glen ,

Its really very helpful ,

I have small doubt ...

If we want to get the out put of hierarchical data into our program i am getting header information  only.....how to get item data into my internal table .

When i use the R_DATA_LINE  parameter then it will go to dump...

could you please give me the reason ..

Thanks ,

vamsi.

former_member189009
Active Participant
0 Kudos

Hi glen.simpson,

    This is very usefully! Thanks for your share.

    I have one question need your help. When I run an ALV report in background job, it will have a spool. If I want to get this ALV runtime information (the layout, field catalog, key fields, filters, etc. plus the data table)  by spool no, how can I realize this function ?

former_member192763
Participant
0 Kudos

Hi Glen Simpson

I tried to play with your solution, using a SAP Query (SQ01) as a source.

The problem is that the ALV list includes a field %ALVCOUNT, that is impossible to exclude, which causes an exception CX_SY_STRUCT_COMP_NAME in the method CREATE_DATA_FOR_COMPONENT of the class CL_SALV_BS_DDIC, that checks for valid field names, and doesn't allow for '%' character.

The exception is raised using cl_salv_bs_runtime_info=>get_data_ref.

:???:

Former Member
0 Kudos

Hi Glen,

Thanks for the good blog.It works like a charm. I have made changes in my old report and i am very happy with the performance.

Any chance of getting header data of the ALV ?

Regards

SSK

swati_singh4
Participant
0 Kudos

well this help me to great extent. However, the alv output of my submit program has subtotals and totals. Also the submit program has multiple all layouts

. would this work in such dynamic scenario. I need to send the output of RPCPRRU0 in pdf

kabil_g
Active Participant
0 Kudos

Hi Glen,

Very Nice BLOG .

Former Member
0 Kudos

i Tried with call transaction its working fine for me too ...

thanks a lot for this kind of code

Former Member
0 Kudos

Hi Glen,

I have tried your solution for calling a standard report :- Tcode VL10c.To get the data in the Custom Report  I need to run standard tcode VL10c at least once in respective system .Then only I got data in the custom report.Please help to resolve the issue.

Former Member
0 Kudos

Dear Glen,

I am still getting a blank field, I tried class CL_SALV_BS_RUNTIME_INFO to fetch the data in the internal table from the standard report  rfitemgl for t-code FBL3N but it is not returning me the data from the field EBELN.

Previously i tried fetching data from LIST_TO_ASCII function module, but there also same problem is coming, it is not returning the data of field EBELN from the report rfitemgl for t-code FBL3N.

Please help me.

Regards,

Prameet Gopal Verma

Former Member
0 Kudos

Hi glen.simpson,

Thanks for sharing your knowledge. It is very useful to my requirement. I will let you know once I get update from my customer side.

Thanks & Regards,

John K.

former_member195791
Participant
0 Kudos

I am having some issues with this class. When I call this within SAP ,  works well, but when I convert the same FM to a RFC and call it from external source, nothing is returned the field symbol.

Any ways to fix this issue?

thanks

Update: Problem solved.

if you using this class for a submit <program>  , make sure the events such as

AT USER-COMMAND are  being triggered. When I call from my RFC from  HTTP, this user command doesn't get triggered for some reason.

justin_santhanam
Active Contributor
0 Kudos
Hello Glen and everyone,

I'm using this method to get data from IH08. It's working great, but I also need Classifications to be exported, since it's not available in ALV ( I mean you have to manually choose Show/hide classifications), I  guess I don't see it in the exported table from memory. Not sure how to achieve this so that I can get the classifications as well.
ziolkowskib
Active Contributor
0 Kudos
Hi Former Member

Very interesting solution. I gave it a try with transaction FAGLL03H (report FAGL_LINE_ITEM_BROWSER) but unfortunately is seems the data retrieved using method GET_DATA_REF in case of that particular report is layout dependent which is a bit unwanted. That report allows user to specify layout on selection screen so mentioned solution could be stll used with own-defined layout but I expected it to be layout independent.

Nevertheless very thank you for very useful and well written blog.

Regards,

Bartosz

 
sarath_chip
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hi Glen,

Really helpful blog, I am just trying if we can achieve this.

Your blog given a solution.

 

Regards,

Sarath
Former Member
0 Kudos
Hi Glen,

this solution works for 'old' tcodes. What about tcodes with 'N'? e.g. ME21n, CN43N? how to correctly export to memory list ?

 

Regards,

Mariusz

 
0 Kudos
Thanks for share!

Best Regards
former_member356171
Participant
0 Kudos
Hi Glen,

Thank you very much for the blog!!

 

I was actually trying get the ALV runtime data from standard report and able to finish it with your help.

 

Thanks,

Divi

 
SBLSVRamana
Explorer
0 Kudos
Hi,

I have used the same code to get ALV output from one standard report into my Z Report and later i'm trying to display ALV output in my Z Report then system is not display anything.

Could you please guide me how get ALV output from report and do some calculations and display ALV in another report.

 

Regards,

Ramana.

 
antioann1924
Discoverer
0 Kudos
Hi Glen,

This is an awesome post!

Thank you very much for sharing!

 

Regards,

Antonis
CharlesRichir
Explorer
0 Kudos

Exactly what I needed. Thank you!

e4rthdog
Explorer
0 Kudos
Thanks a lot. It helped.
Labels in this area