浅谈 SAP ABAP 系统里的 ALV 输出方式实现

由于国情原因,ABAP ALV 相关的报表开发在国内众多 SAP 技术交流群里永远都是一个热门话题。最近 Jerry 和朋友的技术交流群里,郭爷向大家介绍了 ALV Integrated Data Access,能够轻松实现以 ALV 格式展示 CDS view 的数据。

什么是 ALV?ALV 最初是 ABAP List Viewer 的缩写,但在 SAP 文档中找到的当前术语是 SAP List Viewer。 不过,这并不重要,在日常实践中,它被简称为 ALV,不再使用任何名称。
ABAP 列表查看器 (ALV) 是一组应用程序编程接口(API 功能模块和类),用于以表格或分层格式显示数据,以及用于视觉呈现和事件处理的内置选项。
对于用户,ALV 提供了一个友好的界面和一个工具栏,允许每个用户根据自己的喜好调整呈现的布局,并轻松地对数据进行排序或过滤。 许多标准 SAP 报告使用 ALV,由于其灵活性、易于实施和多种功能,它已成为构建自定义 ABAP 报告时的流行工具。ALV 框架的第一个实现是经典 SAP 列表查看器,通常称为 ALV 列表。
感谢郭爷的介绍,Jerry 因为工作原因不会进行 SAP Dynpro 的编程,所以也不知道这个 ALV IDA 的存在。网上搜了一下,发现早在 2018 年就有 SAP 从业者写过介绍它的博客了:

因为使用确实非常简单,Jerry 不会重复博客里的内容,对其详细用法感兴趣的朋友,请移步这篇 SAP 社区博客: SAP List Viewer with integrated Data Access ALV with IDA.
如下图所示,我在 SAPGUI 里写了一个报表,只用一行语句就能完成一个名叫 ZFAT_INTERFACE 这个 CDS view 的 ALV 展示工作。

这个 CDS view 显示的数据,是当前 ABAP 系统里所有的接口(SE24 里查看的 interface)和接口上定义的方法个数。

CDS view 实现源码如下:

为什么要搞这样一个 CDS view 出来?Jerry 曾经给 SAP 成都研究院的同事们做过一个面向对象程序设计的培训,里面讲到了一个原则:
Interface Segregation Principle(接口分离/隔离原则).

接口隔离准则期望达到的效果是,客户类不应被强迫依赖于那些它们实际并不需要的接口。相反地,一个接口定义的方法数量越多,其实现类越容易受制于该接口。例如,一个客户类 A 实现了一个接口,该接口包含了客户类不需要的方法,但这些方法是其他客户类所需要的,那么当其他客户类由于某种原因需要对接口进行修改时,这个修改也将影响客户类 A。通过接口隔离准则,我们尽可能地避免这种不必要的耦合,比如上图中把包含了 Print,Staple, Copy 和 Fax 四个方法的胖接口 Job,拆分成了四个各自只包含一个独立方法的接口。
讲完了接口隔离原则之后,我忽然有了一个想法,SAP ABAP 系统里大量的历史遗留代码里,是否存在着定义了大量方法的胖接口呢?于是就开发了上述的 CDS view 一探究竟。
从使用 ALV IDA 显示 CDS view ZFAT_INTERFACE 的结果看,方法数量排名第一的胖接口 IFUR_NW7__ALL,其上定义了 755 个方法......

再回到 ALV IDA,它能够显示 CDS view 数据的原理是什么?
使用 Jerry 之前文章:
SAP 错误消息调试之七种武器:让所有的错误消息都能被定位 里介绍的第五种办法,孔雀翎之 SAT,即使用 SAT 运行之前编写的 ALV 程序,在 SAT 跟踪结果里,就能找到 cl_salv_gui_table_ida 最后是如何从 CDS view 里取值的:
CL_SQL_STATEMENT->EXECUTE_QUERY

在该方法里设置断点, 执行报表,断点会触发两次:

断点第一次触发,执行的 SQL 表达式:
断点第二次触发,执行的 SQL 表达式:

一旦指向结果集(result set)的引用 lo_result 在 1049 行代码调用 next_package 方法,CDS view 的前 1000 条数据就被赋值到了 ABAP 内表 lr_data 里:

这种不采用 ABAP OPEN SQL,而用 CL_SQL_STATEMENT,CL_SQL_CONNECTION 等系列工具类的数据库访问方式,称为 ADBC - ABAP Database Connectivity.
ADBC 是一套 API 的集合,能允许 ABAP 开发人员使用 ABAP 面向对象编程的方式,同 ABAP 服务器的原生 SQL 接口进行交互。

Jerry 之前的文章集合 Jerry 的 ABAP, Java 和 JavaScript 乱炖,里面有一篇将 ADBC 和 Java 的 JDBC 做了对比:
ADBC vs JDBC
下图左边是用 ADBC 读取数据库的代码,右边是 Java 的 JDBC 代码,大家可以简单对比一下语法:

最后,在哪些版本的 ABAP 服务器上能使用 ALV IDA?
无需查阅文档,直接查看源代码,在 CL_SALV_GUI_TABLE_IDA 有个 DB_CAPABILITIES 方法:

进而查看该方法实现里的 CL_SALV_IDA_CAPABILITY_SERVICE:

当前 DB 是否支持指定的特性,通过这些 IS 方法返回的布尔值决定。

从源代码看,很多特性需要 ABAP 740 SP4 之后的版本才能支持。

感谢阅读。
版权声明: 本文为 InfoQ 作者【Jerry Wang】的原创文章。
原文链接:【http://xie.infoq.cn/article/0a41d4d757f34983fae6a9ba7】。文章转载请联系作者。
评论