In this installment of our IT Partners blog, I will be inviting a good friend of mine Henry Stewart to teach us about using a tool he developed to analyze and perform a WHERE-USED on a RFC in a remote SAP System. Typically, you use the delivered WHERE-USED functionality of the Repository Information System (SE84) inside an SAP instance to discover where the subject object is called or referenced.
But what if the objects calling reference is not in the system that has the RFC? You could log on to every SAP system and do a search, or we can learn from Henry and use his tool.
Here is a brief intro to Henry…..
Henry Stewart has been consulting in the SAP technologies for 8+ years, providing his clients with expert experience in many SAP Modules including SRM, Document Builder, Records Management, FI/CO, SD, MM, PP, RE-FX,HR. Henry has extensive knowledge for implementing SRM in the public sector area customizing and developing unique solutions to meet the needs of his clients. During his free time Henry enjoys spending time with his twin boys, learning new trends in technologies, listening to Audiobooks and watching his alma-mater LSU football. Henry also severed in Louisiana Air National Guard. You can reach him at [email protected]
How to find where an SAP/ABAP Function Module is called
What? This is a strange question – SAP has provided wonderful search facility for all its objects – Where Used. Just display function module(FM) in SE37 transaction, place the cursor on the FM name and click on Where Used Button . It works perfectly if our function module is Normal Function Module – i.e. used internally in the same system in which it exists. With Remote-Enabled Function Modules (RFC) the Where Used is of no help – it will not cross the different SAP systems in the enterprise to find where the RFC is used. If you stop and think for a moment, how can it? During design time we do not know yet which system the RFC can be called from. So what can we do?
First a quick note and a thank you!
In this document we will use definitions Function Module and function interchangeably.
I want to thank Henry Stewart for sharing his wonderful work with us, and as you read and digest this post and the next, you will undoubtedly connect with the hard work and testing that Henry experienced while perfecting this tool. I’d also like to thank Gennady Shlyapintokh, another friend and colleague, for helping us put these posts together as only he can with his enigmatic smile and witty style of prose. You might remember Gennady, sporting his James Bond attire, from a previous post Memory Inspector to Analyze Usage in Real Time
Lets begin…
First let’s define what an RFC is – Remote Function Call(RFC) – Wikipedia, the free encyclopedia
Perspective from ECC
These days rarely are we dealing with one SAP system only. Typically ECC is connected with CRM, SRM, BW and other systems via ABAP connections. These connections are available in SM59 transaction. Let’s consider ECC function BBP_PO_INBOUND. The purpose of this function is to create or change Purchase Order (PO) in ECC. This is a remote-enabled function and is called from outside of ECC. Note the radio button enabling it to be Remotely Called below.
If we do Where Used search in ECC as in the picture below, we will find no references in the Where Used List. The function BBP_PO_INBOUND is not called from ECC.
ECC and SRM
In this example we have two systems ECC and SRM connected via ABAP connection. BBP_PO_INBOUND is called from SRM and in many cases it is difficult to find the places in the SRM code where it is called. So what can we do? One of the methods is a time consuming ABAP scan, but this scan takes long time to run and not always convenient during development and especially troubleshooting. A better alternative would be to use the LOCAL where-used functionality in each discrete system. Let’s explore this concept…
Where-Used – SAP Tool
While our problem statement thus far is accurate, SAP did provide the ability to search for FM references even if the FM does not exist in the system. If you place the FM that does not exist in your system in the SE37 screen and click Where-Used button without going into Display (Display is obviously not possible) – you will get the list of RFC references. lets take an example…
The FM BAPI_PO_GETDETAIL exists in ECC but does not exist in SRM. Lets log into SRM and when we place BAPI_PO_GETDETAIL in SE37 and try to display it will have the message Function module does not exist. (see below)
But if we click Where-Used button, the pop-up with Used-In selection will appear and search will be executed. The result is an usual SAP Where Used List of found locations. You can drill down to the code.
The program that Henry developed that we will analyze shortly has similar capability. Here is a comparison between the program and SAP search for External FM references.
RFC Where-Used Comparison
We can see that both methods have something in common and the custom program provides more functionality plus opportunity to learn!
To analyze the ABAP program Z_FIND_WHERE_RFC_IS_CALLED that allows us to find RFC locations we will consider two fictional SAP systems – ECC_DEV01 and SRM_DEV01. The program can be created in either or both systems. We will analyze the program in SRM_DEV01.
The systems are designated as:
SRM_DEV01 – Original System
ECC_DEV01 – External System
Usage of the tables CROSS and TFDIR.
Two SAP tables help us to solve our problem. The most important in our program is the table CROSS – DD (Data Dictionary) description -Index of Modules Used Externally. The DD description can be misleading. The CROSS table holds all the external programs, outside of the current program. This table holds the links between the program connections to other programs, for example a program that uses a global class, FM, perform some_sub in program some_report, and so on. We are just using the table CROSS because it holds the FM names, when FM RS_NEW_PROGRAM_INDEX runs it is parsing the source code to find programs used outside of the current program, which includes RFC.
We will analyze this table for the Function Modules – subject of this article. All the fields of this table are part of the Primary key:
TYPE – Type of Programming object, e.g. – F – Function Module
NAME – Name of the object in the original system
PROG – Blank for objects of the type F
INCLUDE – Includes in the External system where the object is called.
STATE – Status of programming component (active, saved, transp…)
We are interested in three fields – Type, Name, and Include.
The Function module BBP_PO_INBOUND is created in ECC_DEV01. If we try to find this FM in the CROSS table in ECC_DEV01 we would not find it – it is a RFC and its usage is not recorded in the CROSS table in ECC_DEV01. Now if we go to SRM_DEV01 and look up the CROSS table for the entries where NAME = BBP_PO_INBOUND. Two entries are found:
Type Name Include
1 F BBP_PO_INBOUND /SAPPSSRM/B46B_DPO_TRANSFER_CAE
2 F BBP_PO_INBOUND LBBP_BD_DRIVER_46AU04
To summarize – the Name is in ECC_DEV01, the Include is in SRM_DEV01.
How the CROSS table is updated? When we activate the programming object, the Function Module RS_NEW_PROGRAM_INDEX is called in the Update Task. This FM updates the CROSS table. Although the description of the table CROSS says “Index of Modules Used Externally”, it contains not only external but also all the modules of the Original system. In this article we are not covering the entire usage of the table CROSS only the aspects related to the finding RFC usage in the external system.
The other table of interest is TFDIR – Function Module. Many of the function modules have been created in both systems. The CROSS table will record these function modules without indication whether they are in the Original or the External system. If we would like to exclude the FM with the same name we can check whether FM is in the TFDIR table of the Original system.
We are interested in two fields in TFDIR:
FUNCNAME – Primary Key – Function Module Name
FMODE – Type of function module (local, remote, …)
For the Remote Function Modules the FMODE = “R”. There is a large number of the Remote functions Modules in any of SAP system. For example ECC system has about 37,000 Remote FM and SRM more than 17,000. About 15,500 FM (the same name, but the actual code could be different) are found in both systems.
Use of FUNCTION_IMPORT_INTERFACE and RS_TOOL_ACCESS
After the list of potential locations is selected we still need to ensure that the FM is available in the External system. This is achieved by calling RFC FM FUNCTION_IMPORT_INTERFACE. Destination system is used from the program Selection Screen. If call is successful the RFC is marked as valid. Alternatively the FM RFC_FUNCTION_SEARCH can be used. Basically the FM FUNCTION_IMPORT_INTERFACE only needed to check whether the FM exists in the External system and is an RFC. This can also be checked in the TFDIR table of the External system.
We build the list of locations in the Includes where our target RFC is referenced. To facilitate analysis we can bring user immediately to the found location. To do this two techniques are used – method on_double_click that is called when a user double click on the line with found location and the FM RS_TOOL_ACCESS. When we pass to this function name of the include program and the line where we would like to be positioned it will open the source code at the desired position.
Import parameters of the FM RS_TOOL_ACCESS:
After RS_TOOL_ACCESS is Executed:
Selection Screen
The Selection screen of the program is simple:
We have to specify System of RFC (External System) as it is found in transaction SM59. We can do search for any number of functions that can be placed in RFC Function name. There is a limit of SAP SQL statement size. The program can be designed in such a way that we execute SQL select several times depending on how many RFC’s are searched.
There is also a useful suggestion to run several SAP standard programs to refresh the navigation index and Where-Used list. Goes without saying that even if the program is transported to Production system this should be done with care. But why anyone needs to transport this program to the Production system? This is a tool for developer and the program can be used effectively in the development system.
As we mentioned above there is a large number of RFC with the same name in both systems. We can Exclude FM with the same name found in the Original system. We can also limit our resulting display to only found RFC.
Finding RFC Call Sources
Several internal tables are used to hold found RFC and their location in the code. The result will be collected in the table gt_display. If we were looking in SRM_DEV01 for the locations of three functions:
BBP_PD_PO_PARALLEL_CHECK – SRM FM
BAPI_PO_GETDETAIL – ECC FM
BBP_PO_INBOUND – ECC FM
The result in gt_display will be as in the table below.
This table will be passed to the SAP class for display as an ALV table.
cl_salv_table=>factory( EXPORTING list_display = abap_false IMPORTING r_salv_table = go_salv_table CHANGING t_table = gt_display ).
Other internal tables are:
gt_cross – result of the select from the table CROSS.
gt_rfc – table that holds RFC FM and a Boolean indicator – whether this FM is an RFC in the External system.
(Only RFC that are found in the External system will be analyzed to find code location).
If we ran our example above with three FM we will see in the gt_rfc following entries:
And in the table gt_cross:
All we need now to combine information collected in gt_cross and gt_rfc, find location (line number) in the source code (Include) and collect all we have in the gt_display.
Pattern Search in Sources
One of the interesting features of this program is how the location in the source (line number) is found. This is done in the form find_where_in_source. We call this form for each valid entry in the table gt_cross which will supply the gt_display table with include names and the line numbers where our RFC is found. Obviously any include can have more than one location where RFC is called. All these locations will be found.
This is pretty slick, so read slowly… Here is the plan.
We will read entire include into an internal table. Then we will scan the source code and break it into Tokens and Statements. What are Tokens and Statements? According to SAP help the SCAN ABAP-SOURCE command – “…Breaks down the ABAP source code in the source code table itab1 into tokens according to the rules of the ABAP scanner. The tokens are written – one per line – to the token table itab2…”. “ …In addition to classifying the source code by token, the scanner organizes the tokens themselves into statements – using the colon-comma logic to form chain records – and the statement table itab3 contains a statement description on each line…”.
After that we will build source code lines and check each source line for the FM name pattern in our example “*BBP_PO_INBOUND*”. In general case the pattern to check source code lines is “*FM Name*”. If the source code line contains FM name pattern we will look if it also contains a Destination pattern – “*DESTINATION*”. This will allow us to use only locations in the source code where the FM is called externally.
If the source code does not have any RFC calls (code line has pattern “*DESTINATION*”) we will disregard this include entirely. If the include has RFC calls we loop through the source lines where the FM name pattern is found, check whether this location is an RFC and populate the table gt_display with found FM name, Include name and the location in the source which corresponds to the loop index – sy-tabix.
SAP statements that support this plan are:
READ REPORT is_cross-include INTO lt_source. SCAN ABAP-SOURCE lt_source_temp TOKENS INTO lt_token STATEMENTS INTO lt_statement WITH ANALYSIS.
These are the main ideas. The rest of the code is in form find_where_in_source are statements that build patterns, loop through the tables of tokens, statements, and source to build the table for ALV display.
Two SAP classes are very useful to look for ideas – CL_ABAP_COMPILER and CL_WB_CROSSREFERENCE.
This concludes Part 1 of this blog series. For the programmer familiar with the SAP ALV programming this should be enough to build this very useful and interesting tool – Find Where RFC is Called. In the next month edition we will publish ALV aspects of the program, the program design and the actual program code.