作業要求:
上周老師布置了一個作業,要求自建表采購訂單和行項目,利用Table Control顯示和修改資料,并調用BAPI實作采購訂單的建立,同時擷取建立成功的采購訂單号碼,将采購訂單的資料填入到自建表中。
我的思路:
1.自建采購訂單和訂單明細(行項目表)兩張表。(ZPOUR和ZPODT)
在se11中維護,直接參考标準的采購訂單字段名和字段類型即可,這裡需要注意的點是貨币字段和數量字段需要額外在一個标簽下參考資料類型。
2.在螢幕布局中使用Table Control控件。(TBl)
一種是采用向導方式,比較友善;一種是采用手動建立的方式,稍微有些麻煩,我這裡才用了手動建立,個人認為自由度高一些。
3.調用BAPI( CALL FUNCTION 'BAPI_PO_CREATE1')。
筆者開始很長一段時間調用BAPI都在報一個get_data的錯誤,調用函數為‘MEPO_DOC_ITEM_GET’,看了下代碼發現傳入行項目号(po_item_number)後不能生成訂單資料(ex_data),十分頭疼。
後來發現是兩個問題造成的。
一是在填充函數 poitemx 等更新參數時,對于一個行項目字段必須要指派的有三條:字段值,項目編号,和項目編号更新标志‘X’,缺一不可。百度出的教程中都沒有講項目編号寫出來,最終的解決辦法還是se37看函數構成。例如:
iv_item = iv_item + 10."行号
ls_poitem-po_item = iv_item.
ls_poitemx-po_item = iv_item."這一行必填
ls_poitemx-po_itemx = ‘X’.
二是供應商編号格式的問題,預設格式為十位數字都占滿才能夠調BAPI成功,例如‘13999‘傳入程式會dump掉,‘0000013999‘就不會出現這樣的錯誤。程式崩掉的主要原因還是我這裡沒有做格式的控制,我将在下一片博文中更新關于供應商号的控制。
4.回填資料到自建資料庫表
在調用BAPI生成訂單号後,将訂單号字段EBELN重新指派,同時MODIFY自建表。
代碼如下
相關代碼下載下傳連結:
https://download.csdn.net/download/weixin_43151775/12464982
螢幕邏輯流:
PROCESS BEFORE OUTPUT.
MODULE modify_screen.
MODULE status_0100.
LOOP WITH CONTROL tbl.
MODULE filltbl.
ENDLOOP.
PROCESS AFTER INPUT.
LOOP WITH CONTROL tbl.
FIELD gs_out-matnr MODULE wlms ON REQUEST."自動帶出物料描述
CHAIN.
FIELD gs_out-matnr.
FIELD gs_out-maktx.
FIELD gs_out-menge.
FIELD gs_out-lmein.
FIELD gs_out-netpr.
FIELD gs_out-waers.
FIELD gs_out-netwr.
FIELD gs_out-werks.
FIELD gs_out-lgort.
FIELD gs_out-eindt.
MODULE money ON CHAIN-REQUEST.
ENDCHAIN."計算總金額
MODULE readtbl.
ENDLOOP.
MODULE user_command_0100.
MODULE cancel AT EXIT-COMMAND.
主程式:
REPORT z_zycc521.
DATA:ok_code TYPE sy-ucomm,
save_ok LIKE ok_code. "功能碼
*擡頭表
DATA:BEGIN OF ls_out.
INCLUDE STRUCTURE zpuor.
DATA END OF ls_out.
DATA lt_out LIKE TABLE OF ls_out."自建表采購訂單
*行項目表
DATA:BEGIN OF gs_out.
INCLUDE STRUCTURE zpodt.
DATA END OF gs_out.
DATA gt_out LIKE TABLE OF gs_out."自建表采購訂單明細
DATA iv_item TYPE i."BAPI行項目号
DATA se_flag TYPE i."儲存訂單識别碼
DATA nm_flag TYPE i."訂單号顯示識别碼
--------------------BAPI定義--------------------------------
DATA:
ls_poheader LIKE bapimepoheader, "表頭
ls_poheaderx LIKE bapimepoheaderx,
ls_return TYPE bapiret2, "傳回值
lt_return TYPE TABLE OF bapiret2,
ls_poitem TYPE bapimepoitem, "行項目
lt_poitem TYPE TABLE OF bapimepoitem,
ls_poitemx TYPE bapimepoitemx,
lt_poitemx TYPE TABLE OF bapimepoitemx,
ls_poschedule TYPE bapimeposchedule, "訂單交貨計劃
lt_poschedule TYPE TABLE OF bapimeposchedule,
ls_poschedulex TYPE bapimeposchedulx,
lt_poschedulex TYPE TABLE OF bapimeposchedulx,
ls_pocond TYPE bapimepocond, "價格條件
lt_pocond TYPE TABLE OF bapimepocond,
ls_pocondx TYPE bapimepocondx,
lt_pocondx TYPE TABLE OF bapimepocondx,
lv_ebeln TYPE bapimepoheader-po_number, "傳回訂單号
*Error flag
l_errflag(1) TYPE c.
---------------------------------------------------------------
*定義表控制對象
CONTROLS tbl TYPE TABLEVIEW USING SCREEN 0100.
CALL SCREEN 0100.
AT SELECTION-SCREEN.
FORM bapi.
APPEND ls_out TO lt_out."擡頭表資料插入
*BAPI表頭資料填充
ls_poheader-vendor = ls_out-lifnr.
ls_poheaderx-vendor = ‘X’.
ls_poheader-purch_org = ls_out-ekorg.
ls_poheaderx-purch_org = ‘X’.
ls_poheader-pur_group = ls_out-ekgrp.
ls_poheaderx-pur_group = ‘X’.
ls_poheader-comp_code = ls_out-bukrs.
ls_poheaderx-comp_code = ‘X’.
ls_poheader-doc_date = ls_out-cdate.
ls_poheaderx-doc_date = ‘X’.
ls_poheader-created_by = ls_out-ernam.
ls_poheaderx-created_by = ‘X’.
*BAPI行項目資料填充
LOOP AT gt_out INTO gs_out.
iv_item = iv_item + 10.
ls_poitem-po_item = iv_item.
ls_poitemx-po_item = iv_item.
ls_poitemx-po_itemx = 'X'.
ls_poitem-material = gs_out-matnr.
ls_poitemx-material = 'X'.
ls_poitem-short_text = gs_out-maktx.
ls_poitemx-short_text = 'X'.
ls_poitem-quantity = gs_out-menge.
ls_poitemx-quantity = 'X'.
ls_poitem-po_unit = gs_out-lmein.
ls_poitemx-po_unit = 'X'.
ls_poitem-net_price = gs_out-netwr."淨值
ls_poitemx-net_price = 'X'.
ls_poitem-plant = gs_out-werks."工廠
ls_poitemx-plant = 'X'.
ls_poitem-stge_loc = gs_out-lgort."庫位
ls_poitemx-stge_loc = 'X'.
APPEND ls_poitem TO lt_poitem.
APPEND ls_poitemx TO lt_poitemx.
*價格條件
ls_pocond-itm_number = iv_item.
ls_pocondx-itm_number = iv_item.
ls_pocondx-itm_numberx = ‘X’.
ls_pocond-currency = gs_out-waers.
ls_pocondx-currency = 'X'.
APPEND ls_pocond TO lt_pocond.
APPEND ls_pocondx TO lt_pocondx.
*交貨計劃
ls_poschedule-po_item = iv_item.
ls_poschedulex-po_item = iv_item.
ls_poschedulex-po_itemx = ‘X’.
ls_poschedule-delivery_date = gs_out-eindt."交貨日期
ls_poschedulex-delivery_date = 'X'.
APPEND ls_poschedule TO lt_poschedule.
APPEND ls_poschedulex TO lt_poschedulex.
ENDLOOP.
-------------------調用BAPI----------------------------
CALL FUNCTION ‘BAPI_PO_CREATE1’
EXPORTING
poheader = ls_poheader "擡頭
poheaderx = ls_poheaderx "相應更改參數
memory_uncomplete = space
memory_complete = space
IMPORTING
exppurchaseorder = lv_ebeln "訂單号
TABLES
return = lt_return "傳回參數消息類
poitem = lt_poitem "行項目
poitemx = lt_poitemx "行項目更改參數
poschedule = lt_poschedule "交貨計劃行
poschedulex = lt_poschedulex "交貨計劃更改參數
pocond = lt_pocond "采購訂單中的條件
pocondx = lt_pocondx. " 更改參數
-------------取回傳回訂單号Check and write Return table----------------
CLEAR l_errflag.
LOOP AT lt_return INTO ls_return.
-
WRITE:/ ls_return-type,ls_return-message(50).
IF ls_return-type = ‘E’.
l_errflag = ‘X’.
-
MESSAGE '訂單建立失敗' type 'E'. MESSAGE ls_return-type && ' ' && ls_return-message(50) TYPE 'E'.
ENDIF.
ENDLOOP.
---------------------遞交No errors - Commint-----------------------
IF l_errflag IS INITIAL.
CALL FUNCTION ‘BAPI_TRANSACTION_COMMIT’
EXPORTING
wait = ‘X’.
"回填采購訂單号到資料庫表
LOOP AT lt_out INTO ls_out.
ls_out-ebeln = lv_ebeln.
MODIFY lt_out FROM ls_out.
ENDLOOP.
MODIFY zpuor FROM TABLE lt_out.
LOOP AT gt_out INTO gs_out.
gs_out-ebeln = lv_ebeln.
MODIFY gt_out FROM gs_out.
ENDLOOP.
MODIFY zpodt FROM TABLE gt_out.
MESSAGE '訂單建立成功,單号為 ’ && lv_ebeln TYPE ‘S’.
se_flag = 1.
CALL SCREEN 0100.
ENDIF.
ENDFORM.
----------------------------------------------------------------------
MODULE cancel INPUT.
LEAVE PROGRAM.
ENDMODULE.
----------------------------------------------------------------------
MODULE status_0100 OUTPUT.
SET PF-STATUS ‘STANDARD’.
ENDMODULE.
----------------------------------------------------------------------
MODULE filltbl OUTPUT.
READ TABLE gt_out INTO gs_out INDEX tbl-current_line.
ENDMODULE.
----------------------------------------------------------------------
MODULE readtbl INPUT.
gs_out-ebelp = tbl-current_line * 10.
IF tbl-current_line < lines( gt_out ).
MODIFY gt_out FROM gs_out INDEX tbl-current_line.
ELSEIF tbl-current_line > lines( gt_out ).
APPEND gs_out TO gt_out.
ENDIF.
ENDMODULE. " READ INPUT
----------------------------------------------------------------------
MODULE user_command_0100 INPUT."使用者按鈕
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN ‘S’.
PERFORM bapi.
WHEN ‘C’."清空螢幕的步驟
CLEAR nm_flag.
CLEAR se_flag.
se_flag = 0.
nm_flag = 1.
CLEAR:ls_out,lt_out.
CLEAR:gs_out,gt_out.
CALL SCREEN 0100.
ENDCASE.
ENDMODULE.
----------------------------------------------------------------------
MODULE modify_screen OUTPUT."帶出日期和操作員
LOOP AT SCREEN.
ls_out-cdate = sy-datum.
ls_out-ernam = sy-uname.
ls_out-ctime = sy-uzeit.
IF nm_flag = 1.
CLEAR ls_out-ebeln.
ELSE.
ls_out-ebeln = lv_ebeln.
ENDIF.
IF se_flag EQ 1 AND screen-name = ‘SAVE’.
screen-active = 0.
ELSEIF se_flag NE 1 AND screen-name = ‘SAVE’.
screen-active = 1.
ENDIF.
MODIFY SCREEN.
ENDLOOP.
ENDMODULE.
----------------------------------------------------------------------
MODULE wlms INPUT."物料描述帶出
CLEAR gs_out-maktx.
SELECT SINGLE maktx FROM makt INTO gs_out-maktx WHERE matnr = gs_out-matnr.
MODIFY gt_out
FROM gs_out
INDEX tbl-current_line.
ENDMODULE.
----------------------------------------------------------------------
MODULE money INPUT."計算訂單金額
gs_out-netwr = gs_out-netpr * gs_out-menge.
MODIFY gt_out
FROM gs_out
INDEX tbl-current_line.
ENDMODULE.