1. 概述
4.2.13.4 之前版本,选表读取 SAP ERP 数据 时,采用的是内置 RFC_READ_TABLE 函数,对于特殊字段(如 RAW、QUAN 等)可能会读取异常。
4.2.13.4 及之后版本,支持配置自建函数 FDL_EXTRACT_TABLE_DATA,配置后,定时任务中优先使用自建 FDL_EXTRACT_TABLE_DATA 函数获取SAP表数据。
需要在 ECC6 以上的版本,并在 SAP 系统中添加一个帆软提供的 ABAP Function。
2. 添加 ABAP Function
帆软的 ABAP Function 的名称为「FDL_EXTRACT_TABLE_DATA」,不可改变,将其添加到 SAP 系统中,函数内容如下:
FUNCTION FDL_EXTRACT_TABLE_DATA.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" TABLES
*" FIELDS STRUCTURE ZSQL_CLAUSE_ELEMENTS
*" FROMCLAUSE STRUCTURE ZSQL_CLAUSE_ELEMENTS
*" WHERECLAUSE STRUCTURE ZSQL_CLAUSE_ELEMENTS
*" DATA STRUCTURE ZTABLEROWS
*"----------------------------------------------------------------------
*"----------------------------------------------------------------------
*" Copy selected fields from QUERY_TABLE to DATA_STRUCTURE
*"----------------------------------------------------------------------
TYPE-POOLS: abap.
DATA:
columnName TYPE SO_TEXT,
fieldDataDescrRef TYPE REF TO abap_componentdescr,
numberFields TYPE i,
fieldDescr TYPE abap_componentdescr,
fieldname TYPE string,
fieldDescrTab TYPE abap_component_tab,
rowStructDescr TYPE REF TO cl_abap_structdescr,
rowReference TYPE REF TO data,
returnRowString TYPE string,
dataFieldString TYPE string,
dataline LIKE data,
fromClauseRow TYPE ZALBUS_STRUCT_WHERECLAUSE,
fromClauseString TYPE string,
whereClauseRow TYPE ZALBUS_STRUCT_WHERECLAUSE,
whereClauseString TYPE string,
fieldsRow TYPE ZALBUS_STRUCT_WHERECLAUSE.
FIELD-SYMBOLS:
<datarow> TYPE ANY,
<datafield> TYPE ANY.
* CREATE DataStructure with field names
* Datatypes are read from fieldnames of FIELDS input table
DESCRIBE TABLE FIELDS LINES numberFields.
LOOP AT FIELDS INTO fieldsRow.
fieldname = SY-TABIX.
* names need to be unique and must start with a char
CONCATENATE 'string' fieldname INTO fieldname.
CONDENSE fieldname.
fieldDescr-name = fieldname.
* for dictionary lookup we need to change columnnames from Open SQL
* to dictionary notation
columnName = fieldsRow-TEXT.
REPLACE FIRST OCCURRENCE OF SUBSTRING '~' IN columnName WITH '-' RESPECTING CASE.
fieldDescr-type ?= cl_abap_typedescr=>describe_by_name( columnName ).
APPEND fieldDescr TO fieldDescrTab.
ENDLOOP.
rowStructDescr = cl_abap_structdescr=>create( fieldDescrTab ).
* now we create the actual data structure in memory
create data rowReference type HANDLE rowStructDescr.
* finally we assign it to the Field-symbol used by the select statement
ASSIGN rowReference->* TO <datarow>.
* End Create DataStructure
* to simplify calls we concatenate from and whereclause into strings
* this way caller doesn't need to check word wrappings
fromClauseString = ''.
LOOP AT FROMCLAUSE INTO fromClauseRow.
CONCATENATE fromClauseString fromClauseRow-TEXT INTO fromClauseString.
ENDLOOP.
whereClauseString = ''.
LOOP AT WHERECLAUSE INTO whereClauseRow.
CONCATENATE whereClauseString whereClauseRow-TEXT INTO whereClauseString.
ENDLOOP.
* Now start actual select operation
SELECT (FIELDS) FROM (fromClauseString) INTO <datarow> WHERE (whereClauseString).
* we read all fields of the current row, cast it to string and
* concatenate it into a dataline with division chars.
CLEAR: returnRowString.
DO numberFields TIMES.
ASSIGN component sy-index of structure <datarow> to <datafield>.
dataFieldString = <datafield>.
CONCATENATE returnRowString '' datafieldstring INTO returnRowString.
ENDDO.
dataline = returnRowString.
* finally dataline is added to the return table.
INSERT dataline INTO TABLE data.
ENDSELECT.
ENDFUNCTION.
注:若出现多个字段到一列的情况,需要将代码中的一行:CONCATENATE returnRowString ' ' datafieldstring INTO returnRowString. 替换成 CONCATENATE returnRowString '|' datafieldstring INTO returnRowString.
3. 操作步骤
3.1 新建 abap function
新建abap function,命名为 FDL_EXTRACT_TABLE_DATA 。
点击Source code,将第 2 节的 FDL_EXTRACT_TABLE_DATA 源码贴进去,如下图所示:

点击 Tables 的表格 tab ,新增4个表:FIELDS /FROMCLAUSE /WHERECLAUSE /DATA,类型都为LIKE。
后面的结构类型按照文档源码,前三个输入ZSQL_CLAUSE_ELEMENTS,最后一个输入ZTABLEROWS,如下图所示:

注:此时可能会报错:没有ZSQL_CLAUSE_ELEMENTS和ZTABLEROWS,先保存一下function
展开 ABAP 工作台,双击 ABAP Dictionary 字典,如下图所示:

选择第三个 data type,输入数据结构名称 ZSQL_CLAUSE_ELEMENTS,点击创建,如下图所示:

选中 Structure 结构,点击确定,如下图所示:

输入简称,增加一个数据元素 TEXT,类型为 SO_TEXT,如下图所示:

同样的方法,我们创建 Structure 结构 ZTABLEROWS,增加一条数据元素,名字任意。如 ZTABLEROWS,数据元素 CHAR2000

保存这两个 structure,然后点击上方的结构树按钮,打开 Structure 所在包目录

展开 Structures 目录,就可以看到我们定义的那两个结构了,分别右击 > Activate 激活

回到 FDL_EXTRACT_TABLE_DATA,重新点击左边的 table 表格 tab,新加4个表,FIELDS /FROMCLAUSE /WHERECLAUSE /DATA 类型都为LIKE,后面的结构类型按照文档源码,前三个输入 ZSQL_CLAUSE_ELEMENTS,最后一个输入 ZTABLEROWS
3.2 保存检查
保存 function,并且点击工具栏的 check 按钮进行语法检查。

可能会报错,如下图所示:

则把 function 里面的 ZALBUS_STRUCT_WHERECLAUSE 都改成 ZSQL_CLAUSE_ELEMENTS
3.3 再次check
没有错误则表示 function 可以了,注意还需要设置函数可以远程访问

最后激活函数,完成设置。
