笔者公众号和原创的 ABAP 开发教程,都写了很多授人以鱼不如授人以渔的文章。
近日收到一位朋友提问:
查询当前某个函数被多少程序、接口、代理调用了,然后这些程序、接口、代理的是什么,最后生成一个 ALV 表。就是把图里这个功能给单独抠出来做成一个 ALV 查询的功能,现在这些后台表或是怎么取数的方法我完全找不到呀。
这位朋友咨询的其实就是 SAPGUI 里标准的 Where Used List 功能。
比如 SE37 里,输入一个 Function Module,点击工具栏上的 Where Used List 按钮:
就能看到系统里全部 161 处使用了这个 Function Module 的 ABAP 代码位置:
现在需求就是,搞清楚 ABAP Where Used List 功能,到底是从什么地方把这些数据取出来的。
其实 SAP 社区上之前已经有网友问过类似的问题,比如这个帖子:
https://community.sap.com/t5/application-development-discussions/function-module-or-program-to-get-where-used-list/m-p/1382012
有不少热心网友回复,提供了一些信息,比如这些函数:
RS_EU_CROSSREF
RS_INFOSYSTEM_CREATE_REQUEST
RS_CROSSREFERENCE
当然这些函数都有一定的用处,不过我大致看了一下,有的函数其输入输出参数,同 SAPGUI 的界面展现层耦合得比较紧。
比如 RS_INFOSYSTEM_CREATE_REQUEST 的输出参数是 CL_WB_REQUEST,WB 即 WorkBench,这使得我们无法直接在我们自开发的报表里,重用这些函数。
笔者不是古龙笔下的百晓生,ABAP 开发实体的 Where Used List 信息,到底存储在哪些数据库表里,我也不知道。
但我知道用什么办法,能自行找到答案。
办法有很多,单步调试,事务码 ST05,事务码 SAT 理论上都可行。
如果采用单步调试的方法,在 SE37 里选择一个函数,点击 Where Used List 按钮,弹出让用户指定搜索范围的对话框。
本地新建一个 text 文件,输入如下内容:
[Function]
Command=/H
Type=SystemCommand
然后将 text 文件拖拽到弹出对话框中,松开鼠标,就可以激活系统调试模式了。
传统方式在 SAPGUI 命令输入框里输入 /h,回车激活调试模式,在这里行不通。
因为下图这个模态对话框,会遮盖住背后的命令输入框所在的窗口,阻止我们对其进行输入操作。
调试器激活之后,就可以单步调试了。但不建议采取这种办法,因为费时费力,犹如大海捞针。
待调试的所有代码都是 ABAP WorkBench 的框架代码,调用嵌套层数多,很容易就迷失到茫茫的代码海洋中。
笔者推荐使用事务码 SAT,本人曾经多次利用这个工具,完成了各种各样的调研任务。
金庸笔下的张无忌,学会九阳神功后,在明教光明顶密道内,一个多时辰内就能学到乾坤大挪移第七层。在对决少林空性神僧时,看一遍空性施展的龙爪手之后,就能照样施展出来,并以此轻松击败空性的原版龙爪手。
张无忌只是小时候从谢逊口述,背诵了七伤拳拳经的口诀,学会九阳神功之后,七伤拳在他手中也能信手拈来。稍一挥洒,就让在这门武功上深耕了一辈子的崆峒五老心悦诚服。
SAT 就是 ABAP 江湖中的九阳神功。
它有一个强大之处,就在于能够按照用户的指定,清晰罗列出任何一个事务码内,任何操作执行时调用的 ABAP 代码的明细。
用来调研未知领域的 ABAP 代码执行情况,最合适不过了。
在 SAT 事务码里输入 SE37 然后执行,会以跟踪模式,启动 SE37 事务码。
然后我们在 SE37 里随便输入一个函数,比如 RFC_READ_TABLE, 点击 Where Used List,看到输出结果,最后回退到 SAT.
这个工具会自动将所有跟踪到的数据,在 SAPGUI 的 TabStrip 控件里展示出来。
在 Processing Blocks 面板,会以树形结构展示 ABAP 代码执行情况。
我们将 Gross 即执行耗费时间(单位为微秒)比较长的调用栈逐层展开。
这里看到函数 REPOSITORY_INFOSYSTEM_CALL, 标志着已经进入读取 Where Used List 的核心代码了。
接下来是三个一摸一样的 $OBJECT_CROSS_SELECT$ subroutine 调用。显然,这是在 LOOP 循环里,重复调用了三次。
为什么是三次呢?因为我在 Where Used List 弹出对话框里,指定了三种不同的搜索范围,因此 Subroutine 会以不同的输入参数,重复执行三次,每一次负责在不同的类型中查找。
最后在代码里发现了 CROSS 这张数据库表,存储了 Where Used List 数据。
在 SAT 的 DB tables 即 SE37 里执行 Where Used List 访问到的所有数据库表清单里,CROSS 也赫然在列。
这张表怎么使用呢?
假设想查询有哪些 ABAP 代码,使用到了 Function Module RFC_READ_TABLE, 在 SE16 事务码里,Type 指定为 F,Name 指定为函数名称。
即可查询到结果。其中 Include 列里罗列的以 CM002,CM003,CM004 结尾的名称,实际上代表了存储 ABAP Class 一个个方法源代码的 ABAP 报表名称。CM 即 Class Method 的缩写。
每一个 CM 名称,同一个 ABAP 类的方法名称一一对应。二者可以通过 ABAP 标准工具类进行互相转换,在笔者这些文章里有介绍:
如果对 CROSS 数据库表读取出来的数据,如何进行解析感到还有疑问,可以自行查阅通过 SAT 找到的访问该数据库表的标准代码,如下图所示。然后像张无忌模仿少林龙爪手一样,照着标准代码的逻辑进行解析即可。
笔者近期很多公众号文章的内容,都来自国内 SAP 从业者对我发起咨询的解答。
欢迎大家加入我的知识星球,在里面讨论和交流各种 SAP 相关问题。