一步一步教你写SAPRFC(实战项目)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一步一步教你写SAPRFC(实战项目)
函数目的:OA通过读取采购订单号获取物料号最近5次变价记录,结果如图1-1所示
1)通过TCode:SE37,我们既可以进入RFC的开发初始界面,如图1-2所示。
2)与Report不同的是,新建RFC程序前必须先定义一个FuncitonGroup,一个Group下可包含多个Function,创建Function Group的命令的具体操作路径为:Goto-Function groups-Create group,如图1-2所示。
3)单击Creategroup 命令后将弹出Create Function Group对话框,要求输入自定义的Function group 名称及描述,如图1-3所示。
4)单击保存按钮后系统进入CreateObject Directiory Enter 对话框,该界面中需要输入开发类并选择保存类型,STMP表示保存本地类,也可单击本地对象按钮选择保存在本地,如图1-4所示。
5)选择本地对象按钮保存Functiongroup,系统返回初始界面。
输入自定义Function名称:Z_RFC_SHIZHANSTUDY,单击Create按钮,SAP将弹出Group设置属性对话框,如图1-5所示。
6)输入本例所建Function Group及描述,单击Save按钮保存定义。
到此为止,该Function已被创建成功,系统进入初始界面。
可以看到系统自动生成了预代码,但是还不具备任何功能,需要对Function的输入输出参数及数据处理逻辑程序进行设置,如图1-6所示。
7) Function编辑器共分为7个页面,在Attributes属性设置窗口,设置如图1-7所示。
允许该Function被SAP及非SAP程序调用。
8) Import为数据输入接口,其接口参数可以为单个变量或者为一个结构体。
本例为单个变量,如图1-8所示。
9)Tables可同时作为输入输出接口,其参数可为单个变量或Struct或内表。
本例为Struct,如图1-9所示。
本例创建结构步骤省略
10)单击Source Code选项卡切换到ABAP代码编辑窗口,接口中所定义的参数都是该Function代码的私有变量,可以在Function中直接引用,由此实现与外部程序数据交换。
在Source code中加入程序代码:
[sql] view plaincopyprint?
1.DATA: BEGIN OF POITABOCCURS 0,
2.EBELN LIKE EKKO-EBELN, '采购订单号
3.EBELP LIKE EKPO-EBELP, '采购订单行项目
4.LIFNR LIKE EKKO-LIFNR, '供应商
5.EKORG LIKE EKKO-EKORG, '采购组织
6.WERKS LIKE EKPO-WERKS, '工厂
7.MATNR LIKE EKPO-MATNR, '物料号
8.KSCHL LIKE A017-KSCHL, '条件类型
9.DATAB LIKE A017-DATAB, '有效期从
10.DATBI LIKE A017-DATBI, '有效期到
11.KNUMH LIKE A017-KNUMH, '条件记录号(定价记录号)
12.KBETR LIKE KONP-KBETR,
14.KPEIN LIKE KONP-KPEIN,
15.KMEIN LIKE KONP-KMEIN,
16.END OF POITAB.
17.
18.DATA: BEGIN OF AITAB OCCURS 0,
19.LIFNR LIKE A017-LIFNR, '供应商
20.EKORG LIKE A017-EKORG, '采购组织
21.WERKS LIKE A017-WERKS, '工厂
22.MATNR LIKE A017-MATNR, '物料号
23.DATAB LIKE A017-DATAB, '有效期从
24.DATBI LIKE A017-DATBI, '有效期到
25.KSCHL LIKE A017-KSCHL, '条件类型
26.KNUMH LIKE A017-KNUMH, '条件记录号(定价记录号)
27.END OF AITAB.
28.DATA: AITAB_S LIKE STANDARD TABLE OF AITABWITH HEADER LINE.
29.
30.DATA: BEGIN OF ITAB OCCURS 0,
31.EBELN LIKE EKKO-EBELN, '采购订单号
32.EBELP LIKE EKPO-EBELP, '采购订单行项目
33.LIFNR LIKE EKKO-LIFNR, '供应商
34.EKORG LIKE EKKO-EKORG, '采购组织
35.WERKS LIKE EKPO-WERKS, '工厂
36.MATNR LIKE EKPO-MATNR, '物料号
37.END OF ITAB.
38.
39.DATA: BEGIN OF KITAB OCCURS 0,
40.KBETR LIKE KONP-KBETR,
42.KPEIN LIKE KONP-KPEIN,
43.KMEIN LIKE KONP-KMEIN,
44.KNUMH LIKE KONP-KNUMH,
45.END OF KITAB.
46.
47.
48.' 搜索出采购订单号,供应商,采购组织,物料号,工厂
49.SELECT EKKO~EBELN EKKO~LIFNR
50.EKKO~EKORG EKPO~WERKS EKPO~MATNRekpo~ebe lp
51.INTO CORRESPONDING FIELDS OF TABLEITAB
52.FROM EKPO JOIN EKKO ON EKKO~EBELN =EKPO~EBE LN
53.WHERE EKKO~EBELN = IP_EBELN.
54.
55.'搜索出生效起和终日期,供应商,采购组织,物料号,工厂
56.IF ITAB[] IS NOT INITIAL.
57.在Open SQL中使用FOR ALL ENTRIED IN ITAB 前,一定要检查ITAB表是否为空,否则会造成SQL执行效率极低。
58.SELECT A017~DATBI A017~DATAB A017~KNUMHA01
7~LIFNR A017~MATNR A017~EKORG A017~WERKS
59.INTO CORRESPONDING FIELDS OF TABLE AITAB
60.FROM A017
61.FOR ALL ENTRIES IN ITAB
62.WHERE A017~LIFNR = ITAB-LIFNR
63.AND A017~MATNR = ITAB-MATNR
64.ANDA017~EKORG = ITAB-EKORG
65.AND A017~WERKS = ITAB-WERKS.
66.ENDIF.
67.'搜索出价格,单位等
68.IF AITAB[] IS NOT INITIAL.
69.SELECT KONP~KBETR KONP~KONWA KONP~KPEINK ONP~KMEIN KONP~KNUMH KONP~LOEVM_KO
70.INTO CORRESPONDING FIELDS OF TABLE KITAB
71.FROM KONP
72.FOR ALL ENTRIES IN AITAB
73.WHERE KONP~KNUMH = AITAB-KNUMH
74.AND KONP~LOEVM_KO <> 'X'.
75.ENDIF.
76.DATA: COUNT TYPE I. '定义变量COUNT,计数
77.COUNT = 0.
78.SORT AITAB BY LIFNR EKORG WERKS MATNR DATAB DESCENDING . '对AITAB内表排序--倒序
79.
80.LOOP AT AITAB.
81.MOVE-CORRESPONDING AITAB TO AITAB_S. '将内表AITAB的值转移给AITAB_S
82.APPEND AITAB_S.
83.
84.AT END OF MATNR.' 行组的结尾,如果下一行行组中的任
何字段内容不同于上一行,执行语句块中的内容。
85.CLEAR COUNT.
86.LOOP AT AITAB_S.
87.COUNT = COUNT 1.
88.IF COUNT <= 5. '计数开始,只列出5次的数据信息
89.MOVE-CORRESPONDING AITAB_S TO POITAB.
90.READ TABLE ITAB WITH KEY MATNR = AITAB_S-MATNR LIFNR = AITAB_S-LIFNREKORG = AITAB_S-
EKORG WERKS = AITAB_S-WERKS.
91.IF SY-SUBRC = 0.
92.MOVE-CORRESPONDING ITAB TO POITAB.
93.ENDIF.
94.READ TABLE KITAB WITH KEY KNUMH = AITAB_S-KNUMH. '通过条件记录号读出价格
95.IF SY-SUBRC = 0.
96.MOVE-CORRESPONDING KITAB TO POITAB.
97.ENDIF.
98.APPEND POITAB.
99.CLEAR POITAB.
100.ENDIF.
101.ENDLOOP.
102.CLEAR AITAB_S. ' 将内表重置为填充前的状态,这意味着该内表将不包含任何行
103.REFRESH AITAB_S. ' 如果内表有表头行,该语句并没有将表头行的内容清空。
104.ENDAT.
105.ENDLOOP.
106.LOOP AT POITAB. '因为POITAB内表和ZPO_INFO有相同字段,且字段数量不对等,所以用LOOP AT 做整体赋值操作107.MOVE-CORRESPONDING POITAB TO ZPO_INFO.
108.APPEND ZPO_INFO.
109.ENDLOOP.
[sql] view plaincopyprint?
1.DATA: BEGIN OF POITABOCCURS 0,
2.EBELN LIKE EKKO-EBELN, '采购订单号
3.EBELP LIKE EKPO-EBELP, '采购订单行项目
4.LIFNR LIKE EKKO-LIFNR, '供应商
5.EKORG LIKE EKKO-EKORG, '采购组织
6.WERKS LIKE EKPO-WERKS, '工厂
7.MATNR LIKE EKPO-MATNR, '物料号
8.KSCHL LIKE A017-KSCHL, '条件类型
9.DATAB LIKE A017-DATAB, '有效期从
10.DATBI LIKE A017-DATBI, '有效期到
11.KNUMH LIKE A017-KNUMH, '条件记录号(定价记录号)
12.KBETR LIKE KONP-KBETR,
13.KONWA LIKE KONP-KONWA,
14.KPEIN LIKE KONP-KPEIN,
15.KMEIN LIKE KONP-KMEIN,
16.END OF POITAB.
17.
18.DATA: BEGIN OF AITAB OCCURS 0,
19.LIFNR LIKE A017-LIFNR, '供应商
20.EKORG LIKE A017-EKORG, '采购组织
21.WERKS LIKE A017-WERKS, '工厂
22.MATNR LIKE A017-MATNR, '物料号
23.DATAB LIKE A017-DATAB, '有效期从
24.DATBI LIKE A017-DATBI, '有效期到
25.KSCHL LIKE A017-KSCHL, '条件类型
26.KNUMH LIKE A017-KNUMH, '条件记录号(定价记录
号)
27.END OF AITAB.
28.DATA: AITAB_S LIKE STANDARD TABLE OF AITABWITH HEADER LINE.
29.
30.DATA: BEGIN OF ITAB OCCURS 0,
31.EBELN LIKE EKKO-EBELN, '采购订单号
32.EBELP LIKE EKPO-EBELP, '采购订单行项目
33.LIFNR LIKE EKKO-LIFNR, '供应商
34.EKORG LIKE EKKO-EKORG, '采购组织
35.WERKS LIKE EKPO-WERKS, '工厂
36.MATNR LIKE EKPO-MATNR, '物料号
37.END OF ITAB.
38.
39.DATA: BEGIN OF KITAB OCCURS 0,
40.KBETR LIKE KONP-KBETR,
41.KONWA LIKE KONP-KONWA,
42.KPEIN LIKE KONP-KPEIN,
43.KMEIN LIKE KONP-KMEIN,
44.KNUMH LIKE KONP-KNUMH,
45.END OF KITAB.
46.
47.
48.' 搜索出采购订单号,供应商,采购组织,物料号,工厂
49.SELECT EKKO~EBELN EKKO~LIFNR
50.EKKO~EKORG EKPO~WERKS EKPO~MATNRekpo~ebe lp
51.INTO CORRESPONDING FIELDS OF TABLEITAB
52.FROM EKPO JOIN EKKO ON EKKO~EBELN =EKPO~EBE LN
53.WHERE EKKO~EBELN = IP_EBELN.
54.
55.'搜索出生效起和终日期,供应商,采购组织,物料号,工厂
56.IF ITAB[] IS NOT INITIAL.
57.在Open SQL中使用FOR ALL ENTRIED IN ITAB 前,一定要检查ITAB表是否为空,否则会造成SQL执行效率极低。
58.SELECT A017~DATBI A017~DATAB A017~KNUMHA01 7~LIFNR A017~MATNR A017~EKORG A017~WERKS
59.INTO CORRESPONDING FIELDS OF TABLE AITAB
60.FROM A017
61.FOR ALL ENTRIES IN ITAB
62.WHERE A017~LIFNR = ITAB-LIFNR
63.AND A017~MATNR = ITAB-MATNR
64.ANDA017~EKORG = ITAB-EKORG
65.AND A017~WERKS = ITAB-WERKS.
66.ENDIF.
67.'搜索出价格,单位等
68.IF AITAB[] IS NOT INITIAL.
69.SELECT KONP~KBETR KONP~KONWA KONP~KPEINK ONP~KMEIN KONP~KNUMH KONP~LOEVM_KO
70.INTO CORRESPONDING FIELDS OF TABLE KITAB
71.FROM KONP
72.FOR ALL ENTRIES IN AITAB
73.WHERE KONP~KNUMH = AITAB-KNUMH
74.AND KONP~LOEVM_KO <> 'X'.
75.ENDIF.
76.DATA: COUNT TYPE I. '定义变量COUNT,计数
77.COUNT = 0.
78.SORT AITAB BY LIFNR EKORG WERKS MATNR DATAB DESCENDING . '对AITAB内表排序--倒序
79.
80.LOOP AT AITAB.
81.MOVE-CORRESPONDING AITAB TO AITAB_S. '将内表AITAB的值转移给AITAB_S
82.APPEND AITAB_S.
83.
84.AT END OF MATNR.' 行组的结尾,如果下一行行组中的任何字段内容不同于上一行,执行语句块中的内容。
85.CLEAR COUNT.
86.LOOP AT AITAB_S.
87.COUNT = COUNT 1.
88.IF COUNT <= 5. '计数开始,只列出5次的数据信息
89.MOVE-CORRESPONDING AITAB_S TO POITAB.
90.READ TABLE ITAB WITH KEY MATNR = AITAB_S-MATNR LIFNR = AITAB_S-LIFNREKORG = AITAB_S-
EKORG WERKS = AITAB_S-WERKS.
91.IF SY-SUBRC = 0.
92.MOVE-CORRESPONDING ITAB TO POITAB.
93.ENDIF.
94.READ TABLE KITAB WITH KEY KNUMH = AITAB_S-KNUMH. '通过条件记录号读出价格
95.IF SY-SUBRC = 0.
96.MOVE-CORRESPONDING KITAB TO POITAB.
97.ENDIF.
98.APPEND POITAB.
99.CLEAR POITAB.
100.ENDIF.
101.ENDLOOP.
102.CLEAR AITAB_S. ' 将内表重置为填充前的状态,这意味着该内表将不包含任何行
103.REFRESH AITAB_S. ' 如果内表有表头行,该语句并没有将表头行的内容清空。
104.ENDAT.
105.ENDLOOP.
106.LOOP AT POITAB. '因为POITAB内表和ZPO_INFO有相同字段,且字段数量不对等,所以用LOOP AT 做整体赋值操作107.MOVE-CORRESPONDING POITAB TO ZPO_INFO.
108.APPEND ZPO_INFO.
109.ENDLOOP.
DATA: BEGIN OF POITABOCCURS 0, EBELN LIKE EKKO-EBELN, '采购订单号EBELP LIKE EKPO-EBELP, '采购订单行项目LIFNR LIKE EKKO-LIFNR, '供应商 EKORG LIKE EKKO-EKORG, '采购组织 WERKS LIKE EKPO-WERKS, '工厂MATNR LIKE EKPO-MATNR, '物料号KSCHL LIKE A017-KSCHL, '条件类型 DATAB LIKE A017-DATAB, '有效期从DATBI LIKE A017-DATBI, '有效期到KNUMH LIKE A017-KNUMH, '条件记录号(定价记录号)KBETR LIKE KONP-KBETR, KONWA LIKE KONP-KONWA, KPEIN LIKE KONP-KPEIN, KMEIN LIKE KONP-KMEIN, END OF POITAB. DATA: BEGIN OF AITAB OCCURS 0, LIFNR LIKE A017-LIFNR, '供应商EKORG LIKE A017-EKORG, '采购组织WERKS LIKE A017-WERKS, '工厂MATNR LIKE A017-MATNR, '物料号 DATAB LIKE A017-DATAB, '有效期从 DATBI
LIKE A017-DATBI, '有效期到KSCHL LIKE A017-KSCHL, '条件类型KNUMH LIKE A017-KNUMH, '条件记录号(定价记录号) END OF AITAB. DATA: AITAB_S LIKE STANDARD TABLE OF AITABWITH HEADER LINE. DATA: BEGIN OF ITAB OCCURS 0, EBELN LIKE EKKO-EBELN, '采购订单号EBELP LIKE EKPO-EBELP, '采购订单行项目 LIFNR LIKE EKKO-LIFNR, '供应商 EKORG LIKE EKKO-EKORG, '采购组织WERKS LIKE EKPO-WERKS, '工厂MATNR LIKE EKPO-MATNR, '物料号 END OF ITAB. DATA: BEGIN OF KITAB OCCURS 0, KBETR LIKE KONP-KBETR, KONWA LIKE KONP-KONWA, KPEIN LIKE KONP-KPEIN, KMEIN LIKE KONP-KMEIN, KNUMH LIKE KONP-KNUMH, END OF KITAB. ' 搜索出采购订单号,供应商,采购组织,物料号,工厂SELECT EKKO~EBELN EKKO~LIFNR EKKO~EKORG EKPO~WERKS EKPO~MATNRekpo~ebelp INTO CORRESPONDING FIELDS OF TABLEITAB FROM EKPO JOIN EKKO ON EKKO~EBELN =EKPO~EBELN WHERE EKKO~EBELN = IP_EBELN. '搜索出生效起和终日期,供应商,采购组织,物料号,工厂 IF ITAB[] IS NOT INITIAL. 在Open SQL中使用FOR ALL ENTRIED IN ITAB 前,一定要检查ITAB表是否为空,否则会造成SQL执行效率极低。
SELECT A017~DATBI A017~DATAB A017~KNUMHA017~LIFNR A017~MATNR A017~EKORG A017~WERKS INTO CORRESPONDING FIELDS OF TABLE AITAB FROM A017 FOR ALL ENTRIES IN ITAB WHERE A017~LIFNR = ITAB-LIFNR AND A017~MATNR = ITAB-MATNR ANDA017~EKORG = ITAB-EKORG AND A017~WERKS = ITAB-WERKS. ENDIF. '搜索出价格,单位等IF AITAB[] IS NOT INITIAL. SELECT KONP~KBETR KONP~KONWA KONP~KPEINKONP~KMEIN KONP~KNUMH KONP~LOEVM_KO INTO CORRESPONDING FIELDS OF TABLE KITAB FROM KONP FOR ALL ENTRIES IN AITAB WHERE KONP~KNUMH = AITAB-KNUMH AND KONP~LOEVM_KO <> 'X'. ENDIF. DATA: COUNT
TYPE I. '定义变量COUNT,计数 COUNT = 0. SORT AITAB BY LIFNR EKORG WERKS MATNR DATAB DESCENDING . '对AITAB内表排序--倒序LOOP AT AITAB. MOVE-CORRESPONDING AITAB TO AITAB_S. '将内表AITAB的值转移给AITAB_S APPEND AITAB_S. AT END OF MATNR.' 行组的结尾,如果下一行行组中的任何字段内容不同于上一行,执行语句块中的内容。
CLEAR COUNT. LOOP AT AITAB_S. COUNT = COUNT 1. IF COUNT <= 5. '计数开始,只列出5次的数据信息MOVE-CORRESPONDING AITAB_S TO POITAB. READ TABLE ITAB WITH KEY MATNR = AITAB_S-MATNR LIFNR = AITAB_S-LIFNREKORG = AITAB_S-EKORG WERKS = AITAB_S-WERKS. IF SY-SUBRC = 0. MOVE-CORRESPONDING ITAB TO POITAB. ENDIF. READ TABLE KITAB WITH KEY KNUMH = AITAB_S-KNUMH. '通过条件记录号读出价格IF SY-SUBRC = 0. MOVE-CORRESPONDING KITAB TO POITAB. ENDIF. APPEND POITAB. CLEAR POITAB. ENDIF. ENDLOOP. CLEAR AITAB_S. ' 将内表重置为填充前的状态,这意味着该内表将不包含任何行 REFRESH AITAB_S. ' 如果内表有表头行,该语句并没有将表头行的内容清空。
ENDAT. ENDLOOP. LOOP AT POITAB. '因为POITAB内表和ZPO_INFO有相同字段,且字段数量不对等,所以用LOOP AT 做整体赋值操作MOVE-CORRESPONDING POITAB TO ZPO_INFO. APPEND ZPO_INFO. ENDLOOP.
Function程序编写完成后可直接对其进行测试,保存Function后并激活,激活时要顺带将涉及本Function的所有都选中。
如图1-10所示。
单击编辑界面执行按钮,如图1-11所示。
11) Function的执行及数据查看
可以选择保存按钮将此手工输入保存起来,如图1-12所示。
单击执行,因为此采购订单有3条信息记录,3条信息记录有过很多次改价。
代码中我们只取离现在日期最近的5条,所以结果显示15条数据,结果如图1-13所示。
单击结果如图1-14所示。
至此本例已经全部完成,重要代码部分加注释了,也一目了然。