说明:BDC的应用
以下例子是简单例子:标准工时维护程序,在ALV中允许工时列字段值修改,然后“保存”按钮批量导入后台。
注意:1)先完成基本的取数和数据处理逻辑;
2)BDC录制: T-code:SHDB (更新对话选择“同步”)。
3)BDC代码调用:两个form :bdc_dynpro 用于定义屏幕;bdc_field 用于定义字段赋值,具体要根据录屏时生成的字段赋给内表值
REPORT ZRPP_WHOUR_MAINTENANCE.
TABLES : mara.
TYPE-POOLS: slis.
*------------------Variants & inner tables-----------------------------*
*-> 变量定义
DATA: u_command TYPE slis_formname VALUE 'USER_COMMAND',
ok_code LIKE sy-ucomm.
*BOM展开
data: gt_stpox like stpox occurs 0 with header line. "
*ALV中间变量
DATA: fieldcatalog TYPE slis_t_fieldcat_alv WITH HEADER LINE.
DATA: it_fieldcat TYPE lvc_t_fcat, "字段列举
gd_layout TYPE lvc_s_layo. "层
* BDC中间变量
DATA: itab_bdcdata LIKE STANDARD TABLE OF bdcdata WITH HEADER LINE.
DATA:l_bom LIKE stko-bmeng.
" 物料条件
data: begin of it_mara occurs 0,
matnr like mara-matnr, " 物料号
matkl like mara-matkl, " 物料组
wgbez like t023t-wgbez, " 物料组描述
end of it_mara.
" 工艺路线
data: begin of gw_route01,
plnty like plko-plnty, " 任务清单类型
plnnr like plko-plnnr, " 任务清单组码
plnal like plko-plnal, " 组计数器
zaehl like plko-zaehl, " 内部计数器
datuv like plko-datuv, " 有效起始日期
end of gw_route01.
" 中间结果:
DATA: it_coplpo LIKE TABLE OF coplpo WITH HEADER LINE.
" 结果输出
TYPES: BEGIN OF ty_out,
matkl like mara-matkl, " 物料组
matnr like mara-matnr, " 物料号
wgbez like t023t-wgbez, " 物料组描述
vornr type vornr, " 工序编码
ltxa1 type ltxa1, " 工序描述
vgwrt type vgwrt, " 工序工时
vgwrt_l TYPE vgwrt, " 更新前的标准工时
rate LIKE stpox-MNGKO, " 换算比例
vgwrt_w TYPE vgwrt, " 更新后的标准工时(考虑了小cell的)
SEL,
END OF ty_out.
DATA it_out TYPE TABLE OF ty_out WITH HEADER LINE.
*-------------------SELECTION-SCREEN----------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
SELECT-OPTIONS: s_matnr FOR mara-matnr,
s_matkl FOR mara-matkl.
PARAMETERS: p_werks TYPE werks DEFAULT '2100',
p_find RADIOBUTTON GROUP r01 DEFAULT 'X',
p_write RADIOBUTTON GROUP r01.
SELECTION-SCREEN END OF BLOCK b1 .
*-------------------------- INITIALIZATION --------------------------
*---------------------------START-OF-SELECTION-------------------------
START-OF-SELECTION.
PERFORM frm_initial. " 预处理
PERFORM frm_deal_data. " 取得工艺路线数据
PERFORM frm_alv_display. " alv 显示数据
" 预处理
*&---------------------------------------------------------------------*
*& Form frm_initial
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM frm_initial.
" 如果物料号和物料组同时为空,则查出所有的半成品/成品
if s_matnr = space and s_matkl = space.
select a~matnr a~matkl into corresponding fields of table it_mara
from mara as a join marc as b on a~matnr = b~matnr
where a~matnr LIKE 'B%'
and b~werks = p_werks.
else.
select a~matnr a~matkl into corresponding fields of table it_mara
from mara as a join marc as b on a~matnr = b~matnr
where a~matnr in s_matnr
and a~matkl in s_matkl
and b~werks = p_werks .
endif.
ENDFORM. "frm_initial
" 处理数据
*&---------------------------------------------------------------------*
*& Form frm_deal_data
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM frm_deal_data.
DATA:l_stlnr LIKE mast-stlnr.
CLEAR: it_mara ,gw_route01, it_coplpo[].
LOOP AT it_mara.
select single wgbez from t023t into it_mara-wgbez
where spras = sy-langu and matkl = it_mara-matkl.
select single plnty plnnr plnal zaehl datuv
into corresponding fields of gw_route01
from zvpp_route01 where matnr = it_mara-matnr. " 视图 zvpp_route01
if sy-subrc = 0.
CALL FUNCTION 'CP_EX_PLAN_READ' " 提取工艺路线(各方面)主数据资料
EXPORTING
PLNNR_IMP = gw_route01-plnnr
PLNAL_IMP = gw_route01-plnal
STTAG_IMP = gw_route01-datuv
TABLES
PLPO_EXP = it_coplpo[]
EXCEPTIONS
NOT_FOUND = 1
PLNAL_INITIAL = 2
OTHERS = 3 .
if it_coplpo[] is not INITIAL.
loop at it_coplpo.
it_out-matkl = it_mara-matkl.
it_out-matnr = it_mara-matnr.
it_out-wgbez = it_mara-wgbez.
it_out-vornr = it_coplpo-vornr.
it_out-ltxa1 = it_coplpo-ltxa1.
it_out-vgwrt = it_coplpo-vgw01.
it_out-vgwrt_l = it_out-vgwrt.
it_out-rate = 1. " 默认比例赋值为1
append it_out.
clear it_out.
endloop.
endif.
endif.
ENDLOOP.
" 以下对于物料组为705、706的小cell的特殊处理
CLEAR it_out.
LOOP AT it_out.
if it_out-matkl = '705' or it_out-matkl = '706' .
*& 抓取抬头基本数量,防止BOM有小数点差异
SELECT SINGLE stlnr INTO l_stlnr "BOM对应的物料单
FROM mast WHERE matnr = it_out-matnr
AND werks = '2100'
AND stlan = '1'
AND stlal = '01'.
SELECT SINGLE bmeng INTO l_bom FROM stko
WHERE stlty = 'M'
AND stlnr = l_stlnr
AND stlal = '01'
AND aennr <> '' .
IF sy-subrc <> 0. "如果没有更改的,则找原来的
SELECT SINGLE bmeng INTO l_bom FROM stko
WHERE stlty = 'M'
AND stlnr = l_stlnr
AND stlal = '01'
AND aennr = '' .
IF sy-subrc <> 0.
l_bom = '1000'.
ENDIF.
ENDIF.
CALL FUNCTION 'CS_BOM_EXPL_MAT_V2'
EXPORTING
CAPID = 'PP01'
DATUV = SY-DATUM
MDMPS = ''
MEHRS = 'X'
EMENG = l_bom
MTNRV = it_out-matnr
WERKS = p_werks
TABLES
STB = gt_stpox
EXCEPTIONS
ALT_NOT_FOUND = 1
CALL_INVALID = 2
MATERIAL_NOT_FOUND = 3
MISSING_AUTHORIZATION = 4
NO_BOM_FOUND = 5
NO_PLANT_DATA = 6
NO_SUITABLE_BOM_FOUND = 7
CONVERSION_ERROR = 8
OTHERS = 9.
if sy-subrc = 0.
READ TABLE gt_stpox WITH KEY IDNRK = '1100000001'.
" 后台维护的数据 = 前台维护数据 / 一片大CELL切出的小CELL数(由BOM关系推导)
" ex: 一片大cell 切出小cell数 :l_bom(100000 个) /mngko (313片)
it_out-vgwrt = it_out-vgwrt * l_bom / gt_stpox-mngko. " 显示 前台 = 后台 * 比例
it_out-vgwrt_l = it_out-vgwrt.
it_out-rate = l_bom / gt_stpox-mngko .
MODIFY it_out.
endif.
endif.
ENDLOOP.
ENDFORM. "frm_deal_data
*&---------------------------------------------------------------------*
*& Form frm_alv_display
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM frm_alv_display.
" 字段控制
PERFORM build_fieldcatalog CHANGING it_fieldcat.
" 函数调用
PERFORM frm_alv_output_data .
ENDFORM. "frm_alv_display
" ALV字段列举
*&---------------------------------------------------------------------*
*& Form build_fieldcatalog
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->IT_FIELDCAT text
*----------------------------------------------------------------------*
FORM build_fieldcatalog CHANGING it_fieldcat TYPE lvc_t_fcat.
PERFORM frm_fieldcat_init TABLES it_fieldcat
USING 'MATKL' '物料组' '0' '9' 'X' '' '' '' 'X' '' ''.
PERFORM frm_fieldcat_init TABLES it_fieldcat
USING 'MATNR' '物料号' '1' '18' 'X' '' '' '' 'X' '' ''.
PERFORM frm_fieldcat_init TABLES it_fieldcat
USING 'WGBEZ' '物料组描述' '2' '25' '' '' '' '' '' '' ''.
PERFORM frm_fieldcat_init TABLES it_fieldcat
USING 'VORNR' '工序编码' '3' '10' '' '' '' '' '' '' '' .
PERFORM frm_fieldcat_init TABLES it_fieldcat
USING 'LTXAL' '工序描述' '4' '40' '' '' '' '' '' '' ''.
if p_find = 'X'.
PERFORM frm_fieldcat_init TABLES it_fieldcat
USING 'VGWRT' '工序工时' '5' '12' '' '' '' '' '' '' '3' .
elseif p_write = 'X'.
PERFORM frm_fieldcat_init TABLES it_fieldcat
USING 'VGWRT' '工序工时' '5' '12' '' '' '' 'X' '' '' '3' .
endif.
ENDFORM. "build_fieldcatalog
" AVL字段控制
*&---------------------------------------------------------------------*
*& Form frm_fieldcat_init
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->T_FIELDCAT text
* -->FIELDNAME text
* -->SCRTEXT_M text
* -->COL_POS text
* -->OUTPUTLEN text
* -->EMPHASIZE text
* -->KEY text
* -->CHECKBOX text
* -->EDIT text
* -->FIX_COLUMN text
* -->COL_OPT text
*----------------------------------------------------------------------*
FORM frm_fieldcat_init TABLES t_fieldcat TYPE lvc_t_fcat
USING fieldname TYPE C " 字段名
scrtext_m TYPE C " 标题
col_pos TYPE I " 所在列
outputlen TYPE I " 输出长度
emphasize TYPE C " 高亮显示
key TYPE C " 主键
checkbox TYPE C
edit TYPE C
fix_column TYPE C " 固定列
COL_OPT TYPE C " 是否优化
* ref_tabname TYPE c
* ref_fieldname TYPE c
DECIMALS type i . " 设置小数后的位数,输入时,数字从右向左
.
DATA: ls_fieldcat TYPE lvc_s_fcat.
ls_fieldcat-fieldname = fieldname.
ls_fieldcat-scrtext_m = scrtext_m.
ls_fieldcat-col_pos = col_pos.
ls_fieldcat-outputlen = outputlen.
ls_fieldcat-emphasize = emphasize.
ls_fieldcat-key = key.
ls_fieldcat-checkbox = checkbox.
ls_fieldcat-edit = edit.
ls_fieldcat-fix_column = fix_column.
ls_fieldcat-COL_OPT = COL_OPT.
ls_fieldcat-DECIMALS = DECIMALS.
APPEND ls_fieldcat TO t_fieldcat.
CLEAR ls_fieldcat.
ENDFORM. "frm_fieldcat_init
*&---------------------------------------------------------------------*
*& Form frm_alv_output_data
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM frm_alv_output_data.
GD_LAYOUT-cwidth_opt = 'X'. " 自动收缩
GD_LAYOUT-box_fname = 'SEL'.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid
i_callback_pf_status_set = 'FRM_SET_STATUS' " FORM名字大写
i_callback_user_command = 'USER_COMMAND'
i_grid_title = '标准工时维护'
it_fieldcat_LVC = IT_FIELDCAT
IS_LAYOUT_LVC = GD_LAYOUT
i_save = 'X'
TABLES
t_outtab = it_out
EXCEPTIONS
program_error = 1
OTHERS = 2.
ENDFORM. "frm_alv_output_data
*激活自定义状态栏
FORM frm_set_status USING rt_extab TYPE slis_t_extab.
CLEAR: rt_extab.
REFRESH: rt_extab.
SET PF-STATUS '9001' EXCLUDING rt_extab.
ENDFORM. "FRM_SET_STATUS
* 用户自定义事件
FORM user_command USING ucomm TYPE sy-ucomm
selfield TYPE slis_selfield.
data: lo_guid type ref to cl_gui_alv_grid,
lr_grid type ref to cl_gui_alv_grid,
lt_index_rows TYPE lvc_t_row.
DATA: l_cursor01(15) TYPE c,
l_cursor02(15) TYPE c,
l_vgwrt01 type BDC_FVAL,
l_vgwrt02 TYPE BDC_FVAL.
CASE ucomm.
WHEN '&F03' OR 'EXIT' OR 'CANCLE'.
LEAVE TO SCREEN 0.
WHEN '&DATA_SAVE'." 保存按钮
* 取得当前alv的grid
call function 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = lo_guid.
* 更新数据到内表
call method lo_guid->check_changed_data.
” 批量处理
CLEAR it_out.
LOOP AT it_out.
" 发生变化的才更新 比较 vgwrt_l 与 vgwrt
if it_out-vgwrt_l <> it_out-vgwrt.
" BDC 录制,保存数据
it_out-vgwrt_w = it_out-vgwrt / it_out-rate . " 转换后的提交数据 后台 = 前台 / 比例
CONCATENATE 'PLPOD-VGW01' '('
it_out-vornr+1(02) ')' INTO l_cursor01.
CONCATENATE 'PLPOD-VGW02' '('
it_out-vornr+1(02) ')' INTO l_cursor02.
l_vgwrt01 = it_out-vgwrt_w .
l_vgwrt02 = it_out-vgwrt_w .
“FVAL 是132位的数据,赋值时,从右往左,导致前面出现长短空格,引起BDC保存时,提示字段长度不一致,故去除前导空格
CONDENSE: l_vgwrt01 NO-GAPS,
l_vgwrt02 NO-GAPS.
" 屏幕Form bdc_dynpro 1010
PERFORM bdc_dynpro USING 'SAPLCPDI' '1010'.
" 字段赋值 Form bdc_field
PERFORM bdc_field USING 'BDC_CURSOR' 'RC271-STTAG'.
PERFORM bdc_field USING 'BDC_OKCODE' '/00'.
PERFORM bdc_field USING 'RC27M-MATNR' it_out-matnr.
PERFORM bdc_field USING 'RC27M-WERKS' p_werks.
PERFORM bdc_field USING 'RC271-PLNNR' ''.
PERFORM bdc_field USING 'RC271-STTAG' sy-datum.
PERFORM bdc_field USING 'RC271-PLNAL' ''.
" 换屏了
PERFORM bdc_dynpro USING 'SAPLCPDI' '1400'.
* PERFORM bdc_field USING 'BDC_CURSOR' 'PLPOD-VGW02(01)'.
PERFORM bdc_field USING 'BDC_CURSOR' l_cursor01.
PERFORM bdc_field USING 'BDC_OKCODE' '=BU'.
PERFORM bdc_field USING 'RC27X-ENTRY_ACT' '1'.
* PERFORM bdc_field USING 'PLPOD-VGW01(01)' it_out-vgwrt_w .
* PERFORM bdc_field USING 'PLPOD-VGW02(01)' it_out-vgwrt_w.
PERFORM bdc_field USING l_cursor01 l_vgwrt01 .
PERFORM bdc_field USING l_cursor02 l_vgwrt02.
CALL TRANSACTION 'CA02' USING itab_bdcdata MODE 'E'. " 变更类型为E
REFRESH itab_bdcdata.
ENDIF.
ENDLOOP.
ENDCASE.
ENDFORM. "user_command
*&---------------------------------------------------------------------*
*& Form bdc_dynpro
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->PROGRAM text
* -->DYNPRO text
*----------------------------------------------------------------------*
FORM bdc_dynpro USING program dynpro.
CLEAR itab_bdcdata.
itab_bdcdata-program = program.
itab_bdcdata-dynpro = dynpro.
itab_bdcdata-dynbegin = 'X' .
APPEND itab_bdcdata.
ENDFORM. " bdc_dynpro
*&---------------------------------------------------------------------*
*& Form bdc_field
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->FIELDNAME text
* -->FIELDVALUE text
*----------------------------------------------------------------------*
FORM bdc_field USING fieldname fieldvalue.
CLEAR itab_bdcdata.
itab_bdcdata-fnam = fieldname.
itab_bdcdata-fval = fieldvalue.
APPEND itab_bdcdata.
ENDFORM. " bdc_field