一、导入模板
二、结果
三、源代码
*&---------------------------------------------------------------------*
*& Program ID : ZMM_PO_CREATE
*& Description: EXCEL批导创建采购订单
*&---------------------------------------------------------------------*
*& Created by : Mitchell Wang Date: 2019/09/17 Ver: 01.0
*&---------------------------------------------------------------------*
*& Modified by: author Date: YYYY/MM/DD Ver: 02.0
*& … Description of modification …
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZMM_PO_CREATE .
TYPE-POOLS:SLIS,ICON.
" 定义类型
TYPES:BEGIN OF TP_EXCEL_DATA,
LIFNR TYPE EKKO-LIFNR, " 供应商帐号
EKORG TYPE EKKO-EKORG, " 采购组织
EKGRP TYPE EKKO-EKGRP, " 采购组
BUKRS TYPE EKKO-BUKRS, " 公司代码
KNTTP TYPE CHAR1, " 账户分配类别(科目设置类型)
MATNR TYPE EKPO-MATNR, " 物料
MENGE TYPE EKPO-MENGE, " 数量
LGORT TYPE EKPO-LGORT, " 仓储地点
WERKS TYPE EKPO-WERKS, " 工厂
DELIVERY_DATE TYPE CHAR10, " 交货日期
VBELN TYPE VBAP-VBELN, " 销售订单号
POSNR TYPE VBAP-POSNR, " 销售订单行项目
ZZVKORG TYPE CHAR4, " 销售组织
ZZKUNNR TYPE CHAR10, " 客户
ZZAUART TYPE CHAR4, " 销售凭证类型
END OF TP_EXCEL_DATA.
TYPES:BEGIN OF TP_ALV,
PO_ITEM(5) TYPE N, " 行号
LIFNR TYPE EKKO-LIFNR, " 供应商帐号
EKORG TYPE EKKO-EKORG, " 采购组织
EKGRP TYPE EKKO-EKGRP, " 采购组
BUKRS TYPE EKKO-BUKRS, " 公司代码
KNTTP TYPE CHAR1, " 账户配类别(科目设置类型)
MATNR TYPE EKPO-MATNR, " 物料
MENGE TYPE EKPO-MENGE, " 数量
LGORT TYPE EKPO-LGORT, " 仓储地点
WERKS TYPE EKPO-WERKS, " 工厂
DELIVERY_DATE TYPE CHAR10, " 交货日期
VBELN TYPE VBAP-VBELN, " 销售订单号
POSNR TYPE VBAP-POSNR, " 销售订单行项目
ZZVKORG TYPE CHAR4, " 销售组织
ZZKUNNR TYPE CHAR10, " 客户
ZZNAME1 TYPE CHAR35, " 名称
ZZAUART TYPE CHAR4, " 销售凭证类型
EBELN TYPE EKKO-EBELN, " 采购凭证号
MSGTY TYPE CHAR1, " 消息类型
MSGTXT TYPE CHAR255, " 消息内容
END OF TP_ALV.
TYPES: T_FILE_ALV TYPE STANDARD TABLE OF TP_ALV.
TYPES: W_FILE_ALV TYPE TP_ALV.
*&---------------------------------------------------------------------*
*& Declare GL Internal Table AND Structure
*&---------------------------------------------------------------------*
DATA:T_EXCEL_DATA TYPE TABLE OF TP_EXCEL_DATA ,
W_EXCEL_DATA TYPE TP_EXCEL_DATA .
DATA:T_ALV TYPE TABLE OF TP_ALV ,
W_ALV TYPE TP_ALV .
*&---------------------------------------------------------------------*
*& Constants:
*&---------------------------------------------------------------------*
CONSTANTS:C_TAGX VALUE 'X'.
*----------------------Selection-Screen--------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK B01 WITH FRAME TITLE TEXT-P01.
PARAMETERS:P_FILE TYPE RLGRAP-FILENAME. " 文件地址
SELECTION-SCREEN END OF BLOCK B01.
*======================================================================*
* Report Events
*======================================================================*
INITIALIZATION.
*======================================================================*
* AT SELECTION-SCREEN *
*======================================================================*
AT SELECTION-SCREEN OUTPUT. " pbo
*** Prepare Report Data
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FILE.
PERFORM FRM_OPEN_DIALOG."调用选择文件函数"
AT SELECTION-SCREEN.
"检查屏幕
PERFORM FRM_SCREEN_CHECK.
START-OF-SELECTION.
* 上载文件
PERFORM FRM_UPLOAD_FILE.
* 获取数据
PERFORM FRM_GET_DATA.
END-OF-SELECTION.
* 数据展示
PERFORM FRM_DISPLAY_DATA.
*&---------------------------------------------------------------------*
*& Form FRM_OPEN_DIALOG
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM FRM_OPEN_DIALOG .
DATA:LT_FILE_TABLE TYPE FILETABLE.
DATA:LW_FILE_TABLE TYPE FILE_TABLE .
DATA:LV_RC TYPE I.
DATA:LV_TITLE TYPE STRING .
LV_TITLE = '文件选择'.
CALL METHOD CL_GUI_FRONTEND_SERVICES=>FILE_OPEN_DIALOG
EXPORTING
WINDOW_TITLE = LV_TITLE
DEFAULT_FILENAME = '*.XLSX' " 默认excel文件"
INITIAL_DIRECTORY = '' " 默认打开D盘,也可以默认空"D:\
MULTISELECTION = '' " 文件单选
CHANGING
FILE_TABLE = LT_FILE_TABLE
RC = LV_RC
EXCEPTIONS
FILE_OPEN_DIALOG_FAILED = 1
CNTL_ERROR = 2
ERROR_NO_GUI = 3
NOT_SUPPORTED_BY_GUI = 4
OTHERS = 5.
IF LV_RC EQ 1."因为文件单选,所以这里判断一下选择的数量为1"
READ TABLE LT_FILE_TABLE INDEX 1 INTO P_FILE.
ENDIF.
ENDFORM. "FRM_OPEN_DIALOG
*&---------------------------------------------------------------------*
*& Form FRM_SCREEN_CHECK
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM FRM_SCREEN_CHECK .
*& 选择文件地址为空检查
IF P_FILE IS INITIAL.
MESSAGE E000(ZMM001).
ENDIF.
ENDFORM. "FRM_SCREEN_CHECK
*&---------------------------------------------------------------------*
*& Form FRM_UPLOAD_FILE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM FRM_UPLOAD_FILE .
TYPES TRUXS_T_TEXT_DATA(4096) TYPE C OCCURS 0.
DATA:LV_RAW TYPE TRUXS_T_TEXT_DATA.
CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
EXPORTING
I_LINE_HEADER = 'X' " 文本中的第一行是否是标题头,如果是则不会读取
I_TAB_RAW_DATA = LV_RAW " 该参数实际上没有使用到,但为必输参数
I_FILENAME = P_FILE
TABLES
I_TAB_CONVERTED_DATA = T_EXCEL_DATA
EXCEPTIONS
CONVERSION_FAILED = 1
OTHERS = 2.
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
ENDFORM. "FRM_UPLOAD_FILE
*&---------------------------------------------------------------------*
*& Form FRM_GET_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM FRM_GET_DATA .
DATA: LV_PO_ITEM(5) TYPE N.
DATA:LV_KUNNR TYPE CHAR10.
SORT T_EXCEL_DATA BY LIFNR.
LOOP AT T_EXCEL_DATA INTO W_EXCEL_DATA.
LV_PO_ITEM = LV_PO_ITEM + 10.
MOVE-CORRESPONDING W_EXCEL_DATA TO W_ALV.
LV_KUNNR = W_ALV-ZZKUNNR.
* 补前导0
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
INPUT = LV_KUNNR
IMPORTING
OUTPUT = LV_KUNNR.
SELECT SINGLE NAME1 INTO W_ALV-ZZNAME1
FROM KNA1
WHERE KUNNR = LV_KUNNR.
W_ALV-PO_ITEM = LV_PO_ITEM.
APPEND W_ALV TO T_ALV.
CLEAR:W_ALV,W_EXCEL_DATA.
AT END OF LIFNR.
CLEAR LV_PO_ITEM.
ENDAT.
ENDLOOP.
ENDFORM. "FRM_GET_DATA
*&---------------------------------------------------------------------*
*& Form FRM_DISPLAY_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM FRM_DISPLAY_DATA .
DATA: LS_LAYOUT TYPE LVC_S_LAYO,
LS_FCAT TYPE LVC_S_FCAT,
LT_FCAT TYPE LVC_T_FCAT.
DEFINE _APPEND_FCAT.
CLEAR LS_FCAT.
LS_FCAT-COL_POS = &1.
LS_FCAT-FIELDNAME = &2.
LS_FCAT-SCRTEXT_L = &3.
APPEND LS_FCAT TO LT_FCAT.
END-OF-DEFINITION.
LS_LAYOUT-ZEBRA = ABAP_TRUE.
LS_LAYOUT-CWIDTH_OPT = ABAP_TRUE.
_APPEND_FCAT: '1' 'LIFNR' TEXT-003 ,
'2' 'EKORG' TEXT-004 ,
'3' 'EKGRP' TEXT-005 ,
'4' 'BUKRS' TEXT-006 ,
'5' 'KNTTP' TEXT-007 ,
'6' 'MATNR' TEXT-008 ,
'7' 'MENGE' TEXT-009 ,
'8' 'LGORT' TEXT-010 ,
'9' 'WERKS' TEXT-011 ,
'10' 'DELIVERY_DATE' TEXT-012 ,
'11' 'VBELN' TEXT-013 ,
'12' 'POSNR' TEXT-014 ,
'13' 'ZZVKORG' TEXT-015 ,
'14' 'ZZKUNNR' TEXT-016 ,
'15' 'ZZNAME1' TEXT-023 ,
'16' 'ZZAUART' TEXT-017 ,
'17' 'EBELN' TEXT-018 ,
'18' 'MSGTY' TEXT-019 ,
'19' 'MSGTXT' TEXT-020 .
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
I_CALLBACK_PROGRAM = SY-REPID
I_CALLBACK_PF_STATUS_SET = 'FRM_ALV_SET_STATUS'
I_CALLBACK_USER_COMMAND = 'FRM_USER_COMMAND_STATUS'
IS_LAYOUT_LVC = LS_LAYOUT
IT_FIELDCAT_LVC = LT_FCAT
I_SAVE = 'A'
TABLES
T_OUTTAB = T_ALV
EXCEPTIONS
PROGRAM_ERROR = 1
OTHERS = 2.
ENDFORM. "FRM_DISPLAY_DATA
*&---------------------------------------------------------------------*
*& Form FRM_ALV_STATUS_FILE
*&---------------------------------------------------------------------*
* 标准按钮的设置
*----------------------------------------------------------------------*
* -->RT_EXTAB
*----------------------------------------------------------------------*
FORM FRM_ALV_SET_STATUS USING RT_EXTAB TYPE SLIS_T_EXTAB."
SET PF-STATUS 'STATUS_001' EXCLUDING RT_EXTAB.
ENDFORM. "FRM_ALV_SET_STATUS
*&---------------------------------------------------------------------*
*& Form FRM_ALV_USER_COMMAND
*&---------------------------------------------------------------------*
*& user_command功能实现
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM FRM_USER_COMMAND_STATUS USING UCOMM LIKE SY-UCOMM
SELFIELD TYPE SLIS_SELFIELD."
DATA: LR_GRID TYPE REF TO CL_GUI_ALV_GRID.
DATA L_ANSWER TYPE CHAR1.
DATA: LS_LAYOUT TYPE LVC_S_LAYO.
LS_LAYOUT-ZEBRA = ABAP_TRUE.
LS_LAYOUT-CWIDTH_OPT = ABAP_TRUE.
SELFIELD-REFRESH = 'X'.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
E_GRID = LR_GRID.
CASE UCOMM.
WHEN '&SAVE' .
CALL FUNCTION 'POPUP_TO_CONFIRM_WITH_MESSAGE'
EXPORTING
DIAGNOSETEXT1 = ''
TEXTLINE1 = TEXT-021
TITEL = TEXT-022
IMPORTING
ANSWER = L_ANSWER.
IF L_ANSWER = 'J'. " 确认
PERFORM SAVA_DISPLAY CHANGING T_ALV .
"refresh alv
LR_GRID->SET_FRONTEND_LAYOUT( LS_LAYOUT ).
LR_GRID->REFRESH_TABLE_DISPLAY( ).
ENDIF.
WHEN '&EXIT'.
LEAVE PROGRAM.
WHEN '&BACK'.
SET SCREEN 0.
LEAVE SCREEN.
WHEN '&LEAVE'.
SET SCREEN 0.
LEAVE SCREEN.
WHEN OTHERS.
"refresh alv
LR_GRID->SET_FRONTEND_LAYOUT( LS_LAYOUT ).
LR_GRID->REFRESH_TABLE_DISPLAY( ).
ENDCASE.
ENDFORM. "FRM_USER_COMMAND_STATUS
*&---------------------------------------------------------------------*
*& Form SAVA_DISPLAY
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> W_ALV
*& <-- T_ALV
*&---------------------------------------------------------------------*
FORM SAVA_DISPLAY CHANGING PT_T_ALV TYPE T_FILE_ALV.
DATA:GT_ALV TYPE T_FILE_ALV,
GS_ALV TYPE W_FILE_ALV.
DATA:PW_T_ALV TYPE W_FILE_ALV.
DATA:POHEADER TYPE BAPIMEPOHEADER,
POHEADERX TYPE BAPIMEPOHEADERX.
DATA:POITEM TYPE TABLE OF BAPIMEPOITEM WITH HEADER LINE,
POITEMX TYPE TABLE OF BAPIMEPOITEMX WITH HEADER LINE.
DATA:POSCHEDULE TYPE TABLE OF BAPIMEPOSCHEDULE WITH HEADER LINE,
POSCHEDULX TYPE TABLE OF BAPIMEPOSCHEDULX WITH HEADER LINE.
DATA:POACCOUNT TYPE TABLE OF BAPIMEPOACCOUNT WITH HEADER LINE,
POACCOUNTX TYPE TABLE OF BAPIMEPOACCOUNTX WITH HEADER LINE.
DATA:RETURN LIKE TABLE OF BAPIRET2 WITH HEADER LINE.
DATA:LV_PO_ITEM(5) TYPE N.
DATA:LV_LIFNR TYPE ELIFN.
DATA:L_RETURN LIKE RETURN.
DATA:LV_MESSAGE(255).
DATA:LV_PO TYPE CHAR10.
GT_ALV[] = PT_T_ALV[].
SORT GT_ALV BY LIFNR.
DELETE ADJACENT DUPLICATES FROM GT_ALV COMPARING LIFNR.
LOOP AT GT_ALV INTO GS_ALV.
* 采购订单抬头
CLEAR LV_LIFNR.
LV_LIFNR = GS_ALV-LIFNR.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
INPUT = LV_LIFNR
IMPORTING
OUTPUT = LV_LIFNR.
POHEADER-COMP_CODE = GS_ALV-BUKRS. " 公司代码
POHEADER-DOC_TYPE = 'NB'. " 采购凭证类型
POHEADER-VENDOR = LV_LIFNR. " 供应商帐号
POHEADER-PURCH_ORG = GS_ALV-EKORG. " 采购组织
POHEADER-PUR_GROUP = GS_ALV-EKGRP. " 采购组
POHEADER-DOC_DATE = SY-DATUM. " 采购凭证日期
POHEADER-LANGU = SY-LANGU. " 语言代码
POHEADERX-COMP_CODE = C_TAGX.
POHEADERX-DOC_TYPE = C_TAGX.
POHEADERX-VENDOR = C_TAGX.
POHEADERX-PURCH_ORG = C_TAGX.
POHEADERX-PUR_GROUP = C_TAGX.
POHEADERX-DOC_DATE = C_TAGX.
POHEADERX-LANGU = C_TAGX.
CLEAR LV_PO_ITEM.
LOOP AT PT_T_ALV INTO PW_T_ALV WHERE LIFNR = GS_ALV-LIFNR.
LV_PO_ITEM = LV_PO_ITEM + 10.
POITEM-PO_ITEM = PW_T_ALV-PO_ITEM. " 采购凭证的项目编号
POITEM-ACCTASSCAT = PW_T_ALV-KNTTP. " 科目分配类别
POITEM-MATERIAL = PW_T_ALV-MATNR. " 物料号
POITEM-QUANTITY = PW_T_ALV-MENGE. " 采购订单数量
POITEM-STGE_LOC = PW_T_ALV-LGORT. " 仓储地点
POITEM-PLANT = PW_T_ALV-WERKS. " 工厂
APPEND POITEM.
CLEAR POITEM.
POITEMX-PO_ITEM = PW_T_ALV-PO_ITEM. " 采购凭证的项目编号
POITEMX-ACCTASSCAT = C_TAGX. " 科目分配类别
POITEMX-MATERIAL = C_TAGX. " 物料号
POITEMX-QUANTITY = C_TAGX. " 采购订单数量
POITEMX-STGE_LOC = C_TAGX. " 仓储地点
POITEMX-PLANT = C_TAGX. " 工厂
APPEND POITEMX.
CLEAR POITEMX.
POSCHEDULE-PO_ITEM = PW_T_ALV-PO_ITEM. "采购凭证的项目编号
POSCHEDULE-SCHED_LINE = PW_T_ALV-PO_ITEM. "采购凭证的项目编号
POSCHEDULE-DELIVERY_DATE = PW_T_ALV-DELIVERY_DATE."交货日期
POSCHEDULE-QUANTITY = PW_T_ALV-MENGE."采购订单数量
APPEND POSCHEDULE.
CLEAR POSCHEDULE.
POSCHEDULX-PO_ITEM = PW_T_ALV-PO_ITEM. "采购凭证的项目编号
POSCHEDULX-SCHED_LINE = PW_T_ALV-PO_ITEM. "采购凭证的项目编号
POSCHEDULX-DELIVERY_DATE = C_TAGX."交货日期
POSCHEDULX-QUANTITY = C_TAGX."采购订单数量
APPEND POSCHEDULX.
CLEAR POSCHEDULX.
IF PW_T_ALV-KNTTP <> ''.
POACCOUNT-PO_ITEM = PW_T_ALV-PO_ITEM. "采购凭证的项目编号
POACCOUNT-GL_ACCOUNT = '12430000'."总帐科目
POACCOUNT-SD_DOC = PW_T_ALV-VBELN."销售和分销凭证号
POACCOUNT-ITM_NUMBER = PW_T_ALV-POSNR."销售凭证项目
APPEND POACCOUNT.
CLEAR POACCOUNT.
POACCOUNTX-PO_ITEM = PW_T_ALV-PO_ITEM. "采购凭证的项目编号
POACCOUNTX-GL_ACCOUNT = C_TAGX."总帐科目
POACCOUNTX-SD_DOC = C_TAGX."销售和分销凭证号
POACCOUNTX-ITM_NUMBER = C_TAGX."销售凭证项目
APPEND POACCOUNTX.
CLEAR POACCOUNTX.
ENDIF.
CLEAR:PW_T_ALV.
ENDLOOP.
CALL FUNCTION 'BAPI_PO_CREATE1'
EXPORTING
POHEADER = POHEADER
POHEADERX = POHEADERX
IMPORTING
EXPPURCHASEORDER = LV_PO
TABLES
RETURN = RETURN
POITEM = POITEM
POITEMX = POITEMX
POSCHEDULE = POSCHEDULE
POSCHEDULEX = POSCHEDULX
POACCOUNT = POACCOUNT
POACCOUNTX = POACCOUNTX.
LOOP AT RETURN WHERE TYPE = 'E' OR TYPE = 'A'.
ENDLOOP.
IF SY-SUBRC = 0.
CLEAR: LV_MESSAGE.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
LOOP AT RETURN INTO L_RETURN WHERE TYPE = 'E' .
CONCATENATE LV_MESSAGE L_RETURN-MESSAGE ';'
INTO LV_MESSAGE.
ENDLOOP.
PW_T_ALV-MSGTY = 'E'.
PW_T_ALV-MSGTXT = LV_MESSAGE.
MODIFY PT_T_ALV FROM PW_T_ALV TRANSPORTING MSGTY MSGTXT WHERE LIFNR = GS_ALV-LIFNR.
CLEAR:PW_T_ALV,GS_ALV.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
WAIT = 'X'.
PW_T_ALV-EBELN = LV_PO.
PW_T_ALV-MSGTY = 'S'.
PW_T_ALV-MSGTXT = '创建成功'.
MODIFY PT_T_ALV FROM PW_T_ALV TRANSPORTING EBELN MSGTY MSGTXT WHERE LIFNR = GS_ALV-LIFNR.
CLEAR:PW_T_ALV,GS_ALV.
ENDIF.
REFRESH: POITEM,POITEMX,POSCHEDULE,POSCHEDULX,
POACCOUNT,POACCOUNTX,RETURN.
CLEAR: POITEM,POITEMX,POSCHEDULE,POSCHEDULX,
POACCOUNT,POACCOUNTX,POHEADER,POHEADERX,RETURN.
ENDLOOP.
* 更新客户数据
PERFORM FRM_UPDATE_DATA.
ENDFORM. "SAVA_DISPLAY
*&---------------------------------------------------------------------*
*& Form FRM_UPDATE_DATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM FRM_UPDATE_DATA.
DATA:GT_ALV_DATA TYPE T_FILE_ALV,
GW_ALV_DATA TYPE W_FILE_ALV.
GT_ALV_DATA[] = T_ALV[].
DELETE GT_ALV_DATA WHERE ZZVKORG = ''.
LOOP AT GT_ALV_DATA INTO GW_ALV_DATA WHERE MSGTY = 'S'.
UPDATE EKPO SET ZZVKORG = GW_ALV_DATA-ZZVKORG ZZKUNNR = GW_ALV_DATA-ZZKUNNR
ZZNAME1 = GW_ALV_DATA-ZZNAME1 ZZAUART = GW_ALV_DATA-ZZAUART
WHERE EBELN = GW_ALV_DATA-EBELN AND EBELP = GW_ALV_DATA-PO_ITEM .
COMMIT WORK AND WAIT.
ENDLOOP.
ENDFORM. "FRM_UPDATE_DATA