SAP通过EXCEL导入批量修改或添加物料BOM程序,如果BOM存则先删除BOM,如果BOM不存在则添加BOM。
REPORT zppb015.
*----------------------------------------------------------------------*
* 数据库表声明/Database Table Declaration
*----------------------------------------------------------------------*
TABLES: sscrfields.
*&---------------------------------------------------------------------*
*& ALV TYPE/ALV 类型定义 *
*&---------------------------------------------------------------------*
*&--- ALV 数据组,类型池
TYPE-POOLS: slis,
vrm.
*&--- 定义 ALV 显示的字段列及其描述等属性
DATA: gt_fieldcat TYPE lvc_t_fcat, " 字段目录
gs_fieldcat TYPE lvc_s_fcat, " 字段目录
gs_layout TYPE lvc_s_layo. " 布局结构
*----------------------------------------------------------------------*
* 结构声明类型/Structure Type Declaration
*----------------------------------------------------------------------*
*&--- 主表数据
TYPES: BEGIN OF ty_tab,
matnr TYPE mast-matnr , " 产品编码
matnr_o TYPE mast-matnr , " 旧产品编码
fmaktx TYPE makt-maktx , " 产品描述
werks TYPE mast-werks , " 工厂代码
stlal TYPE mast-stlal , " 版本
bmeng TYPE stko-bmeng , " 基本用量
posnr TYPE stpo-posnr , " 项目编号
postp TYPE stpo-postp , " 项目类别
idnrk TYPE stpo-idnrk , " 组件编码
idnrk_o TYPE stpo-idnrk , " 旧组件编码
smaktx TYPE makt-maktx , " 组件描述
menge TYPE stpo-menge , " 组件用量
ausch TYPE stpo-ausch , " 损耗率
kzkup TYPE stpo-kzkup , " 联产品
lgort TYPE stpo-lgort , " 发货库位
stlan TYPE mast-stlan , " BOM用途
bmein TYPE stko-bmein , " 基本用量单位
meins TYPE stpo-meins , " 组件单位
stlbe TYPE stzu-stlbe, "权限组
* stktx TYPE stko-stktx , " 母件表头备注
* sortf TYPE stpo-sortf , " 物料类型(排序字符串)
alpgr TYPE stpo-alpgr , " 替代组
* alprf TYPE stpo-alprf , " 优先级
* aennr TYPE stpo-aennr , " ECN号
* potx1 TYPE stpo-potx1 , " 项目文本1
"alpst TYPE stpo-alpst , " 策略
ewahr TYPE stpo-ewahr , " 使用比例
* potx2 TYPE stpo-potx2 , " 项目文本2
* itsob TYPE stpo-itsob , " 特殊采购
Ztype(10), "导入类型
check ,
icon TYPE char4 , " LIGHT
type TYPE bapi_mtype , " 消息类型
message TYPE bapi_msg , " 消息
znumb TYPE int4,
END OF ty_tab.
*----------------------------------------------------------------------*
* 全局变量定义/Global Variable Definition
*----------------------------------------------------------------------*
*&--- 主数据表
DATA: gt_tab TYPE TABLE OF ty_tab,
gt_excel TYPE TABLE OF ty_tab WITH HEADER LINE,
gs_tab TYPE ty_tab.
*&--- Excel 数据存储
DATA: gt_xlstmp TYPE alsmex_tabline OCCURS 0. " 保存 Excel 中读取的记录
*&--- 选择界面下载按钮参数
DATA: gs_functxt TYPE smp_dyntxt.
*&---------------------------------------------------------------------*
*& 字段串定义/Field-Symbols *
*&---------------------------------------------------------------------*
FIELD-SYMBOLS: LIKE alsmex_tabline. " Excel 单元格
FIELD-SYMBOLS: TYPE any.
*&---------------------------------------------------------------------*
*& Macro 宏定义 *
*&---------------------------------------------------------------------*
DEFINE mcr_set_catalog.
CLEAR gs_fieldcat.
gs_fieldcat-fieldname = &1. " 字段技术名称
gs_fieldcat-coltext = &2. " 显示名称
gs_fieldcat-no_zero = &3. " 为输出隐藏零
gs_fieldcat-ref_table = &4. " 参照表
gs_fieldcat-ref_field = &5. " 参照表字段
APPEND gs_fieldcat TO gt_fieldcat.
END-OF-DEFINITION.
*&---------------------------------------------------------------------*
*& SELECTION SCREEN/选择屏幕 *
*&---------------------------------------------------------------------*
SELECTION-SCREEN:FUNCTION KEY 1. " 在屏幕定义功能码
*&--- 选择屏幕块
SELECTION-SCREEN: BEGIN OF BLOCK blk1 WITH FRAME TITLE TEXT-101. " 选择条件
PARAMETERS: p_file TYPE dxfields-longpath. " 文件路径
SELECTION-SCREEN: END OF BLOCK blk1.
*&---------------------------------------------------------------------*
*& INITIALIZATION/选择屏幕前初始化 *
*&---------------------------------------------------------------------*
INITIALIZATION.
*&---初始化选择屏幕值
*&---初始化变量
gs_functxt-icon_id = icon_mapped_relation.
gs_functxt-icon_text = TEXT-102. " 模板下载
sscrfields-functxt_01 = gs_functxt.
*----------------------------------------------------------------------*
* At selection-screen *
*----------------------------------------------------------------------*
AT SELECTION-SCREEN.
*&--- 下载模板
CASE sscrfields-ucomm.
WHEN 'FC01'." 系统预留的功能码
" 下载模板文件
PERFORM frm_download_excel.
WHEN OTHERS.
ENDCASE.
*&---------------------------------------------------------------------*
*& AT SELECTION-SCREEN OUTPUT/选择屏幕输出 *
*&---------------------------------------------------------------------*
AT SELECTION-SCREEN OUTPUT.
*&---------------------------------------------------------------------*
*& AT SELECTION-SCREEN ON VALUE-REQUEST/ 选择屏幕搜索帮助 *
*&---------------------------------------------------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
*&--- 选择文件获取文件路径
PERFORM frm_select_infile CHANGING p_file.
*&---------------------------------------------------------------------*
*& START-OF-SELECTION/开始选择屏幕 *
*&---------------------------------------------------------------------*
START-OF-SELECTION.
*-- 获取数据
PERFORM frm_get_data.
*&---------------------------------------------------------------------*
*& END-OF-SELECTION/结束选择屏幕(程序结束处理,输出等) *
*&---------------------------------------------------------------------*
END-OF-SELECTION.
IF gt_tab IS NOT INITIAL.
*-- ALV 显示
PERFORM frm_display_alv.
ELSE.
MESSAGE s008(zpp001) DISPLAY LIKE 'E'. " 没有找到符合条件的数据
LEAVE LIST-PROCESSING.
ENDIF.
*&---------------------------------------------------------------------*
*& Form FRM_USER_STATUS
*&---------------------------------------------------------------------*
*& ALV 工具栏状态
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_set_pf_status USING ps_extab TYPE slis_t_extab.
SET PF-STATUS 'STATUS_0500'. " 自定义状态名称
ENDFORM. "FRM_SET_PF_STATUS
*&---------------------------------------------------------------------*
*& Form FRM_USER_COMMAND
*&---------------------------------------------------------------------*
*& ALV 工具栏命令
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_usr_command USING pv_ucomm LIKE sy-ucomm
ps_selfield TYPE slis_selfield.
DATA: lr_alv_grid TYPE REF TO cl_gui_alv_grid.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = lr_alv_grid. " 获取全局变量
CALL METHOD lr_alv_grid->check_changed_data. " 获取响应事件
ps_selfield-refresh = 'X'. " 刷新界面
ps_selfield-row_stable = 'X'.
ps_selfield-col_stable = 'X'.
*&--- 触发工具栏命令
CASE pv_ucomm.
" 触发「导入」按钮
WHEN 'ZIMPORT'.
PERFORM frm_call_bapi. " 调用 BAPI
WHEN OTHERS.
ENDCASE.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_GET_DATA
*&---------------------------------------------------------------------*
*& 获取上传 Excel 文件数据后校验数据
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_get_data .
DATA: ls_tab TYPE ty_tab,
lv_tabix TYPE sy-tabix,
lv_lenht TYPE i,
lv_ewahr TYPE ewahr.
PERFORM frm_upload_data. " 上传数据
IF gt_tab IS NOT INITIAL.
*&--- 物料工厂信息
SELECT matnr,
werks
INTO TABLE @DATA(lt_matr)
FROM marc
FOR ALL ENTRIES IN @gt_tab
WHERE ( matnr = @gt_tab-matnr AND werks = @gt_tab-werks )
OR ( matnr = @gt_tab-idnrk AND werks = @gt_tab-werks ).
*&--- 备选物料清单
SELECT matnr,
werks,
stlal
INTO TABLE @DATA(lt_mast)
FROM mast
FOR ALL ENTRIES IN @gt_tab
WHERE matnr = @gt_tab-matnr
AND stlal = @gt_tab-stlal
AND werks = @gt_tab-werks.
*&--- 基本用量单位
SELECT mara~matnr,
mara~meins
INTO TABLE @DATA(lt_mara)
FROM mara
FOR ALL ENTRIES IN @gt_tab
WHERE matnr = @gt_tab-matnr .
*&--- 组件用量单位
SELECT mara~matnr,
mara~meins
INTO TABLE @DATA(lt_mara_sub)
FROM mara
FOR ALL ENTRIES IN @gt_tab
WHERE matnr = @gt_tab-idnrk.
*&--- 发货库位校验
SELECT
werks,
lgort
FROM t001l
FOR ALL ENTRIES IN @gt_tab
WHERE werks = @gt_tab-werks AND
lgort = @gt_tab-lgort
INTO TABLE @DATA(lt_t001l).
ENDIF.
"获取权限参数
RANGES:g_ranges FOR marc-werks.
DATA:lt_us335 TYPE TABLE OF us335.
CALL FUNCTION 'GET_AUTH_VALUES'
EXPORTING
object1 = 'M_MATE_WRK'
* OBJECT2 = ' '
* OBJECT3 = ' '
* OBJECT4 = ' '
* OBJECT5 = ' '
* OBJECT6 = ' '
* OBJECT7 = ' '
user = sy-uname
* TCODE = SY-TCODE
* OPTIMIZE =
TABLES
values = lt_us335[]
EXCEPTIONS
user_doesnt_exist = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ELSE.
DATA:lv_flg TYPE char01.
LOOP AT lt_us335 INTO DATA(ls_us335) WHERE field = 'WERKS'.
IF ls_us335-lowval EQ '*'.
DATA(lv_authority_flg) = 'X'.
EXIT.
ELSE.
*"单值
g_ranges-sign = 'I'.
g_ranges-option = 'EQ'.
g_ranges-low = ls_us335-lowval.
APPEND g_ranges.
ENDIF.
ENDLOOP.
ENDIF.
SORT gt_tab BY matnr werks stlal posnr.
SORT lt_matr BY matnr werks.
SORT lt_mast BY matnr werks stlal.
SORT lt_mara BY matnr.
SORT lt_t001l BY werks lgort.
SORT lt_mara_sub BY matnr.
CLEAR: gs_tab.
LOOP AT gt_tab INTO gs_tab.
lv_tabix = sy-tabix + 1.
CLEAR gs_tab-message.
*&--- BOM 用途取值,默认为 1
gs_tab-stlan = '1'.
*&--------权限校验
IF lv_authority_flg NE 'X'.
IF gs_tab-werks NOT IN g_ranges.
gs_tab-message = gs_tab-message && TEXT-126.
ENDIF.
ENDIF.
*&--- 检查模版中头物料(MATNR)与组件物料(IDNRK)是否在工厂主数据中存在,系统报错,提示:物料XXX在工厂XX中不存在
READ TABLE lt_matr INTO DATA(ls_matr) WITH KEY matnr = gs_tab-matnr
werks = gs_tab-werks BINARY SEARCH.
IF sy-subrc NE 0.
IF gs_tab-postp <> 'T'. " 项目类型为 T 时,不进行物料工厂校验
gs_tab-message = gs_tab-message && TEXT-112 && TEXT-109 && gs_tab-matnr && TEXT-110 && gs_tab-werks && TEXT-111.
ENDIF.
ENDIF.
READ TABLE lt_matr INTO ls_matr WITH KEY matnr = gs_tab-idnrk
werks = gs_tab-werks BINARY SEARCH.
IF sy-subrc NE 0.
IF gs_tab-postp <> 'T'. " 项目类型为 T 时,不进行物料工厂校验
gs_tab-message = gs_tab-message && TEXT-112 && TEXT-109 && gs_tab-idnrk && TEXT-110 && gs_tab-werks && TEXT-111.
ENDIF.
ENDIF.
* 2. 校验发货库位在工厂有没有存在,查询表T001L
READ TABLE lt_t001l INTO DATA(ls_t001l) WITH KEY werks = gs_tab-werks
lgort = gs_tab-lgort BINARY SEARCH.
IF sy-subrc <> 0 AND gs_tab-lgort IS NOT INITIAL.
gs_tab-message = gs_tab-message && TEXT-112 && TEXT-122. " 发货库位在工厂中不存在
ENDIF.
* 3. 检查模版中头物料(MATNR)+BOM版本(STLAL)是否在工厂BOM已存在,系统报错,提示:物料(MATNR)BOM版本(STLAL)在工厂XX
* 中已存在BOM 参考表 mast
* READ TABLE LT_MAST INTO DATA(LS_MAST) WITH KEY MATNR = GS_TAB-MATNR
* WERKS = GS_TAB-WERKS
* STLAL = GS_TAB-STLAL BINARY SEARCH.
* IF SY-SUBRC = 0.
* GS_TAB-MESSAGE = GS_TAB-MESSAGE && TEXT-112 && TEXT-109 && GS_TAB-MATNR && TEXT-113 && GS_TAB-STLAL && TEXT-110 && GS_TAB-WERKS && TEXT-114.
* ENDIF.
* 4. 模版中如果出现相同的头物料(MATNR)与组件物料(IDNRK)相同,系统报错,提示:父物料与子物料不能相同。
READ TABLE gt_tab INTO ls_tab WITH KEY matnr = gs_tab-matnr
werks = gs_tab-werks
stlan = gs_tab-stlan
stlal = gs_tab-stlal
idnrk = gs_tab-matnr BINARY SEARCH.
IF sy-subrc = 0.
gs_tab-message = gs_tab-message && TEXT-112 && TEXT-115. " 父物料与子物料不能相同
ENDIF.
* 5. 模版中如果出现相同的头物料(MATNR)相同的行项(POSNR),系统报错,提示:父物料下面的组件行项目不可重复。
READ TABLE gt_tab INTO ls_tab INDEX lv_tabix .
IF sy-subrc = 0.
IF ls_tab-posnr = gs_tab-posnr AND
ls_tab-matnr = gs_tab-matnr AND
ls_tab-werks = gs_tab-werks AND
ls_tab-stlan = gs_tab-stlan AND
ls_tab-stlal = gs_tab-stlal.
gs_tab-message = gs_tab-message && TEXT-112 && TEXT-116. " 父物料下面的组件行项目不可重复
ENDIF.
ENDIF.
* 6. 模版中组件物料数量(MENGE)为空或等于零,系统报错,提示:组件物料数量错误。
IF gs_tab-menge IS INITIAL.
gs_tab-message = gs_tab-message && TEXT-112 && TEXT-117. " 组件物料数量错误
ENDIF.
* 7. 如果有维护权限组,如不为空,又不等于WDF0,提示“权限组错误”
IF gs_tab-stlbe IS NOT INITIAL AND ( gs_tab-stlbe NE 'WDF0' AND gs_tab-stlbe NE 'WDF1' ).
gs_tab-message = gs_tab-message && TEXT-112 && TEXT-123. " 权限组错误
ENDIF.
* 8. 1. BOM版本不能为空,
* 8. 2. 如BOM版本已存在,提示“该版本已存在”:MAST-MATNR = 产品编码,MAST-WERKS = 工厂,MAST-STLAN = 1,MAST-STLAL = BOM版本,查询记录>0
IF gs_tab-stlal IS INITIAL.
gs_tab-message = gs_tab-message && TEXT-112 && TEXT-124. " 权限组错误
ENDIF.
*---修改导入BOM的判断是否已有BOM,有也可导入
* IF gs_tab-stlal IS NOT INITIAL .
* SELECT COUNT( * ) FROM mast WHERE matnr EQ @gs_tab-matnr AND werks EQ @gs_tab-werks AND stlal EQ @gs_tab-stlal.
* IF sy-subrc EQ 0.
* gs_tab-message = gs_tab-message && TEXT-112 && TEXT-125. " 权限组错误
* ENDIF.
*
* ENDIF.
*&--- 判定错误消息,赋值指示灯状态
gs_tab-message = gs_tab-message+1.
IF gs_tab-message IS NOT INITIAL.
gs_tab-icon = '@0A@'. " 红灯
gs_tab-type = 'E'.
ELSE.
gs_tab-icon = '@08@'. " 绿灯
gs_tab-type = 'S'.
ENDIF.
IF gs_tab-stlal IS NOT INITIAL .
SELECT COUNT( * ) FROM mast WHERE matnr EQ @gs_tab-matnr AND werks EQ @gs_tab-werks AND stlal EQ @gs_tab-stlal.
IF sy-subrc EQ 0.
"gs_tab-message = gs_tab-message && TEXT-112 && TEXT-125. " 权限组错误
gs_tab-ztype = '修改'.
ELSE.
gs_tab-ztype = '新增'.
ENDIF.
ENDIF.
*&--- 回写物料基础单位
" 母件物料基础单位
READ TABLE lt_mara INTO DATA(ls_mara1) WITH KEY matnr = gs_tab-matnr BINARY SEARCH.
IF sy-subrc = 0.
gs_tab-bmein = ls_mara1-meins.
ENDIF.
IF gs_tab-idnrk IS NOT INITIAL.
" 组件基础单位
READ TABLE lt_mara INTO DATA(ls_mara2) WITH KEY matnr = gs_tab-idnrk BINARY SEARCH.
IF sy-subrc = 0.
gs_tab-meins = ls_mara2-meins.
ENDIF.
ELSEIF gs_tab-idnrk IS INITIAL.
CLEAR: gs_tab-meins.
ENDIF.
" 组件基础单位
IF gs_tab-idnrk IS NOT INITIAL. " 不为空,正常获取
READ TABLE lt_mara_sub INTO DATA(ls_mara_sub) WITH KEY matnr = gs_tab-idnrk BINARY SEARCH.
IF sy-subrc = 0.
gs_tab-meins = ls_mara_sub-meins.
ENDIF.
ELSEIF gs_tab-idnrk IS INITIAL. " 为空,默认 PC
gs_tab-meins = 'ST'.
ENDIF.
MODIFY gt_tab FROM gs_tab.
CLEAR: gs_tab.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DISPLAY_ALV
*&---------------------------------------------------------------------*
*& 配置 ALV 样式,字段目录并展示 内表数据
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_display_alv .
*&--- 设置字段目录
PERFORM frm_build_fieldcat.
*&--- 设置布局属性
PERFORM frm_build_layout.
*&--- ALV 展示数据
PERFORM frm_build_alv.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_BUILD_FIELDCAT
*&---------------------------------------------------------------------*
*& 配置 ALV 字段目录
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_build_fieldcat .
CLEAR gt_fieldcat.
mcr_set_catalog: 'ICON ' TEXT-c01 '' '' '' , " 状态
'MESSAGE' TEXT-c02 '' '' '' , " 消息
'ZTYPE' TEXT-c34 '' '' '' , " 导入类型
'MATNR' TEXT-c03 '' 'MAST' 'MATNR' , " 产品编码
'MATNR_O' TEXT-c04 '' 'MAST' 'MATNR' , " 旧产品编码
'FMAKTX' TEXT-c05 '' 'MAKT' 'MAKTX' , " 产品描述
'WERKS' TEXT-c06 '' 'MAST' 'WERKS' , " 工厂代码
'STLAL' TEXT-c07 '' 'MAST' 'STLAL' , " 版本
'BMENG' TEXT-c08 '' 'STKO' 'BMENG' , " 基本数量
'POSNR' TEXT-c09 '' 'STPO' 'POSNR' , " 项目编号
'POSTP' TEXT-c10 '' 'STPO' 'POSTP' , " 项目类别
'IDNRK' TEXT-c11 '' 'STPO' 'IDNRK' , " 组件编码
'IDNRK_O' TEXT-c12 '' 'STPO' 'IDNRK' , " 旧组件编码
'SMAKTX' TEXT-c13 '' 'MAKT' 'MAKTX' , " 组件描述
'MENGE' TEXT-c14 '' 'STPO' 'MENGE' , " 组件用量
'KZKUP' TEXT-c15 '' 'STPO' 'KZKUP' , " 联产品
'AUSCH' TEXT-c18 '' 'STPO' 'AUSCH' , " 损耗率
'LGORT' TEXT-c16 '' 'STPO' 'LGORT' , " 发货库位
'STLBE' TEXT-c33 '' 'STZU' 'STLBE' . " 权限组
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_BUILD_LAYOUT
*&---------------------------------------------------------------------*
*& 配置 ALV 样式
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_build_layout .
CLEAR gs_layout.
gs_layout-sel_mode = 'A'. " 设置行模式
gs_layout-cwidth_opt = 'X'. " 优化列宽设置
gs_layout-zebra = 'X'. " 设置斑马线
gs_layout-box_fname = 'CHECK'. " 选择字段
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SELECT_INFILE
*&---------------------------------------------------------------------*
*& 获取上传文件路径
*&---------------------------------------------------------------------*
*& <-- P_FILE
*&---------------------------------------------------------------------*
FORM frm_select_infile CHANGING pv_file.
*&--- 定义传出文件名内表 和传出参数
DATA: lt_upfile TYPE filetable,
lv_rc TYPE i,
lv_window TYPE string,
lv_filefilter TYPE string,
lv_default TYPE string.
*&--- 默认值赋值
lv_window = TEXT-106. " 请选择本地文件
lv_filefilter = TEXT-107. " EXCEL文件 (*.xlsx)|*.xlsx|EXCEL文件 (*.xls)|*.xls|文本|*.txt|
lv_default = TEXT-108. " *.xlsx
*&--- 调用类方法
CALL METHOD cl_gui_frontend_services=>file_open_dialog
EXPORTING
window_title = lv_window " 请选择本地文件
file_filter = lv_filefilter " EXCEL文件 (*.xlsx)|*.xlsx|EXCEL文件 (*.xls)|*.xls|文本|*.txt|
default_filename = lv_default " *.xlsx
CHANGING
file_table = lt_upfile
rc = lv_rc.
*&--- 读取成功,赋值文件路径
IF sy-subrc = 0 AND lv_rc = 1.
READ TABLE lt_upfile INTO p_file INDEX 1.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DOWNLOAD_EXCEL
*&---------------------------------------------------------------------*
*& 下载模板文件
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_download_excel .
DATA: lv_name(128), lv_type(3), lv_size TYPE i.
DATA: lv_num TYPE i.
DATA: lv_user_act TYPE i. " 文件保存对话框,用户行为
DATA: lv_filename TYPE string, " 下载文件名
lv_wintitle TYPE string, " 下载对话框标题名
lv_filepath TYPE string, " 文件路径
lv_fullpath TYPE string, " 全文件路径
lv_file TYPE rlgrap-filename,
lv_title TYPE string,
lv_window TYPE string,
lv_filefilter TYPE string,
lv_xlsname TYPE wwwdatatab-objid VALUE 'ZPPB004', " 模板名称
lv_key TYPE wwwdatatab,
lv_subrc TYPE sy-subrc.
DATA: lv_def_file_name TYPE string. " 默认文件名
*&--- 默认值赋值
lv_def_file_name = TEXT-103. " BOM主数据批导模板.xls
lv_filefilter = TEXT-104. " EXCEL 文档|*.
lv_window = TEXT-105. " 请选择路径
*&--- 文件保存对话框,获得保存路径
CALL METHOD cl_gui_frontend_services=>file_save_dialog
EXPORTING
window_title = lv_window " 请选择路径
default_file_name = lv_def_file_name " 默认文件名
file_filter = lv_filefilter " 文件类型过滤(只显示本地文件夹)
CHANGING
filename = lv_filename " 保存的文件名
path = lv_filepath " 文件路径
fullpath = lv_fullpath " 全文件路径
user_action = lv_user_act
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE e011(zpp001). " 文件保存失败
RETURN.
ENDIF.
*&--- 取消下载
IF lv_user_act = '9'.
MESSAGE s001(zpp001). " 下载已取消
RETURN.
ENDIF.
lv_file = lv_fullpath.
lv_key-relid = 'MI'.
lv_key-objid = lv_xlsname. " SMW0 中对象 ID
*&--- 从 SAP 资源库中下载文件
CALL FUNCTION 'DOWNLOAD_WEB_OBJECT'
EXPORTING
key = lv_key
destination = lv_file
IMPORTING
rc = lv_subrc.
IF lv_subrc <> 0.
MESSAGE s003(zpp001) DISPLAY LIKE 'E'. " 模板下载失败,请上传模板
STOP.
ELSEIF lv_subrc = 0.
MESSAGE s012(zpp001). " 模板下载成功
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_UPLOAD_DATA
*&---------------------------------------------------------------------*
*& 上传数据
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_upload_data .
DATA: lv_filename LIKE rlgrap-filename, " 文件名
lt_raw TYPE truxs_t_text_data,
lv_path TYPE rlgrap-filename, " 路径
lt_line TYPE c VALUE 1,
lv_value(255) TYPE c.
IF p_file IS INITIAL.
MESSAGE s013(zpp001) DISPLAY LIKE 'E'. " 文件名不能为空
LEAVE LIST-PROCESSING.
ENDIF.
lv_path = p_file . " 赋值路径
REFRESH gt_xlstmp.
" 读取 EXCEL 文件数据
CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
EXPORTING
filename = lv_path " 路径
i_begin_col = 1
i_begin_row = 6 " 从第 4 行开始 读取
i_end_col = 20 " 结束列
i_end_row = 65536 " 结束行
TABLES
intern = gt_xlstmp " 存储读取的记录 行、列、值
EXCEPTIONS
inconsistent_parameters = 1
upload_ole = 2
OTHERS = 3.
IF sy-subrc <> 0 .
MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno DISPLAY LIKE sy-msgty
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
STOP.
ENDIF.
*&--- 将读取到的记录存储到 GT_DATA 内表中
CLEAR gt_excel.
SORT gt_xlstmp BY row col .
" 循环赋值
LOOP AT gt_xlstmp ASSIGNING .
ASSIGN COMPONENT -col OF STRUCTURE TO .
lv_value = -value .
CONDENSE lv_value.
gt_excel-znumb = -row.
CASE -col. " 判断当前列,并赋值到对应技术字段
WHEN 2.
gt_excel-matnr = lv_value.
WHEN 3.
gt_excel-matnr_o = lv_value.
WHEN 4.
gt_excel-fmaktx = lv_value.
WHEN 5.
gt_excel-werks = lv_value.
WHEN 6.
gt_excel-stlal = lv_value.
WHEN 7.
gt_excel-bmeng = lv_value.
WHEN 8.
gt_excel-posnr = lv_value.
WHEN 9.
gt_excel-postp = lv_value.
WHEN 10.
gt_excel-idnrk = lv_value.
WHEN 11.
gt_excel-idnrk_o = lv_value.
WHEN 12.
gt_excel-smaktx = lv_value.
WHEN 13.
gt_excel-menge = lv_value.
WHEN 14.
gt_excel-kzkup = lv_value.
WHEN 15.
gt_excel-ausch = lv_value.
WHEN 16.
gt_excel-lgort = lv_value.
WHEN 17.
gt_excel-stlbe = lv_value.
WHEN 18.
gt_excel-alpgr = lv_value.
WHEN 19.
gt_excel-ewahr = lv_value.
ENDCASE.
AT END OF row.
APPEND gt_excel.
CLEAR gt_excel.
ENDAT.
ENDLOOP.
IF gt_excel[] IS INITIAL.
MESSAGE s008(zpp001) DISPLAY LIKE 'E'. " 没有找到符合条件的数据
STOP.
ENDIF.
*&--- gt_excel 赋值给 gt_tab
CLEAR: gt_tab.
MOVE-CORRESPONDING gt_excel[] TO gt_tab.
LOOP AT gt_tab ASSIGNING FIELD-SYMBOL().
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
input = -matnr
IMPORTING
output = -matnr
EXCEPTIONS
length_error = 1
OTHERS = 2.
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
input = -idnrk
IMPORTING
output = -idnrk
EXCEPTIONS
length_error = 1
OTHERS = 2.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = -stlal
IMPORTING
output = -stlal.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CALL_BAPI
*&---------------------------------------------------------------------*
*& 调用对应 BAPI 导入
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_call_bapi .
*&--- BAPI 参数声明
DATA: lt_head TYPE TABLE OF ty_tab,
ls_head TYPE ty_tab,
lt_item TYPE TABLE OF ty_tab,
ls_item TYPE ty_tab,
lv_type,
lv_msg TYPE bapi_msg,
lv_matnr TYPE marc-matnr,
lv_stlal TYPE mast-stlal.
DATA: lt_bomg TYPE TABLE OF bapi1080_bgr_c,
ls_bomg TYPE bapi1080_bgr_c,
lt_var TYPE TABLE OF bapi1080_bom_c,
ls_var TYPE bapi1080_bom_c,
lt_matr TYPE TABLE OF bapi1080_mbm_c,
ls_matr TYPE bapi1080_mbm_c,
lt_items TYPE TABLE OF bapi1080_itm_c,
ls_items TYPE bapi1080_itm_c,
lt_itas TYPE TABLE OF bapi1080_rel_itm_bom_c,
ls_itas TYPE bapi1080_rel_itm_bom_c,
lt_ret TYPE TABLE OF bapiret2,
ls_ret TYPE bapiret2.
DATA: lv_lines TYPE sposn. " 行项值
*&--- 判断有误数据提示修改
LOOP AT gt_tab INTO gs_tab WHERE type NE 'S' AND check = abap_true .
MESSAGE e014(zpp001). " 请修改有误数据
ENDLOOP.
*&--- 有效数据赋值对应 抬头 & 行项
LOOP AT gt_tab INTO gs_tab WHERE check = abap_true.
APPEND gs_tab TO lt_head.
APPEND gs_tab TO lt_item.
ENDLOOP.
*&--- 抬头排序去重
SORT lt_head BY matnr werks stlan stlal.
DELETE ADJACENT DUPLICATES FROM lt_head COMPARING matnr werks stlan stlal.
LOOP AT lt_head INTO ls_head WHERE check = abap_true.
CLEAR: lt_bomg ,
ls_bomg ,
lt_var ,
ls_var ,
lt_matr ,
ls_matr ,
lt_items ,
ls_items ,
lt_itas ,
ls_itas ,
lt_ret ,
ls_ret ,
lv_type ,
lv_msg ,
lv_matnr ,
lv_stlal ,
lv_lines .
*&--- 补前导零
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
input = ls_head-matnr
IMPORTING
output = lv_matnr.
*&--- 补前导零
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = ls_head-stlal
IMPORTING
output = lv_stlal.
*&--- 检验同 备选 BOM 是否已存在,如果存在,则删除(实现覆盖)
SELECT mast~matnr,
mast~werks,
mast~stlan,
mast~stlal
INTO TABLE @DATA(lt_mast)
FROM mast
WHERE matnr = @lv_matnr
AND werks = @ls_head-werks
AND stlan = @ls_head-stlan
AND stlal = @lv_stlal.
IF lt_mast IS NOT INITIAL.
" 存在,即删除 BOM
CALL FUNCTION 'CSAP_MAT_BOM_DELETE'
EXPORTING
material = ls_head-matnr
plant = ls_head-werks
bom_usage = ls_head-stlan
alternative = ls_head-stlal
fl_no_change_doc = 'X'
fl_commit_and_wait = 'X'
EXCEPTIONS
error = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno DISPLAY LIKE sy-msgty
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDIF.
CLEAR ls_bomg.
ls_bomg-bom_group_identification = 'BAPI_SMP_COL1'. " 标识物料单组
ls_bomg-object_type = 'BGR'. " BOM 组中对象标识
ls_bomg-object_id = 'SIMPLE1'. " BOM 组中对象标识
ls_bomg-bom_usage = ls_head-stlan. " BOM 用途
ls_bomg-ltxt_lang = sy-langu. " 语言
ls_bomg-created_in_plant = ls_head-werks. " 工厂
ls_bomg-auth_group = ls_head-stlbe. " 权限组
APPEND ls_bomg TO lt_bomg.
CLEAR ls_var.
ls_var-bom_group_identification = 'BAPI_SMP_COL1'.
ls_var-object_type = 'BOM'.
ls_var-object_id = 'SIMPLE1'.
ls_var-alternative_bom = lv_stlal. " 可选BOM
* LS_var-bom_status = '01'. " BOM状态
ls_var-base_qty = ls_head-bmeng. " 数量
ls_var-base_unit = ls_head-bmein. " 计量单位
ls_var-valid_from_date = sy-datum. " 有效期起始日期
* ls_var-change_no = ls_head-aennr. " ECN
ls_var-function = 'NEW'.
* ls_var-alt_text = ls_head-stktx. " BOM 表头备注
APPEND ls_var TO lt_var.
CLEAR ls_matr.
ls_matr-bom_group_identification = 'BAPI_SMP_COL1'.
ls_matr-material = lv_matnr. " 物料编码
ls_matr-plant = ls_head-werks. " 工厂
ls_matr-bom_usage = ls_head-stlan. " BOM 用途
ls_matr-alternative_bom = lv_stlal. " 可选 BOM
APPEND ls_matr TO lt_matr.
*&--- 循环行项转码&赋值
LOOP AT lt_item INTO ls_item WHERE matnr = ls_head-matnr AND
werks = ls_head-werks AND
stlan = ls_head-stlan AND
stlal = ls_head-stlal .
CLEAR ls_items.
lv_lines += 10.
ls_item-posnr = lv_lines.
CALL FUNCTION 'CONVERSION_EXIT_NUMCV_INPUT'
EXPORTING
input = ls_item-posnr
IMPORTING
output = ls_item-posnr.
ls_items-bom_group_identification = 'BAPI_SMP_COL1'.
ls_items-object_type = 'ITM'.
ls_items-object_id = 'SIMPLE1'.
ls_items-item_no = ls_item-posnr. " 行号
ls_items-item_cat = 'L'. " 类别
IF ls_item-postp IS NOT INITIAL.
ls_items-item_cat = ls_item-postp. " 类别
ENDIF.
*&--- 转码
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
input = ls_item-idnrk
IMPORTING
output = ls_items-component.
ls_items-component = ls_item-idnrk. " 组件物料
ls_items-comp_qty = ls_item-menge. " 组件数量 (BTCI)
*&--- 行项目赋值
ls_items-comp_unit = ls_item-meins. " 组件计量单位
ls_items-comp_scrap = ls_item-ausch .
ls_items-ltxt_lang = sy-langu.
ls_items-valid_from_date = sy-datum. " 有效起始日期
ls_items-cost_rel = 'X'. " 与成本相关
ls_items-iss_st_loc = ls_item-lgort. " 库存地点
ls_items-co_product = ls_item-kzkup. " 联产品
ls_items-alt_item_group = ls_item-alpgr. " 替代组
SELECT COUNT( * ) FROM marc WHERE matnr EQ @ls_item-idnrk AND werks EQ @ls_head-werks
"AND disgr EQ 'ZP01'.
AND sbdkz EQ '1' OR sbdkz IS INITIAL.
IF sy-subrc EQ 0.
ls_items-expl_type = 'D1'. " 展开类型
ENDIF.
IF ls_item-alpgr IS NOT INITIAL.
ls_items-alt_item_strategy = '2'. " 策略
ENDIF.
ls_items-usage_prob = ls_item-ewahr. " 使用概率
APPEND ls_items TO lt_items.
ENDLOOP.
CLEAR ls_itas.
ls_itas-bom_group_identification = 'BAPI_SMP_COL1'.
ls_itas-sub_object_type = 'ITM'.
ls_itas-sub_object_id = 'SIMPLE1'.
ls_itas-super_object_type = 'BOM'.
ls_itas-super_object_id = 'SIMPLE1'.
ls_itas-valid_from_date = sy-datum.
ls_itas-function = 'NEW'.
APPEND ls_itas TO lt_itas.
*&--- 创建物料 BOM
CALL FUNCTION 'BAPI_MATERIAL_BOM_GROUP_CREATE'
EXPORTING
all_error = 'X'
TABLES
bomgroup = lt_bomg
variants = lt_var
items = lt_items
materialrelations = lt_matr
itemassignments = lt_itas
return = lt_ret.
CLEAR lv_msg.
READ TABLE lt_ret INTO ls_ret WITH KEY type = 'E'.
IF sy-subrc = 0.
*&--- 回滚
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
LOOP AT lt_ret INTO ls_ret .
lv_msg = lv_msg && TEXT-112 && ls_ret-message.
ENDLOOP.
ls_head-type = 'E'.
ls_head-message = lv_msg+1.
ELSE.
*&--- 提交事务操作
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
READ TABLE lt_ret INTO ls_ret WITH KEY type = 'W'.
IF ls_ret IS NOT INITIAL. " 提示警告信息
ls_head-type = 'W'.
LOOP AT lt_ret INTO ls_ret .
lv_msg = lv_msg && TEXT-112 && ls_ret-message.
ENDLOOP.
ls_head-message = lv_msg+1.
ELSE.
ls_head-type = 'S'.
ls_head-message = TEXT-121. " 创建成功
ENDIF.
ENDIF.
MODIFY lt_head FROM ls_head.
ENDLOOP.
*&--- 循环内表判断消息类型
LOOP AT lt_head INTO ls_head.
LOOP AT gt_tab INTO gs_tab WHERE matnr = ls_head-matnr AND
werks = ls_head-werks AND
stlan = ls_head-stlan AND
stlal = ls_head-stlal AND
check = abap_true.
gs_tab-type = ls_head-type.
gs_tab-message = ls_head-message.
*&--- 根据消息类型修改指示灯
IF gs_tab-type = 'E'.
gs_tab-icon = '@0A@'. " 红灯
ELSE.
gs_tab-icon = '@08@'. " 绿灯
ENDIF.
MODIFY gt_tab FROM gs_tab.
ENDLOOP.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_build_alv
*&---------------------------------------------------------------------*
*& ALV 展示导入数据
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_build_alv .
*&--- ALV 展示导入数据
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid " 当前程序
i_callback_pf_status_set = 'FRM_SET_PF_STATUS'
i_callback_user_command = 'FRM_USR_COMMAND'
is_layout_lvc = gs_layout " 界面格式
it_fieldcat_lvc = gt_fieldcat " 字段属性
TABLES
t_outtab = gt_tab
EXCEPTIONS
program_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno DISPLAY LIKE sy-msgty
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDFORM.
导入EXCEL模板: