SAP 提供 SE11 / SE16 / SE16N 查看表数据,SE11 首先进入的是表结构界面,然后再跳转到选择屏幕,在界面中输入选择条件运行,或直接运行,才能看到表数据。如果表设置了表维护生成器 (Table maintenance generator),可以使用事务码 SM30 查看和维护表数据。以上这些方法,有一个共同的问题:SAP的数据展示界面和维护,基于 SAP List Viewer 或者 ALV Control ,具备基本的数据操作功能,比如排序、筛选、数字型字段求和等,但复杂的加工处理不得不借助于 Excel 。而且,利用 SAP 标准功能导出到导出到 Excel,数据并不能直接使用,格式也还需要继续加工,重复执行这些操作是不是很浪费时间?
如果朋友们希望充分利用 Excel 的强大功能,并且在 Excel 中查看 SAP 的表数据,不妨参考本博客即将介绍的三种方法。三种方法实现的难度不同,有着各自不能的使用场景。掌握这些方法,可以做出很多意想不到的解决方案。
利用 RFC 在 Excel 中查看 SAP 表数据
第一种方法,在 Excel 中通过 VBA 并利用 SAP ActiveX 控件,从 SAP 系统获取数据。我们知道 SAP 有一个通用的读取数据表数据和结构的函数 RFC_READ_TABLE
,但该函数有较多限制,比如:
- 获取列的字段所有字符不能超过 512 个字符
- FLOAT 类型数据可能引发
ASSIGN_BASE_WRONG_ALIGNMENT
异常
(参考: Working around limitations of TableReader / RFC_READ_TABLE Symptoms)
所以,如果想从外部获取 SAP 数据,并不建议直接使用这个函数。如果要获取的表示固定的,可以自定义一个函数,比如要获取 SKA1 表的数据,自定义一个函数 Z_SKA1_READ:
为了能在外部访问,需要勾上Remote-Enabled Module 选项。另外函数提供 Importing 参数,允许对 COA (KTOPL) 字段进行筛选,如下图:
Tables 参数用于导出表的数据,将其名称定义为 content:
FM 的代码如下:
这样,我们就可以在 Excel 中通过 VBA 获取 SKA1 表的数据。VBA 使用 RFC的方法和细节,我之前写过系列博客,有需要请参考:
本篇只给出 VBA 调用 Z_SKA1_READ 函数的完整代码:
不知道是不是因为 GUI 升级到 750 原因,
itab.data
属性返回值为空,所以在将数据写入到 Excel worksheet 的时候,只能用循环的方式读取。本文对代码不再重复说明。
刚才的函数读取指定表的数据,如果需要读取的每一个数据表都需要定义一个函数,灵活性也不够,对吧。在 SQL 使用动态条件不难,但 FM 返回值貌似不能动态,我查看和思考了 RFC_READ_TABLE
函数,其返回值是放在一个行为 CHAR512 的表中,分隔符由调用函数来指定,估计也是由于这个原因。所以这种方法不方便实现任意表的数据导出,我将在另外两种方法中说明如何导出任意表的数据。
ABAP Restful API
通过 Restful API 暴露数据,好处符合最新 IT 技术趋势,使用 Http 协议,各种语言都可以处理,无其它依赖条件。如果使用 Excel 2013 之后的版本,Power Queryt 提供对网站数据的解析,处理 json 数据轻而易举,不用编写代码。
SAP 提供 Restful API 的方法请参考我之前写的文章:
- SAP 如何提供 RESTful Web 服务?
- SAP 如何提供 RESTful Web 服务(2) - ABAP 与 JSON
- SAP 如何提供 RESTful Web 服务(3) - Rest 路径处理
在 ABAP 中实现 ABAP Restful API 的过程简要说明如下:
1、通过事务码 SE24 创建一个类,将类命名为 ZCL_READ_TABLE,实现 IF_HTTP_EXTENSION
接口,实现接口的 HANDLE_REQUEST
方法,假设我们只需要读取 SKA1 表的数据,可编写如下代码:
2、通过事务码 SICF 定义服务,在默认的 sap 节点下新建 ztables 节点:
双击 ztables 节点,如果不需要客户端输入账号和密码,在 logon 页签中设置默认的用户名称和密码。关键是和刚才的 class 关联,切换到 Handler list 页签,设置处理器为 ZCL_READ_TABLE:
回到上一界面,选中 ztables,右键,激活 ztables 节点对应的服务。在 SICF 界面检查 SAP 服务器是否开启,端口多少(菜单:Go to -> ICM Monitor)。如果一切 OK,在客户端就可以访问 SAP Restful Service。比如网址可能为:http://sapecc6:8000/sap/ztables/ska1 。
我们当然不满足只能查看一个表的数据,接下来,我们改写代码,运行客户端按下面的 url 格式发送请求:
http://sapecc6:8000/sap/ztables?tablename=t030
根据 query string - tablename 来指定要查询的表名,从而实现任意表数据的查询。进入 zcl_read_table 类将代码改写如下:
接下来,演示如何在 Excel 中消费 SAP Restful Service,不展开操作细节。Power Query 我之前也写过系列博客,请自行参考。这种方法的好处是在 Excel 中不用编写代码,并且数据处理的灵活性比较高。
在 Excel 界面中,切换到【数据】页签,通过【获取数据】 选项,选择自其他源,自网站,在弹出对话框中,输入 http://sapecc6:8000/sap/ztables?tablename=SKA1。
点击确定按钮,进入 Power Query 编辑器界面,选中列表,右键,选择菜单项:到表。
点击右上角展开按钮,对数据进行展开:
然后将数据加载到 Excel 工作表,就可以在 Excel 工作表中查看 ska1 表的数据,支持刷新。
XXL_SIMPLE_API 函数
XXL_SIMPLE_API 实现将 internal table 的数据导出到 Excel,相对而言,比 OLE 和 DOI 技术更加简单。但每次导出时,弹出对话框,略显不便。
为了使用这个函数,需要先定义 3 个内表,最重要的是根据 gxxlt_v 结构创建内表,代表要在 Excel 显示的数据的表头 (heading)。这个结构和导出数据的 internal table 的字段数必须相同。
假设我们需要导出 SAP 的示例数据表 spfli 的内容,根据该表的字段定义一个内表:
定义一个填充 gt_gxxlt_v 内表的子例程:
然后调用 XXL_SIMPLE_API 函数,将内表的数据导出到 Excel:
完整代码如下:
讲解了导出一个 table 的方式后,接下来我们看看如何实现允许用户根据指定表名导出任意表的数据。为了实现复用,我们用函数来实现,函数名为 Z_TABLE_TO_EXCEL。
以下是参数的界面:
-
I_TABLENAME
: 表名 -
I_OPTIONS
: 用 Open SQL 方式对数据进行筛选 -
I_SORT
: 用 Open SQL 方式对字段进行排序
定义如下 Exceptions:
以下是 FM 的完整代码:
函数的用法比较简单,利用 SE37 测试如下:
源代码
源码放在 github - SAP Table Export to Excel