前提要求:
①.
BW模型已经创建好并且抽好了数。
②.
已经有MDX语句基础。(BW有MDX语句学习测试环境,T-CODE:MDXTEST)
③.
对BW模型的星形模型设计结构已经掌握。
假设你对上面的知识已经完全了解了,就可以进行本次开发了,下面将介绍如何通过MDX语句进行RFC编写(以例子为基础进行讲解)。
模型:ZAAQM01→http://s2/bmiddle/0022XmNdty6HyBGVkiZ21&690
函数模块:ZMY_BW_RFC_ZAAQM01
http://s13/bmiddle/0022XmNdty6HyBTyhCu56&690
下面是RFC开发步骤:
1)
首先,创建RFC及设置好属性参数,如下图:
http://s5/bmiddle/0022XmNdty6HyBVpoQo38&690
2)
然后设置好RFC的Import参数,这里参数取决于你自身的需求,没有固定格式:
http://s3/bmiddle/0022XmNdty6HyBJlznYe2&690
3)
设置RFC输出数据格式参数,首先确定表格式,到SE11创建表结构,此处与ECC数据源创建时创建的结构类似,在此不重复:
http://s9/bmiddle/0022XmNdty6HyBKcrs418&690
4)
编写RFC源码,首先,利用MDX语句进行CUBE查询时,可以通过:
CALL FUNCTION 'EXPORT_GET_DATA_FROM_MDX'
来利用MDX语句进行CUBE数据查询,在调用这个FUNCTION之前,必须写好MDX语句及查询维度,如下面语句:
DATA :
TAB_CELL_DATA TYPE TABLE OF BAPI6111CD,
REC_DIMENSION TYPE BAPI6111AXD,
TAB_DIMENSION TYPE TABLE OF BAPI6111AXD,
REC_AIXS_INFO TYPE BAPI6111AXI,
TAB_AIXS_INFO TYPE TABLE OF BAPI6111AXI,
REC_MDCOLUMNS TYPE BAPI6111MPP,
TAB_MDCOLUMNS TYPE TABLE OF BAPI6111MPP,
REC_MDROWS TYPE BAPI6111MPP,
TAB_MDROWS TYPE TABLE OF BAPI6111MPP,
REC_DS_MDX_STMT TYPE BAPI6111MDX,
TAB_DS_MDX_STMT TYPE TABLE OF BAPI6111MDX.
*"*************************************************************************
* MDX 查询语句拼装
*"*************************************************************************
REC_DS_MDX_STMT-LINE = 'select'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' {[Measures].MEMBERS}'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' on columns,'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' filter(crossjoin({'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
LOOP AT ITAB_SWERK ASSIGNING .
CONCATENATE '[ZQM_SWERK].[' -/BIC/ZQM_SWERK '],' INTO SWERK_STR.
IF SY-TABIX = LINES( ITAB_SWERK ).
STR_LENTH = STRLEN( SWERK_STR ) - 1.
REC_DS_MDX_STMT-LINE = SWERK_STR(STR_LENTH)."去掉最后一个逗号
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
ELSE.
REC_DS_MDX_STMT-LINE = SWERK_STR.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
ENDIF.
ENDLOOP.
REC_DS_MDX_STMT-LINE = '},{'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
LOOP AT ITAB_LIFNR ASSIGNING .
CONCATENATE '[ZQM_LIFNR].[' -/BIC/ZQM_LIFNR '],' INTO LIFNR_STR.
IF SY-TABIX = LINES( ITAB_LIFNR ).
STR_LENTH = STRLEN( LIFNR_STR ) - 1.
REC_DS_MDX_STMT-LINE = LIFNR_STR(STR_LENTH)."去掉最后一个逗号
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
ELSE.
REC_DS_MDX_STMT-LINE = LIFNR_STR.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
ENDIF.
ENDLOOP.
REC_DS_MDX_STMT-LINE = '}),'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = '[Measures].[ZQM_SELCT] > 0) ON ROWS'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' from'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' $ZAAQM01'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' where {'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REPLACE ALL OCCURRENCES OF '.' IN I_PTERM_L WITH ''.
REPLACE ALL OCCURRENCES OF '.' IN I_PTERM_H WITH ''.
CONCATENATE '[ZQM_PTERM].[' I_PTERM_L ']:[ZQM_PTERM].[' I_PTERM_H ']' INTO PTERM_STR.
REC_DS_MDX_STMT-LINE = PTERM_STR.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = '}'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
*"**********************************************************************
* 查询维度选定
*"**********************************************************************
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM01P'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM01T'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM01U'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM011'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM012'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM013'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
通过MDX语句我们可以确定查询输出的数据格式,然后进行封装、转换就可以了,具体输出的格式可以在开发中调试查看,具体格式处理方法可以参照我下面的例子,下面给出完整源码:
FUNCTION ZMY_BW_RFC_ZAAQM01.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(I_SWERK_L) TYPE /BIC/OIZQM_SWERK OPTIONAL
*" VALUE(I_SWERK_H) TYPE /BIC/OIZQM_SWERK OPTIONAL
*" VALUE(I_PTERM_L) TYPE /BIC/OIZQM_PTERM OPTIONAL
*" VALUE(I_PTERM_H) TYPE /BIC/OIZQM_PTERM OPTIONAL
*" VALUE(I_LIFNR_L) TYPE /BIC/OIZQM_LIFNR OPTIONAL
*" VALUE(I_LIFNR_H) TYPE /BIC/OIZQM_LIFNR OPTIONAL
*" VALUE(I_MODEL) TYPE I DEFAULT 0
*" TABLES
*" E_T_DATA STRUCTURE ZBW_E_ZAAQM01
*" E_T_SWERK STRUCTURE ZBW_E_SWERK
*" E_T_LIFNR STRUCTURE ZBW_E_LIFNR
*"----------------------------------------------------------------------
DATA :
TAB_CELL_DATA TYPE TABLE OF BAPI6111CD,
REC_DIMENSION TYPE BAPI6111AXD,
TAB_DIMENSION TYPE TABLE OF BAPI6111AXD,
REC_AIXS_INFO TYPE BAPI6111AXI,
TAB_AIXS_INFO TYPE TABLE OF BAPI6111AXI,
REC_MDCOLUMNS TYPE BAPI6111MPP,
TAB_MDCOLUMNS TYPE TABLE OF BAPI6111MPP,
REC_MDROWS TYPE BAPI6111MPP,
TAB_MDROWS TYPE TABLE OF BAPI6111MPP,
REC_DS_MDX_STMT TYPE BAPI6111MDX,
TAB_DS_MDX_STMT TYPE TABLE OF BAPI6111MDX.
IF I_MODEL = 0 ."取数
DATA:
ITAB_SWERK TYPE TABLE OF ZBW_E_SWERK,
ITAB_LIFNR TYPE TABLE OF ZBW_E_LIFNR,
SWERK_STR TYPE STRING,
LIFNR_STR TYPE STRING,
PTERM_STR TYPE STRING,
STR_LENTH TYPE I,
GS_DATA TYPE ZBW_E_ZAAQM01.
FIELD-SYMBOLS:
TYPE ZBW_E_SWERK,
TYPE ZBW_E_LIFNR,
TYPE BAPI6111MPP,
TYPE BAPI6111CD.
"获取工厂、检验日期及供应商可选列表
SELECT DISTINCT /BIC/ZQM_SWERK TXTSH TXTMD
FROM /BIC/TZQM_SWERK
INTO CORRESPONDING FIELDS OF TABLE E_T_SWERK.
SELECT DISTINCT /BIC/ZQM_LIFNR TXTMD
FROM /BIC/TZQM_LIFNR
INTO CORRESPONDING FIELDS OF TABLE E_T_LIFNR.
*"*************************************************************************
* 传入参数检查
*"*************************************************************************
IF I_SWERK_L IS NOT INITIAL AND I_SWERK_H IS INITIAL. "检验工厂传入情况
SELECT DISTINCT /BIC/ZQM_SWERK TXTSH TXTMD
FROM /BIC/TZQM_SWERK
INTO CORRESPONDING FIELDS OF TABLE ITAB_SWERK
WHERE /BIC/ZQM_SWERK = I_SWERK_L.
ELSE.
IF I_SWERK_L IS INITIAL."假如没有限定工厂下限,则默认下限为0001
I_SWERK_L = '0001'.
ENDIF.
IF I_SWERK_H IS INITIAL."假如没有限定工厂,则默认为所有工厂
I_SWERK_H = '9999'.
ENDIF.
SELECT DISTINCT /BIC/ZQM_SWERK TXTSH TXTMD
FROM /BIC/TZQM_SWERK
INTO CORRESPONDING FIELDS OF TABLE ITAB_SWERK
WHERE /BIC/ZQM_SWERK BETWEEN I_SWERK_L AND I_SWERK_H.
ENDIF.
IF I_LIFNR_L IS NOT INITIAL AND I_LIFNR_H IS INITIAL.
SELECT DISTINCT /BIC/ZQM_LIFNR TXTMD
FROM /BIC/TZQM_LIFNR
INTO CORRESPONDING FIELDS OF TABLE ITAB_LIFNR
WHERE /BIC/ZQM_LIFNR = I_LIFNR_L.
ELSE.
IF I_LIFNR_L IS INITIAL."假如没有限定供应商下限,则默认下限为000001
I_LIFNR_L = '000001'.
ENDIF.
IF I_LIFNR_H IS INITIAL."假如没有限定供应商,则默认为所有供应商
I_LIFNR_H = '999999'.
ENDIF.
SELECT DISTINCT /BIC/ZQM_LIFNR TXTMD
FROM /BIC/TZQM_LIFNR
INTO CORRESPONDING FIELDS OF TABLE ITAB_LIFNR
WHERE /BIC/ZQM_LIFNR BETWEEN I_LIFNR_L AND I_LIFNR_H.
ENDIF.
IF I_PTERM_L IS INITIAL.
I_PTERM_L = '19700101'.
ENDIF.
IF I_PTERM_H IS INITIAL.
I_PTERM_H = '99991231'.
ENDIF.
*"*************************************************************************
* MDX 查询语句拼装
*"*************************************************************************
REC_DS_MDX_STMT-LINE = 'select'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' {[Measures].MEMBERS}'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' on columns,'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' filter(crossjoin({'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
LOOP AT ITAB_SWERK ASSIGNING .
CONCATENATE '[ZQM_SWERK].[' -/BIC/ZQM_SWERK '],' INTO SWERK_STR.
IF SY-TABIX = LINES( ITAB_SWERK ).
STR_LENTH = STRLEN( SWERK_STR ) - 1.
REC_DS_MDX_STMT-LINE = SWERK_STR(STR_LENTH)."去掉最后一个逗号
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
ELSE.
REC_DS_MDX_STMT-LINE = SWERK_STR.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
ENDIF.
ENDLOOP.
REC_DS_MDX_STMT-LINE = '},{'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
LOOP AT ITAB_LIFNR ASSIGNING .
CONCATENATE '[ZQM_LIFNR].[' -/BIC/ZQM_LIFNR '],' INTO LIFNR_STR.
IF SY-TABIX = LINES( ITAB_LIFNR ).
STR_LENTH = STRLEN( LIFNR_STR ) - 1.
REC_DS_MDX_STMT-LINE = LIFNR_STR(STR_LENTH)."去掉最后一个逗号
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
ELSE.
REC_DS_MDX_STMT-LINE = LIFNR_STR.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
ENDIF.
ENDLOOP.
REC_DS_MDX_STMT-LINE = '}),'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = '[Measures].[ZQM_SELCT] > 0) ON ROWS'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' from'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' $ZAAQM01'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = ' where {'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REPLACE ALL OCCURRENCES OF '.' IN I_PTERM_L WITH ''.
REPLACE ALL OCCURRENCES OF '.' IN I_PTERM_H WITH ''.
CONCATENATE '[ZQM_PTERM].[' I_PTERM_L ']:[ZQM_PTERM].[' I_PTERM_H ']' INTO PTERM_STR.
REC_DS_MDX_STMT-LINE = PTERM_STR.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
REC_DS_MDX_STMT-LINE = '}'.
APPEND REC_DS_MDX_STMT TO TAB_DS_MDX_STMT.
*"**********************************************************************
* 查询维度选定
*"**********************************************************************
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM01P'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM01T'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM01U'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM011'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM012'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
REC_DIMENSION-DIM_KEY = 'KEY_ZAAQM013'.
APPEND REC_DIMENSION TO TAB_DIMENSION.
*"**********************************************************************
* 执行MDX查询
*"**********************************************************************
CALL FUNCTION 'EXPORT_GET_DATA_FROM_MDX' "Creates the MDX object and selects the data
TABLES
pt_mdx_statement = TAB_DS_MDX_STMT " bapi6111mdx MDX Statement
pt_mndtry_prptys_rows = TAB_MDROWS " bapi6111mpp Default Features of Member
pt_mndtry_prptys_columns = TAB_MDCOLUMNS " bapi6111mpp Default Features of Member
pt_axis_info = TAB_AIXS_INFO " bapi6111axi MD_COMMAND Axis Info.
pt_axis_dimensions = TAB_DIMENSION " bapi6111axd Axis Dimensions
pt_cells = TAB_CELL_DATA " bapi6111cd Data in Dataset Cell
EXCEPTIONS
ERROR_CONVERTING_TIME_FORMAT = 1 " Time Format is incorrect
MDX_QUERY_SYNTAX_CHECK_FAILED = 2 " Syntax error in MDX statement
ERROR_WHEN_SELECTING_DATA = 3 " Error when selecting results from MDX object
ERROR_WHEN_CREATING_MDX_OBJECT = 4 " Error when creating MDX object
ERROR_WHEN_GETTING_AXIS_INFO = 5 " Error when reading axis information from MDX object
ERROR_WHEN_GETTING_AXIS_DATA = 6 " Error when reading axis data from MDX object
ERROR_WHEN_GETTING_CELL_DATA = 7 " Error when reading cell data from MDX object
. " EXPORT_GET_DATA_FROM_MDX
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
*"**********************************************************************
* 数据封装
*"**********************************************************************
IF TAB_CELL_DATA IS NOT INITIAL."把数据填入E_T_DATA
DATA:
ROWS_COUNTER TYPE I VALUE 0,"用记录行
DATA_COUNTER TYPE I VALUE 0,
RECORD TYPE I VALUE 0,"当前记录数
NUM_OF_LINE TYPE I VALUE 0,"总行数
STR1 TYPE STRING VALUE '',
STR2 TYPE STRING VALUE ''.
NUM_OF_LINE = LINES( TAB_MDROWS ) / 2.
DO NUM_OF_LINE TIMES."根据行数决定循环次数
ROWS_COUNTER = ( SY-INDEX - 1 ) * 2 + 1.
DATA_COUNTER = ( SY-INDEX - 1 ) * 3 + 1.
CLEAR GS_DATA.
READ TABLE TAB_MDROWS ASSIGNING INDEX ROWS_COUNTER."读取工厂
IF SY-SUBRC = 0.
SPLIT -MEM_UNAM AT '.' INTO : STR1 STR2.
GS_DATA-SWERK = STR2+1(4).
GS_DATA-NAME2 = -MEM_CAP.
CLEAR: STR1,STR2.
ENDIF.
READ TABLE TAB_MDROWS ASSIGNING INDEX ROWS_COUNTER + 1."读取供应商
IF SY-SUBRC = 0.
SPLIT -MEM_UNAM AT '.' INTO : STR1 STR2.
IF STRLEN( STR2 ) < 6."对于长度不足6位的供应商,在其后面补0
CONCATENATE '00000' STR2 '000000' INTO STR2.
ENDIF.
GS_DATA-LIFNR = STR2+5(6).
GS_DATA-NAME1 = -MEM_CAP.
CLEAR: STR1,STR2.
ENDIF.
READ TABLE TAB_CELL_DATA ASSIGNING INDEX DATA_COUNTER."读取供货总数量
IF SY-SUBRC = 0.
GS_DATA-SELCT = -VALUE.
ENDIF.
READ TABLE TAB_CELL_DATA ASSIGNING INDEX DATA_COUNTER + 1."读取合格数量
IF SY-SUBRC = 0.
GS_DATA-SFRBE = -VALUE.
ENDIF.
READ TABLE TAB_CELL_DATA ASSIGNING INDEX DATA_COUNTER + 2."读取不合格数量
IF SY-SUBRC = 0.
GS_DATA-SPERR = -VALUE.
ENDIF.
RECORD = RECORD + 1.
GS_DATA-RECORD = RECORD.
APPEND GS_DATA TO E_T_DATA.
ENDDO.
ENDIF.
ELSE."获取工厂、检验日期及供应商可选列表
SELECT DISTINCT /BIC/ZQM_SWERK TXTSH TXTMD
FROM /BIC/TZQM_SWERK
INTO CORRESPONDING FIELDS OF TABLE E_T_SWERK.
SELECT DISTINCT /BIC/ZQM_LIFNR TXTMD
FROM /BIC/TZQM_LIFNR
INTO CORRESPONDING FIELDS OF TABLE E_T_LIFNR.
* SELECT DISTINCT DATE0
* FROM /BI0/SDATE
* INTO CORRESPONDING FIELDS OF TABLE E_T_PTERM.
ENDIF.
*"**********************************************************************
ENDFUNCTION.
加载中,请稍候......