目录
开发类型:
调用BDC,以创建销售订单为例
开发申请:
开发申请如下,BDC文件名称是由业务顾问做好储存在SAP系统中的(如果没有,请让顾问提供)
预设效果图如下:
开发说明:这个功能是和批导程序一起的,为了方便阅读学习,拆分成了两个小开发。其实创建销售订单是有一个标准的BAPI的,但是因为业务的同事在谈需求时,考虑到用户的便捷性,填写批导模板数据的时候不想要输入太多数据,就选择了使用BDC,用户上传的时候数据就少一些。
开发步骤:
首先需要生成BDC程序,然后复制BDC的子例程,修改后即可调用,详细步骤如下:
1、生成BDC程序
使用SHDB找到业务储存的DBC记录,点击生成程序
2、查看BDC代码
创建成功后,即可进入SE38,搜索我们刚刚的程序名称ZBDC_VA01,看到BDC的代码
BDC_DYNPRO 指的就是屏幕,通过事务代码VA01,点击系统->状态即可以看到前台得屏幕展示如下
3、拷贝主程序
拷贝主程序,调整为自己的子例程
从open_group下面开始开始,到close_group上面结束。复制完后,把每一行的perform和using关键字都删掉,像下列所示代码一样。(其实可以看到下列的表和字段也是常客,VBAK表即销售订单凭证抬头表。)
因为是批量创建销售订单,所以将BDC放到一个大LOOP循环里面调用,为其字段赋值为上传上来的内表的值;又因为销售订单存在一个单子对应多个行项目得情况,所以在BDC复制的时候也进行了一次小LOOP循环。(这个就根据自己的逻辑来设置了),代码如下
*perform open_group
bdc_dynpro 'SAPMV45A' '0101'.
bdc_field 'BDC_CURSOR'
'VBAK-AUART'.
bdc_field 'BDC_OKCODE'
'/00'.
bdc_field 'VBAK-AUART'
LS_ALV-AUART.
bdc_field 'VBAK-VKORG'
LS_ALV-VKORG.
bdc_field 'VBAK-VTWEG'
LS_ALV-VTWEG.
bdc_field 'VBAK-SPART'
LS_ALV-SPART.
bdc_dynpro 'SAPMV45A' '4001'.
bdc_field 'BDC_OKCODE'
'/00'.
bdc_field 'VBKD-BSTDK'
LS_ALV-BSTDK.
bdc_field 'BDC_CURSOR'
LS_ALV-KUNNR.
bdc_field 'KUAGV-KUNNR'
LS_ALV-KUNNR.
bdc_field 'VBKD-BSTKD'
LS_ALV-BSTKD.
bdc_field 'RV45A-KETDAT'
LS_ALV-BSTDK.
bdc_field 'RV45A-KPRGBZ'
'D'.
bdc_field 'VBKD-PRSDT'
LS_ALV-BSTDK.
*多行s---------------
LOOP AT GT_ALV INTO GS_ALV WHERE BSTKD = LS_ALV-BSTKD.
bdc_dynpro 'SAPMV45A' '4001'.
bdc_field 'BDC_OKCODE'
'/00'.
bdc_field 'VBKD-BSTKD'
GS_ALV-BSTKD.
bdc_field 'VBKD-BSTDK'
GS_ALV-BSTDK.
bdc_field 'KUAGV-KUNNR'
GS_ALV-KUNNR.
bdc_field 'KUWEV-KUNNR'
GS_ALV-KUNNR.
bdc_field 'RV45A-KETDAT'
GS_ALV-BSTDK.
bdc_field 'RV45A-KPRGBZ'
'D'.
bdc_field 'VBKD-PRSDT'
GS_ALV-BSTDK.
bdc_field 'VBKD-ZTERM'
GS_ALV-ZTERM.
bdc_field 'BDC_CURSOR'
'KOMV-KBETR(02)'.
bdc_field 'RV45A-MABNR(02)'
GS_ALV-MATNR.
bdc_field 'RV45A-KWMENG(02)'
GS_ALV-KWMENG.
bdc_field 'VBAP-WERKS(02)'
GS_ALV-WERKS.
IF GS_ALV-WAERS = 'KRW' OR GS_ALV-WAERS = 'JPY' OR GS_ALV-WAERS = 'VND'.
bdc_field 'KOMV-KBETR(02)'
GS_ALV-KBETR1.
ELSE.
bdc_field 'KOMV-KBETR(02)'
GS_ALV-KBETR.
ENDIF.
ENDLOOP.
*多行e---------------
bdc_dynpro 'SAPMV45A' '4001'.
bdc_field 'BDC_OKCODE'
'=SICH'.
bdc_field 'VBKD-BSTKD'
LS_ALV-BSTKD.
bdc_field 'VBKD-BSTDK'
LS_ALV-BSTDK.
bdc_field 'KUAGV-KUNNR'
LS_ALV-KUNNR.
bdc_field 'KUWEV-KUNNR'
LS_ALV-KUNNR.
bdc_field 'RV45A-KETDAT'
LS_ALV-BSTDK.
bdc_field 'RV45A-KPRGBZ'
'D'.
bdc_field 'VBKD-PRSDT'
LS_ALV-BSTDK.
bdc_field 'VBKD-ZTERM'
LS_ALV-ZTERM.
bdc_field 'BDC_CURSOR'
'RV45A-MABNR(02)'.
*这里和程序BDC_VA01少了一行事务代码的赋值,我们放到后面用CALL TRANSACTION 来调用
*perform close_group.
4、调用事务代码
填充数据后使用CALL TRANSACTION 调用事务代码,(VA01)销售订单,执行模式选N(不显示屏幕的静默模式),更新模式选S(同步)
5、进行消息处理
调用VA01后,进行BDC的消息处理。
处理后的消息储存在LT_MSGTAB表中,我们只需要READ TABLE 就可以读取里面的内容了,可以将这里面的内容赋值到我们需要使用的其他地方。
至此,就将BDC赋值、调用、返回消息进行了一个正常的调用周期。
代码如下:
整个BDC的子例程代码如下:
DATA: LT_ALV TYPE STANDARD TABLE OF TY_ALV,
LS_ALV TYPE TY_ALV.
LT_ALV = GT_ALV.
CLEAR:GS_ALV.
DATA: LT_BDCDATA TYPE TABLE OF BDCDATA, " BDC执行内表
LT_MSGTAB TYPE TABLE OF BDCMSGCOLL, " BDC返回信息表
LS_BDCDATA TYPE BDCDATA,
LS_MSGTAB TYPE BDCMSGCOLL, " BDC返回信息表
LV_MESS TYPE STRING,
LV_MESSAGE TYPE STRING.
DATA: LC_MODE TYPE C VALUE 'N'. " BDC运行模式:A、E、N、P
DATA: LC_UPMODE TYPE C VALUE 'S', " BDC更新模式:L、A、S
LV_TCODE(10) TYPE C VALUE 'VA01'. " 销售定价新增
DEFINE BDC_DYNPRO.
CLEAR LS_BDCDATA.
LS_BDCDATA-PROGRAM = &1.
LS_BDCDATA-DYNPRO = &2.
LS_BDCDATA-DYNBEGIN = 'X'.
APPEND LS_BDCDATA TO LT_BDCDATA.
END-OF-DEFINITION.
DEFINE BDC_FIELD.
CLEAR LS_BDCDATA.
LS_BDCDATA-FNAM = &1.
LS_BDCDATA-FVAL = |{ &2 }|.
APPEND LS_BDCDATA TO LT_BDCDATA.
END-OF-DEFINITION.
SORT LT_ALV BY BSTKD.
DELETE ADJACENT DUPLICATES FROM LT_ALV COMPARING BSTKD.
LOOP AT LT_ALV INTO LS_ALV.
*perform open_group
bdc_dynpro 'SAPMV45A' '0101'.
bdc_field 'BDC_CURSOR'
'VBAK-AUART'.
bdc_field 'BDC_OKCODE'
'/00'.
bdc_field 'VBAK-AUART'
LS_ALV-AUART.
bdc_field 'VBAK-VKORG'
LS_ALV-VKORG.
bdc_field 'VBAK-VTWEG'
LS_ALV-VTWEG.
bdc_field 'VBAK-SPART'
LS_ALV-SPART.
bdc_dynpro 'SAPMV45A' '4001'.
bdc_field 'BDC_OKCODE'
'/00'.
bdc_field 'VBKD-BSTDK'
LS_ALV-BSTDK.
bdc_field 'BDC_CURSOR'
LS_ALV-KUNNR.
bdc_field 'KUAGV-KUNNR'
LS_ALV-KUNNR.
bdc_field 'VBKD-BSTKD'
LS_ALV-BSTKD.
bdc_field 'RV45A-KETDAT'
LS_ALV-BSTDK.
bdc_field 'RV45A-KPRGBZ'
'D'.
bdc_field 'VBKD-PRSDT'
LS_ALV-BSTDK.
*多行s---------------
LOOP AT GT_ALV INTO GS_ALV WHERE BSTKD = LS_ALV-BSTKD.
bdc_dynpro 'SAPMV45A' '4001'.
bdc_field 'BDC_OKCODE'
'/00'.
bdc_field 'VBKD-BSTKD'
GS_ALV-BSTKD.
bdc_field 'VBKD-BSTDK'
GS_ALV-BSTDK.
bdc_field 'KUAGV-KUNNR'
GS_ALV-KUNNR.
bdc_field 'KUWEV-KUNNR'
GS_ALV-KUNNR.
bdc_field 'RV45A-KETDAT'
GS_ALV-BSTDK.
bdc_field 'RV45A-KPRGBZ'
'D'.
bdc_field 'VBKD-PRSDT'
GS_ALV-BSTDK.
bdc_field 'VBKD-ZTERM'
GS_ALV-ZTERM.
bdc_field 'BDC_CURSOR'
'KOMV-KBETR(02)'.
bdc_field 'RV45A-MABNR(02)'
GS_ALV-MATNR.
bdc_field 'RV45A-KWMENG(02)'
GS_ALV-KWMENG.
bdc_field 'VBAP-WERKS(02)'
GS_ALV-WERKS.
IF GS_ALV-WAERS = 'KRW' OR GS_ALV-WAERS = 'JPY' OR GS_ALV-WAERS = 'VND'.
bdc_field 'KOMV-KBETR(02)'
GS_ALV-KBETR1.
ELSE.
bdc_field 'KOMV-KBETR(02)'
GS_ALV-KBETR.
ENDIF.
ENDLOOP.
*多行e---------------
bdc_dynpro 'SAPMV45A' '4001'.
bdc_field 'BDC_OKCODE'
'=SICH'.
bdc_field 'VBKD-BSTKD'
LS_ALV-BSTKD.
bdc_field 'VBKD-BSTDK'
LS_ALV-BSTDK.
bdc_field 'KUAGV-KUNNR'
LS_ALV-KUNNR.
bdc_field 'KUWEV-KUNNR'
LS_ALV-KUNNR.
bdc_field 'RV45A-KETDAT'
LS_ALV-BSTDK.
bdc_field 'RV45A-KPRGBZ'
'D'.
bdc_field 'VBKD-PRSDT'
LS_ALV-BSTDK.
bdc_field 'VBKD-ZTERM'
LS_ALV-ZTERM.
bdc_field 'BDC_CURSOR'
'RV45A-MABNR(02)'.
*perform close_group.
CALL TRANSACTION LV_TCODE " BDC调用的事务码
USING LT_BDCDATA " BDC执行内表
MODE LC_MODE " BDC运行模式
MESSAGES INTO LT_MSGTAB " BDC返回信息表
UPDATE LC_UPMODE. " 批导更新模式(A = '异步',S = '同步')
WAIT UP TO '0.1' SECONDS.
" BDC 消息处理
CLEAR:LV_MESSAGE,LV_MESS.
LOOP AT LT_MSGTAB INTO LS_MSGTAB WHERE MSGTYP = 'E' OR MSGTYP = 'A' OR ( MSGTYP = 'S' AND MSGNR = '344').
CALL FUNCTION 'MESSAGE_TEXT_BUILD'
EXPORTING
MSGID = LS_MSGTAB-MSGID
MSGNR = LS_MSGTAB-MSGNR
MSGV1 = LS_MSGTAB-MSGV1
MSGV2 = LS_MSGTAB-MSGV2
MSGV3 = LS_MSGTAB-MSGV3
MSGV4 = LS_MSGTAB-MSGV4
IMPORTING
MESSAGE_TEXT_OUTPUT = LV_MESS.
LV_MESSAGE = LV_MESSAGE && LV_MESS.
ENDLOOP.
READ TABLE LT_MSGTAB INTO LS_MSGTAB WITH KEY MSGV1 = '标准订单'.
IF SY-SUBRC = 0 AND LS_MSGTAB-MSGTYP = 'S'.
LS_ALV-ICON = ICON_LED_GREEN.
LS_ALV-MSG = |标准订单:{ LS_MSGTAB-MSGV2 }|.
ELSE.
CLEAR LS_MSGTAB .
READ TABLE LT_MSGTAB INTO LS_MSGTAB WITH KEY MSGV1 = '服务订单'.
IF SY-SUBRC = 0 AND LS_MSGTAB-MSGTYP = 'S'.
LS_ALV-ICON = ICON_LED_GREEN.
LS_ALV-MSG = |服务订单:{ LS_MSGTAB-MSGV2 }|.
ELSE.
CLEAR LS_MSGTAB .
READ TABLE LT_MSGTAB INTO LS_MSGTAB WITH KEY MSGV1 = '退货订单'.
IF SY-SUBRC = 0 AND LS_MSGTAB-MSGTYP = 'S'.
LS_ALV-ICON = ICON_LED_GREEN.
LS_ALV-MSG = |退货订单:{ LS_MSGTAB-MSGV2 }|.
ELSE.
LS_ALV-ICON = ICON_LED_RED.
LS_ALV-MSG = LV_MESSAGE.
ENDIF.
ENDIF.
ENDIF.
MODIFY LT_ALV FROM LS_ALV."更新alv
CLEAR: LT_BDCDATA,GS_ALV,LS_ALV.
FREE:LT_MSGTAB.
ENDLOOP.
整个代码其实很简单,主要是要注意BDC的一单一行和一单多行,BDC里面某些字段是不一样的,要注意辨别。