ABAP SALV model has some cool features. Getting the data table from the model, is one of them. Let’s explore the solution.
Problems analyzing LIST returned by LIST_FROM_MEMORY
SUBMIT is a great feature of ABAP. You can generate the report output, send LIST to the memory using SUBMIT .. EXPORTING LIST TO MEMORY. You can get this list from the memory using the FM LIST_FROM_MEMORY and use that to write the list using WRITE_LIST .
Everything is good so far, but when you need to read the values from the list, things get messy. You would need to parse the data, remove the lines, formatting etc. This would be painful and not much fun.
Workaround
You can overcome this issues by a workaround:
- Export the list to the unique Memory ID from the submitted Program
- Import the list from the memory ID in the caller program
To be able to implement this workaround, you would need to modify the Submitted program in order to pass the data to the memory ID. Once you do that, caller program would be able to get it back after control is back in the main program.
Use SALV Model class CL_SALV_BS_RUNTIME_INFO
To overcome this limitation of the workaround, SALV model would be helpful. If the output of the submitted report is generated by the SALV Fullscreen model, the data can be easily retrieved back using the SALV model class CL_SALV_BS_RUNTIME_INFO. This class CL_SALV_BS_RUNTIME_INFO has few methods which can be really useful in this situation.
Let the model know, that you don’t want to generate the output, but interested in the data.
Instruct Model to get the data
cl_salv_bs_runtime_info=>set( EXPORTING display = SPACE metadata = SPACE data = ‘X’ ).
Once the report is submitted, get the data from the runtime information
Retrieve Data
DATA lo_data TYPE REF TO data. TRY. " get data from the SALV model cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = lo_data ). CATCH cx_salv_bs_sc_runtime_info. Message 'Unable to get data from SALV' type 'I'. ENDTRY.
Example
To show it in action, I’m submitting the report SALV_DEMO_TABLE_SIMPLE.
Demo Program
DATA: lt_outtab TYPE STANDARD TABLE OF alv_t_t2. FIELD-SYMBOLS: <lt_outtab> like lt_outtab. DATA lo_data TYPE REF TO data. " Let know the model cl_salv_bs_runtime_info=>set( EXPORTING display = abap_false metadata = abap_false data = abap_true ). SUBMIT salv_demo_table_simple AND RETURN. TRY. " get data from SALV model cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = lo_data ). ASSIGN lo_data->* to <lt_outtab>. BREAK-POINT. CATCH cx_salv_bs_sc_runtime_info. ENDTRY.
Note that,
- Not sending the list to memory
- No need to modify the submitted program to export the data to memory
- No need to Import the data
These method does the same export and import but they are hidden from the caller.
Debugger shows that the data has been successfully retrieved from the model.
One more reason to use SALV Model 🙂
Thank you for this great hint! Hope SAP standard developers use SALV model more frequently.
Thanks a lot!
How cl_salv_bs_runtime_info=>get_data_ref work if submited program have two or more salv table? Or have some subscreen with salv table?
Getting error : The field “” is unknown, but there is a field with the
similar name “LT_OUTTAB”. “LT_OUTTAB”.
Great tip my friend. Thank you for it.
Just one thing, as we need to modify the submitted program, if we have submitted a standard program then we need to do the “old way”, parsing data and so on (if the client doesn’t want to change the standard program)
@ Satyavrit Gaur
Add this line-
FIELD-SYMBOLS LIKE lt_outtab.
@ Naimesh – really cool! Once again I’ve learn a really neat and useful trick!
Thanks All.
@Clemens – Lets see and wait how may of standard SAP programs uses the SALV
@Calm – I guess, this would only be feasible for the fullscreen ALV. So, if you have more than one list, they would need to be in the Grid. I would have to try and see how that works out.
@Satyavrit – Fixed the Program
@Ricardo – Yes agree that if the Std SAP program is not using SALV, it may not be possible to get back the data.
@Steve – 🙂
This works also with standard cl_alv_gui_grid, so will also work with FM reuse_alv_grid_display.
Great post, Naimesh.
I would like to use this code to capture the output from transaction ME2L (Purchasing Documents per Vendor), which is program RM06EL00.
I have already changed the “SUBMIT…AND RETURN” statement to submit RM06EL00 with the appropriate selection parameters and I can see in debug that the correct records are getting to lo_data. However, I am not sure what to change the “lt_outtab TYPE STANDARD TABLE OF” to instead of alv_t_t2 to match the data coming out of RM06EL00. How would I find the correct table to use? I have dug around in the code for RM06EL00, but cannot find a table or structure that is being used to store the data.
@Lukasz – Yes, you are right. It works with CL_ALV_GUI_GRID as well.
@Jack – I think the best way to know which table is being sent to the SALV, is by setting up the break-point in the FACTORY method of CL_SALV_TABLE.
You can also put the breakpoint in the method SET_DATA of the class CL_SALV_BS_RUNTIME_INFO. Once it stops there, you can check the call stack to find out which specific ALV FM / method was called. Once you know the table name, search it in the submitted program to know the structure.
Regards,
Naimesh Patel
Naimesh,
I had no luck when setting a break point in the FACTORY method, so I tried your second suggestion. I have never worked with the call stack in the debugger, so at first, I kept getting lost. However, I kept digging and finally found the table that is being used by RM06EL00, changed my program, and am not getting the records returned to lt_outtab.
Thanks so much for your help.
Jack
@ Jack Sugrue : We can use Meta Data method to retrieve the structure of the standard program used in the Output of the report.
Something like below :
cl_salv_bs_runtime_info=>set(
EXPORTING display = abap_false
metadata = abap_true
data = abap_true ).
SUBMIT rsvtprot WITH cusobj = ‘V_T001B’
WITH dbeg = udate
* WITH tbeg = utime_fr
WITH dend = udate_to
* WITH tend = utime_to
WITH users = user[]
WITH alv_grid = ‘X’ AND RETURN.
TRY.
cl_salv_bs_runtime_info=>get_data_ref(
IMPORTING r_data_descr = lr_data_descr ).
ASSIGN lr_data->* TO .
cl_salv_bs_runtime_info=>get_data(
IMPORTING
t_data =
).
* TRY.
CALL METHOD cl_salv_bs_runtime_info=>get_metadata
RECEIVING
value = ls_metadata.
CATCH cx_salv_bs_sc_runtime_info.
MESSAGE `Unable to retrieve ALV data` TYPE ‘E’.
ENDTRY.
Thanks, Ritesh. I will give that a try.
Naimesh and Ritesh, I appreciate your help. However, I am stuck. I am trying to use this technique on transaction IW29. The Program is RIQMEL20. I have tried the methods that both of you suggested to try to find the structure, but still cannot make it work.
It looks like the structure is very close to RIHQMEL_LIST, but it has a few fields added (ROW_COUNT and PM_SELECTED). I have tried to create my own structure based on RIHQMEL_LIST, but I keep getting a Runtime Error “Assign Type Conflict” because the field does not have the required type.
Would it be possible for one of you to take a look at the program RIQMEL20 (Tcode IW29) and help me determine which structure to assign the data to?
I appreciate all of your help.
Never mind. I just figured out that I can change the FIELD-SYMBOL to by TYPE ANY TABLE and it works fine.