1. 前言
- ZALSM_EXCEL_TO_INTERNAL_TABLE 函数实现方法参考文章:读取EXCEL数据到SAP函数重新封装为ZALSM_EXCEL_TO_INTERNAL_TABLE(解决单元格至多上传50字符 单次至多上传9999行 只能读取单个SHEET)
- 相对于 BAPI_MATERIAL_MAINTAINDATA_RT WRF_MATERIAL_MAINTAINDATA_RT 可以实现更多的物料主数据的导入
- 供应商层级的GTIN(条码导入)
- 门店数据的列表执行清单(Execute Listing)
- 采购信息记录PIR的导入(包括货源清单)
- 供应商层级的GTIN(条码导入)
- BOM组件信息等等
2. 实现
-
导入模板
- 基本数据
- 附加数据
- 基本数据
-
代码
TYPE-POOLS: truxs. TABLES: ztmm_sfzs,sscrfields. *----------------------------------------------------------------------* * CLASS lcl_events DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_events DEFINITION. PUBLIC SECTION. METHODS: on_user_command "定义设置SALV on_user_command属性的方法 FOR EVENT added_function OF cl_salv_events_table IMPORTING e_salv_function. METHODS: on_double_click FOR EVENT double_click OF cl_salv_events_table IMPORTING row column. ENDCLASS. "lcl_events DEFINITION *----------------------------------------------------------------------* * CLASS lcl_events IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_events IMPLEMENTATION. METHOD on_user_command. PERFORM frm_on_user_command USING e_salv_function. ENDMETHOD. "on_user_command METHOD on_double_click. PERFORM frm_double_click USING row column. ENDMETHOD. "on_user_command ENDCLASS. "lcl_events IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_excel_uploader DEFINITION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_excel_uploader DEFINITION. PUBLIC SECTION. DATA: header_rows_count TYPE i. DATA: max_rows TYPE i. DATA: filename TYPE localfile. DATA: sheet_name TYPE alsmex_tabline-value. METHODS: constructor. METHODS: upload CHANGING ct_data TYPE ANY TABLE. PRIVATE SECTION. DATA: lv_tot_components TYPE i. METHODS: do_upload IMPORTING iv_begin TYPE i iv_end TYPE i EXPORTING rv_empty TYPE flag CHANGING ct_data TYPE STANDARD TABLE. ENDCLASS. "lcl_excel_uploader DEFINITION *----------------------------------------------------------------------* * CLASS lcl_excel_uploader IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS lcl_excel_uploader IMPLEMENTATION. METHOD constructor. max_rows = 9999. ENDMETHOD. "constructor METHOD upload. DATA: lo_struct TYPE REF TO cl_abap_structdescr, lo_table TYPE REF TO cl_abap_tabledescr, lt_comp TYPE cl_abap_structdescr=>component_table. lo_table ?= cl_abap_structdescr=>describe_by_data( ct_data ). lo_struct ?= lo_table->get_table_line_type( ). lt_comp = lo_struct->get_components( ). * lv_tot_components = lines( lt_comp ). * DATA: lv_empty TYPE flag, lv_begin TYPE i, lv_end TYPE i. * lv_begin = header_rows_count + 1. lv_end = max_rows. WHILE lv_empty IS INITIAL. do_upload( EXPORTING iv_begin = lv_begin iv_end = lv_end IMPORTING rv_empty = lv_empty CHANGING ct_data = ct_data ). lv_begin = lv_end + 1. lv_end = lv_begin + max_rows. ENDWHILE. ENDMETHOD. "upload * METHOD do_upload. DATA: li_exceldata TYPE STANDARD TABLE OF zalsmex_tabline. DATA: ls_exceldata LIKE LINE OF li_exceldata. DATA: lv_tot_rows TYPE i. DATA: lv_packet TYPE i. FIELD-SYMBOLS: <struc> TYPE any, <field> TYPE any. * Upload this packet CALL FUNCTION 'ZALSM_EXCEL_TO_INTERNAL_TABLE' EXPORTING filename = filename i_begin_col = 1 i_begin_row = iv_begin i_end_col = lv_tot_components i_end_row = iv_end i_sheet_name = sheet_name TABLES intern = li_exceldata EXCEPTIONS inconsistent_parameters = 1 upload_ole = 2 OTHERS = 3. * something wrong, exit IF sy-subrc NE 0. MESSAGE '导入文件失败,请检查文件是否存在未被锁定!' TYPE 'S' DISPLAY LIKE 'E'. LEAVE LIST-PROCESSING. rv_empty = 'X'. ENDIF. * No rows uploaded, exit IF li_exceldata IS INITIAL AND sheet_name = '基本-物料主数据'. MESSAGE '模板为空,请检查模板!' TYPE 'S' DISPLAY LIKE 'E'. LEAVE LIST-PROCESSING. rv_empty = 'X'. ENDIF. * Move from Row, Col to Flat Structure LOOP AT li_exceldata INTO ls_exceldata. " Append new row AT NEW row. APPEND INITIAL LINE TO ct_data ASSIGNING <struc>. ENDAT. " component and its value ASSIGN COMPONENT ls_exceldata-col OF STRUCTURE <struc> TO <field>. IF sy-subrc EQ 0. <field> = ls_exceldata-value. ENDIF. " add the row count AT END OF row. IF <struc> IS NOT INITIAL. lv_tot_rows = lv_tot_rows + 1. ENDIF. ENDAT. ENDLOOP. * packet has more rows than uploaded rows, * no more packet left. Thus exit lv_packet = iv_end - iv_begin. IF lv_tot_rows LT lv_packet. rv_empty = 'X'. ENDIF. ENDMETHOD. "do_upload ENDCLASS. "lcl_excel_uploader IMPLEMENTATION TYPES: BEGIN OF ty_mian_upload, zsort TYPE string, "编码 matnr TYPE string, "物料编号 maktx TYPE string, "物料描述 mtart TYPE string, "商品类型 matkl TYPE string, "物料组 attyp TYPE string, "商品类别 zconv_unit TYPE string, "是否单位转换 meins TYPE string, "基本单位 umrez TYPE string, "比值 bstme TYPE string, "采购单位 zconv_cd TYPE string, "是否列出XX zconv_xm TYPE string, "是否列出XX zconv_fz TYPE string, "是否列出XX mhdhb TYPE string, "总货架寿命 zconv_deli TYPE string, "是否配货单位(用于标识现裱 /现烤) sobsl TYPE string, "特殊采购类 bklas TYPE string, "评估类 stprs TYPE string, "标准价 END OF ty_mian_upload. TYPES: BEGIN OF ty_pur_upload, zsort TYPE string, "编码 lifnr TYPE string, "供应商 werks TYPE string, "工厂 mwskz TYPE string, "税代码 netpr TYPE string, "净价 ean11 TYPE string, "GTIN END OF ty_pur_upload. TYPES: BEGIN OF ty_logistics_alv, zsort TYPE string, "编码 werks TYPE marc-werks, "工厂 dismm TYPE marc-dismm, "RP类型 disls TYPE marc-disls, "批量大小 bstrf TYPE marc-bstrf, "舍入值 dispo TYPE marc-dispo, "存货计划员/RP控制器 xchpf TYPE marc-xchpf, "批次管理 lgfsb TYPE marc-lgfsb, "库存地点/外部采购仓储地点 zmein TYPE marc-zmein, "是否配货单位(用于标识现裱 /现烤) beskz TYPE marc-beskz, "采购类型 sobsl TYPE marc-sobsl, "特殊采购类 rgekz TYPE marc-rgekz, "反冲 lgpro TYPE marc-lgpro, "生产仓储地点 webaz TYPE marc-webaz, "收货处理时间 fhori TYPE marc-fhori, "计划边际码 strgr TYPE marc-strgr, "策略组 vrmod TYPE marc-vrmod, "消耗模式 vint1 TYPE marc-vint1, "向前消耗期间 vint2 TYPE marc-vint2, "逆向消耗期间 mtvfp TYPE marc-mtvfp, "可用性检查 sbdkz TYPE marc-sbdkz, "独立/集中 fevor TYPE marc-fevor, "生产管理员 sfcpf TYPE marc-sfcpf, "生产计划参数文件 frtme TYPE marc-frtme, "生产单位 uneto TYPE marc-uneto, "不足交货允差 ueeto TYPE marc-ueeto, "过度交货允差 END OF ty_logistics_alv. TYPES: BEGIN OF ty_main_alv, icon TYPE char4, "指示 text TYPE string, "提示文本 zsort TYPE char30, "编码 matnr TYPE mara-matnr, "物料编号 mtart TYPE mara-mtart, "商品类型 matkl TYPE mara-matkl, "物料组 attyp TYPE mara-attyp, "商品类别 zconv_unit TYPE char1, "是否单位转换 maktx TYPE makt-maktx, "物料描述 meins TYPE mara-meins, "基本单位 umrez TYPE marm-umrez, "比值 bstme TYPE mara-bstme, "采购单位 taklv TYPE mara-taklv, "税收分类 mhdrz TYPE mara-mhdrz, "剩余货架寿命 mhdhb TYPE mara-mhdhb, "总货架寿命 zconv_cd TYPE char1, "是否列出XX zconv_xm TYPE char1, "是否列出XX zconv_fz TYPE char1, "是否列出XX mtpos TYPE mvke-mtpos, "项目类别组 kondm TYPE mvke-kondm, "物料定价组 ktgrm TYPE mvke-ktgrm, "科目设置组 lstfl TYPE mvke-lstfl, "列表-存储 lstvz TYPE mvke-lstvz, "列表-分销中心 zconv_deli TYPE char1, "是否配货单位(用于标识现裱 /现烤) sobsl TYPE marc-sobsl, "特殊采购类 bklas TYPE mbew-bklas, "评估类 peinh TYPE mbew-peinh, "价格单位 stprs TYPE mbew-stprs, "标准价 zconv_pur TYPE char1, "是否扩充采购组织 z_conv_sales TYPE char200,"扩充信息显示 vkorg TYPE mvke-vkorg, "销售组织 vtweg TYPE mvke-vtweg, "分销渠道 END OF ty_main_alv. TYPES: BEGIN OF ty_pur_alv, zsort TYPE char30, "编码 lifnr TYPE eina-lifnr, "供应商 ekorg TYPE eine-ekorg, "采购组织 werks TYPE eine-werks, "工厂 ekgrp TYPE eine-ekgrp, "采购组 mwskz TYPE eine-mwskz, "税代码 netpr TYPE eine-netpr, "净价 waers TYPE eine-waers, " 货币码 peinh TYPE eine-peinh, " 价格单位 bprme TYPE eine-bprme, "订单价格单位(采购) ean11 TYPE mean-ean11, "GTIN hpean TYPE mean-hpean, "主 GTIN lartn TYPE mlea-lartn, "是否分配GTIN到当前供应商 lfean TYPE mlea-lfean, "供应商的主GTIN numtp TYPE numtp, "GTIN类型 END OF ty_pur_alv. DATA: go_alv TYPE REF TO cl_salv_table. TYPES: ty_main_t TYPE TABLE OF ty_main_alv WITH KEY zsort, ty_pur_t TYPE TABLE OF ty_pur_alv WITH KEY zsort. DATA: gt_outmain TYPE ty_main_t, gt_outpur TYPE ty_pur_t, gt_logistics_alv TYPE TABLE OF ty_logistics_alv. DATA: gs_text TYPE smp_dyntxt. SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE l_title1. PARAMETERS : p_file TYPE string OBLIGATORY MODIF ID m1. SELECTION-SCREEN END OF BLOCK b1. SELECTION-SCREEN FUNCTION KEY 1. INITIALIZATION. PERFORM frm_init_funckey. p_file = 'C:\' && text-t01 && '.XLS'. l_title1 = '选择文件'. AT SELECTION-SCREEN OUTPUT. AT SELECTION-SCREEN. IF sscrfields-ucomm = 'FC01'. PERFORM frm_download_template. ENDIF. AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file. PERFORM frm_f4_request. START-OF-SELECTION. PERFORM frm_read_excel. END-OF-SELECTION. PERFORM frm_show_alv. *&---------------------------------------------------------------------* *& Form FRM_F4_REQUEST *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM frm_f4_request . DATA: lv_rc TYPE i. DATA: lt_file_table TYPE filetable, wa_file_table TYPE file_table. CALL METHOD cl_gui_frontend_services=>file_open_dialog EXPORTING window_title = '打开文件' CHANGING file_table = lt_file_table rc = lv_rc. IF sy-subrc = 0. READ TABLE lt_file_table INTO wa_file_table INDEX 1. p_file = wa_file_table-filename. ENDIF. ENDFORM. " FRM_F4_REQUEST *&---------------------------------------------------------------------* *& Form FRM_READ_EXCEL *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM frm_read_excel. DATA: lt_main_upload TYPE TABLE OF ty_mian_upload, wa_main_upload TYPE ty_mian_upload, lt_pur_upload TYPE TABLE OF ty_pur_upload, wa_pur_upload TYPE ty_pur_upload. DATA: l_main_comp TYPE i, l_pur_comp TYPE i. DATA: lo_struct TYPE REF TO cl_abap_structdescr, lo_table TYPE REF TO cl_abap_tabledescr, lt_comp TYPE cl_abap_structdescr=>component_table. DATA: lo_uploader TYPE REF TO lcl_excel_uploader. TYPES: BEGIN OF ty_logrt, lgort TYPE t001l-lgort, END OF ty_logrt. DATA: lt_t023 TYPE TABLE OF t023, "物料组 lt_t006 TYPE TABLE OF t006, "单位 lt_t001l TYPE TABLE OF ty_logrt, "库存地点 lt_lfa1 TYPE TABLE OF lfa1, "供应商 lt_kna1 TYPE TABLE OF kna1. "客户 DATA: wa_main_alv TYPE ty_main_alv, wa_outpur TYPE ty_pur_alv. DATA: l_continue_flag TYPE string. DATA: lt_ean_type TYPE TABLE OF typeinterv, wa_ean_type TYPE typeinterv. DATA: l_matnr TYPE mara-matnr. "get components numbers(RTTS) lo_table ?= cl_abap_structdescr=>describe_by_data( lt_main_upload ). "Main lo_struct ?= lo_table->get_table_line_type( ). lt_comp = lo_struct->get_components( ). l_main_comp = lines( lt_comp ). lo_table ?= cl_abap_structdescr=>describe_by_data( lt_pur_upload ). "Purchase lo_struct ?= lo_table->get_table_line_type( ). lt_comp = lo_struct->get_components( ). l_pur_comp = lines( lt_comp ). "read excel data CREATE OBJECT lo_uploader. lo_uploader->max_rows = 1000. "设置读取最大行,默认9999 lo_uploader->filename = p_file. lo_uploader->header_rows_count = 3. "Main lo_uploader->sheet_name = '基本-物料主数据'. lo_uploader->upload( CHANGING ct_data = lt_main_upload ). IF sy-subrc NE 0. MESSAGE '读取数据失败,请检查模板!' TYPE 'E'. ENDIF. "Purchase lo_uploader->sheet_name = '附加-采购视图数据'. lo_uploader->upload( CHANGING ct_data = lt_pur_upload ). IF sy-subrc NE 0. MESSAGE '读取数据失败,请检查模板!' TYPE 'E'. ENDIF. SORT lt_main_upload BY zsort ASCENDING. SORT lt_pur_upload BY zsort lifnr ASCENDING ean11 DESCENDING. "loading check data SELECT * FROM t023 INTO TABLE lt_t023 ORDER BY matkl ASCENDING. SELECT * FROM t006 INTO TABLE lt_t006 ORDER BY msehi ASCENDING. SELECT DISTINCT lgort FROM t001l INTO TABLE lt_t001l ORDER BY lgort ASCENDING. SELECT * FROM lfa1 INTO TABLE lt_lfa1 ORDER BY lifnr ASCENDING. SELECT * FROM kna1 INTO TABLE lt_kna1 ORDER BY kunnr ASCENDING. "处理导入的数据并且赋默认值 LOOP AT lt_main_upload INTO wa_main_upload. CLEAR: wa_main_alv. "condensed all field PERFORM frm_condensed_allfield USING l_main_comp CHANGING wa_main_upload. "检查序列码 IF strlen( wa_main_upload-zsort ) NE 5 OR wa_main_upload-zsort+0(1) NE 'A'. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '排序编码不符合规范!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ELSE. wa_main_alv-zsort = wa_main_upload-zsort. ENDIF. "检查商品类型 IF wa_main_upload-mtart NE 'Z001' AND wa_main_upload-mtart NE 'Z002' AND wa_main_upload-mtart NE 'Z003' AND wa_main_upload-mtart NE 'Z005' AND wa_main_upload-mtart NE 'Z007' AND wa_main_upload-mtart NE 'Z008'. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '商品类型仅允许输入Z001/Z002/Z003/Z005/Z007/Z008!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ELSE. wa_main_alv-mtart = wa_main_upload-mtart. ENDIF. "检查物料编码 CASE wa_main_alv-mtart. WHEN 'Z001' OR 'Z002'. "Z001/Z002 WHEN OTHERS. "Z003/Z005/Z007/Z008 IF wa_main_upload-matnr IS INITIAL. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '物料编码必输!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ENDIF. ENDCASE. wa_main_alv-matnr = wa_main_upload-matnr. CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT' EXPORTING input = wa_main_alv-matnr IMPORTING output = wa_main_alv-matnr. "检查物料组 READ TABLE lt_t023 TRANSPORTING NO FIELDS WITH KEY matkl = wa_main_upload-matkl BINARY SEARCH. IF sy-subrc = 0. wa_main_alv-matkl = wa_main_upload-matkl. ELSE. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '物料组在SAP中不存在!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ENDIF. CASE wa_main_alv-mtart. WHEN 'Z001'. IF wa_main_upload-matkl+0(1) NE '1'. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '物料组只允许1*!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ENDIF. WHEN 'Z002'. IF wa_main_upload-matkl+0(1) NE '2'. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '物料组只允许2*!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ENDIF. WHEN 'Z003'. IF wa_main_upload-matkl+0(1) NE '4'. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '物料组只允许4*!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ENDIF. WHEN 'Z005'. IF wa_main_upload-matkl+0(1) NE '7'. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '物料组只允许5*!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ENDIF. WHEN 'Z007'. IF wa_main_upload-matkl+0(1) NE '3'. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '物料组只允许7*!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ENDIF. WHEN 'Z008'. IF wa_main_upload-matkl+0(1) NE '6'. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '物料组只允许6*!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ENDIF. ENDCASE. "检查商品类别 IF wa_main_upload-attyp NE '00' AND wa_main_upload-attyp NE '10'. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '商品类别仅允许输入00/10!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ELSE. wa_main_alv-attyp = wa_main_upload-attyp. ENDIF. "检查是否转换单位 IF wa_main_upload-zconv_unit IS NOT INITIAL AND wa_main_upload-zconv_unit NE 'X'. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '是否单位转换仅允许输入空或X!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ELSEIF wa_main_upload-zconv_unit IS NOT INITIAL. wa_main_alv-zconv_unit = wa_main_upload-zconv_unit. ENDIF. "物料描述 IF wa_main_upload-maktx IS INITIAL. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '物料描述必输!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ELSE. wa_main_alv-maktx = wa_main_upload-maktx. ENDIF. "基本单位 READ TABLE lt_t006 TRANSPORTING NO FIELDS WITH KEY msehi = wa_main_upload-meins BINARY SEARCH. IF sy-subrc NE 0. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '基本单位在SPA中不存在!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ELSE. wa_main_alv-meins = wa_main_upload-meins. ENDIF. "比值 & 采购单位 IF wa_main_alv-zconv_unit = 'X'. IF wa_main_upload-umrez IS INITIAL OR wa_main_upload-bstme IS INITIAL. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '比值/采购单位必输!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ENDIF. IF zcl_common_tools=>check_valid_number( wa_main_upload-umrez ) = abap_false. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '比值只能输入数字!' CHANGING wa_main_alv . "1.是否错误 2.消息文本 CONTINUE. ENDIF. READ TABLE lt_t006 TRANSPORTING NO FIELDS WITH KEY msehi = wa_main_upload-bstme BINARY SEARCH. IF sy-subrc NE 0. PERFORM frm_fill_outtab TABLES gt_outmain USING 'X' '采购单位在SPA中不存在!' CHANGING wa_main_alv . "1.是否错误