授人以鱼不如授人以渔:手撕 ABAP Where Used List 的标准功能实现

文摘   2024-08-22 18:18   北京  

笔者公众号和原创的 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 相关问题。

码农干货铺
永远要保持一种无论何时何地都逼着自己更努力更优秀来享受更好生活的学习状态
 最新文章