When more analysis on a custom report in ECC system is required, users ask for a bw report that shows exactly the same data with the custom report in ECC. In standard cases, the rational behavior would be to search for business content if there is any corresponding content for the requirement. Most of the time, we can’t find it in business content (That may be the reason why a custom report is written in ECC J). In such cases we have some alternatives to go with. In this blog I am going to discuss three alternatives, compare the advantages and explain the solution to the one which I mostly prefer.
The information I give does not include any detailed ABAP knowledge, but gives an understanding on how we can handle these types of requirements. I am not an ABAP developer, so, in this blog I will only give the sufficient ABAP code to make changes in necessary spots in your report and function modules.
The Alternative Solutions:
1. 1. Creating a function module:
In this approach, we can write a function module that exactly behaves the same way as the program of the custom report. Then we create a datasource using function module. This approach is nothing different than creating a totally new datasource according to a new requirement. You can only use the logic in the program. You can directly upload your infoprovider using this datasource.
2. 2. Using the program of the custom report to fill in a Z table:
With a minor change in the program, we can add some code to fill in a Z table. Then we can create a datasource with extraction from view. We use z table as the source. This is an easier way compared to the previous alternative. You don’t need to write the whole logic once more. Everything is thought once. When a change request in the logic comes from the user, the change is implemented only in the program. As long as the fields of the custom report are not changed, there is no maintenance for change requests (I am assuming full upload to infoprovider). Even if a change in fields arrives, the only thing we need to do would be replicating the datasource and changing the Z table.
3. 3. The final approach I am going to give in detail is changing the report code so that we can call it from another function module. Then we use this function module to create the datasource. This is even better than the second approach. In this approach we don’t need to create a Ztable. So we have some performance related gains. We don’t spend a space in ECC for Ztable. We don’t require the time to write into that table and also read from that table. When the function is called to upload an infoprovider, the code calls the report code to generate the data we require. Now let’s go with the details. I will explain this approach with a sample report where we show a very small information from MARA table.
Detailed Explanation for 3rd Approach:
For the detailed explanation, I got some help from my ABAP developer colleague, Gozde Candan. We have created a very simple program that gets the list of materials according to a material type selected in the selection screen. We also have created a transaction for this program. This is only for illustration. It does not matter how complicated the code is, you can reorganize the code in such a way I describe in this blog. We have written the program with a single select statement, so that it would be easier to show how we change it.
Suppose we have a transaction called ZMATLIST. This transaction gets the list of materials according to a material type selected.
To find the name of the program behind this transaction, we go to the system menu on top of the screen:
When we select status, a screen appears showing SAP data:
In the field “PROGRAM”, we see the name of the program that we make the changes so that the code inside can be called within a function module.
With the transaction code se38 we can view the code for this program:
For this program, we have defined a structure zmaterial:
This structure is created with TCODE: SE11. This part is important, because we will use this same structure for the datasource. If the design of the code does not include (most of the time it does, but in some cases it may not include) a structure like this, then it should be changed so that before it flows to the gui screens, an internal table defined by such a structure should be filled with the data .
Now we go on by editing this program. What we are going to do is adding a flag to the program to understand if it is being imported by a function module. In the function module, we are going to set this flag. So we will import the value of this flag from function module to this program. Reading the value of the flag, we are going to export the to the function module. That is; we are doing one import for the flag value (from function module) and one export for the data (to the function module).
The code in rectangles is added to the code.
DATA:it_mara TYPE zmaterial OCCURS 0 WITH HEADER LINE.
*pflag is the name of the flag we define. You can give any name.
*This part is the simple selection statement according to the parameter (material type) selected in the
*selection screen of the gui. The data is filled in an internal table called it_mara. For complicated z reports,
*this part can be much more longer. The idea here is filling in the internal table it_mara.
parameter:mtart TYPE mara–mtart.
SELECT * FROM mara INTO CORRESPONDING FIELDS OF TABLE it_mara WHERE mtart = mtart.
*What we do with the below IMPORT statement is that, we get the value of pflag importing from the function
Memory id is a unique id, we can give any name. We will use
*module using memory id ‘ZFLAGFROMBWFM’.
*this same id in the function module to export pflag.
IMPORT pflag FROM MEMORY ID ‘ZFLAGFROMBWFM’.
*We add an if statement to make any necessary changes for showing the data.
IF pflag IS INITIAL.
*In this part, since pflag is not set, we understand that the data generated should be shown in gui screen.
*So any gui related code is written in this part.
LOOP AT it_mara.
WRITE:/ it_mara–matnr, it_mara–ersda, it_mara–ernam.
*In this part, pflag is set from the function module as ‘X’. Thus, we export the data from it_mara to the internal
*table defined in the function module with the memory id ‘ZMATERIALLISTTOBWFM’. This unique memory is
*going to be used in the function module to import the material list to i_e_t_data defined in the function module.
EXPORT it_mara TO MEMORY ID ‘ZMATERIALLISTTOBWFM’.
That is all we do in the report code. Now, it is time to create a function module for our datasource. What we need is a function group where LRSAXD01 is included in the top. I will not explain in detail how to create a function module for bw. Though, here are the screenshots of the function module we have created:
And the source code is:
DATA: l_s_select TYPE srsc_s_select.
STATICS: s_s_if TYPE srsc_s_if_simple,
s_counter_datapakid TYPE sytabix,
i_e_t_data TYPE zmaterial OCCURS 0
WITH HEADER LINE.
DATA: ls_rsselect TYPE rsselect.
*We need to define pflag here, too.
*This part is standart for all bw functions, lr_mtart is defined to enable
*the material type for selection. ‘ZBW_MATLIST’ is the name of the datasource
*we will define.
RANGES:lr_mtart FOR zmaterial–matnr.
IF i_initflag = sbiwa_c_flag_on.
s_s_if–t_select = i_t_select.
log_write ‘E’ ‘R3’ ‘009’ i_dsource ‘ ‘.
s_s_if–requnr = i_requnr.
s_s_if–dsource = i_dsource.
s_s_if–maxsize = i_maxsize.
APPEND LINES OF i_t_select TO s_s_if–t_select.
APPEND LINES OF i_t_fields TO s_s_if–t_fields.
s_counter_datapakid = 0.
IF s_counter_datapakid = 0.
LOOP AT s_s_if–t_select INTO ls_rsselect.
MOVE-CORRESPONDING ls_rsselect TO lr_mtart.
*In this part, we do everything necessary to for loading data. As an initial
*step, we need to send the value of our flag to the report code so that it can
*export the data to this function. Remind that we use the same memory id in
*report code to import the value for pflag. With this EXPORT statement, in
*memory to a space called ‘ZFLAGFROMBWFM’, the value of pflag is written as
*‘X’. The IMPORT statement has to be called from the report code with the same
*memory id, to get the value of pflag.
pflag = ‘X’.
EXPORT pflag TO MEMORY ID ‘ZFLAGFROMBWFM’.
*Now, the value of pflag is exported to the program ZMATERIALLIST. When we
*submit, the report code is called. We also need to send the required
*selections in this submit command. If no selection is required for BW data
*upload, then in this part, we can remove the assignment of material type. But
*in this case, we need to add some extra code to the selection statement in
*the report code.
SUBMIT zmateriallist WITH mtart = lr_mtart–low AND RETURN.
*And as the final step, we import it_mara from ZMATERIALLIST program to our
*internal table i_e_t_data with this unique memory id: ‘ZMATERIALLISTTOBWFM’.
IMPORT it_mara = i_e_t_data FROM MEMORY ID ‘ZMATERIALLISTTOBWFM’.
IF i_e_t_data IS INITIAL.
DO i_maxsize TIMES.
s_counter_datapakid = s_counter_datapakid + 1.
READ TABLE i_e_t_data INDEX s_counter_datapakid.
IF sy–subrc NE 0.
APPEND i_e_t_data TO e_t_data.
Finally we create our datasource using extraction by FM. We use ZBW_MATERIAL_LIST function, we created. And as the structure we select ZMATERIAL which we used in both report code and the function module itself.
As a result, this approach uses the same code for both ECC and BW reports, thus, helping prevent the repetitive software development. One more advantage is that, when a change request arrives from the users, it is only done in report code. No extra effort is spent for BW side. In this blog I gave a sample using import and export statements. There may be other methods that uses this idea. I tried to explain the one I know 🙂
I hope, this blog to be helpful for both BW experts whom are not familiar with ABAP and ABAP developers whom are not familiar with BW codes.