Краткое описание проблемы
Автоматическая обработка документальных партий с помощью пользовательского кода ABAP
Мой работодатель хочет выполнить автоматическую обработку документов для некоторых продуктов от внешних поставщиков, и я пытаюсь понятькак это настроить с помощью пользовательской настройки и ABAP.
Мне кажется, что документальные партии предназначены только для использования через MIGO - в любом случае я не могу найти правильное решение для их назначения программно, и любое взломанное решение, которое я могу придуматькажется недостаточным и нестабильным.
Какие пути у меня есть, чтобы решить эту проблему?
Улучшение BAPI_GOODSMVT_CREATE?
Можно ли как-то сделать это с помощью таких вещей, как BAPI_GOODSMVT_CREATE
?
Улучшение адресатов сообщений PPPI?
Мне также это особенно нужно дляработать для обмена сообщениями потребления через PPPI, и я подумал построить поверх стандартного назначения сообщений PI04
, FM COCI_CONFIRM_MATERIAL_CONS
.
Этот FM создает документ с материалом, но не проходит через BAPI_GOODSMVT_CREATE
FM.
Однако используется MB_CREATE_GOODS_MOVEMENT
.
То, что я уже пробовал
Одноразовое решение для взлома на основе снимков MIGO
Я создал решение для взлома для одной области, где я наблюдал, какиеТаблицы обновлений MIGO выполнялись и с какими данными (через FM VB_INSERT_BATCH
и VB_BATCH_WHERE_USED_LIST
), а затем заполняли эти структуры вручную.
Однако предоставление всей необходимой информации не представляется возможным для других областей реализации, поскольку они не имеют всех необходимых значений и не охватывают непредвиденные ситуации, когда могут потребоваться другие параметры.
Чтение через код BAPI_GOODSMVT_CREATE
Я пытался следить за тем, выполняет ли BAPI_GOODSMVT_CREATE
те же FM, но только обнаружил, что он получает доступ к VB_BATCH_WHERE_USED_LIST
.
Возможно активировать эту функцию, управляя идентификаторами памяти Documentary Batch #1
, Documentary Batch #2
, Documentary Batch #3
и Documentary Batch #5
(см. FM VBDBDM_DATA_POST_IM
), но для этого необходимо заполнить много данныхвключая структуру с именем DOCUBATCH_SCREEN_FIELDS
, что опять-таки заставляет думать, что это может быть неправильным подходом.
Несмотря на это, это все еще не позволяет мне поддерживать пакетную обработку через таблицы MCHA и MCH1.
Собранное решение на основе снимка MIGO
Здесьтак выглядит мое взломанное решение. Опять же, это неосуществимый способ решения проблемы, так как в других областях реализации нет результирующего Материального документа, доступного немедленно:
FUNCTION zproxy_mdr_goodsreceipt.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(IS_GOODSRECEIPT_HEAD) TYPE ZPROXY_GOODSREC_HEAD
*" VALUE(IT_GOODSRECEIPT_ITEM) TYPE ZPROXY_GOODSREC_ITEM_T
*" REFERENCE(I_CREATE_TO_FROM_REQUIREMENTS) TYPE FLAG DEFAULT '-'
*" EXPORTING
*" REFERENCE(E_GOODSMVT_MSG_IDNO) TYPE CHAR23
*" REFERENCE(E_MBLNR) TYPE MBLNR
*" REFERENCE(E_TO_CREATION_SUBRC) TYPE SY-SUBRC
*" REFERENCE(E_LGNUM_ERROR) TYPE LGNUM
*" REFERENCE(E_TBNUM_ERROR) TYPE TBNUM
*" REFERENCE(E_DOCBATCH_SUBRC) TYPE SY-SUBRC
*" REFERENCE(E_DOCBATCH_MSG_IDNO) TYPE CHAR23
*" REFERENCE(E_CLASSNUM) TYPE BAPI1003_KEY-CLASSNUM
*" REFERENCE(E_OBJKEY) TYPE BAPI1003_KEY-OBJECT
*" EXCEPTIONS
*" GOODSMVT_FAILED
*" NO_TRANSFER_REQUIREMENTS
*" TRANSFER_ORDER_CREATION_ERROR
*"----------------------------------------------------------------------
FIELD-SYMBOLS: <return> TYPE bapiret2,
<goods_rec_item> TYPE zproxy_goodsrec_item,
<mseg> TYPE mseg,
<char_char> TYPE bapi1003_alloc_values_char,
<ltap_creat> TYPE LTAP_CREAT.
DATA: ls_header TYPE bapi2017_gm_head_01,
ls_code TYPE bapi2017_gm_code,
ls_item TYPE bapi2017_gm_item_create,
lt_item TYPE STANDARD TABLE OF bapi2017_gm_item_create,
lt_return TYPE STANDARD TABLE OF bapiret2,
ls_headret TYPE bapi2017_gm_head_ret,
l_mblnr LIKE bapi2017_gm_head_ret-mat_doc,
l_docubatch TYPE charg_d,
l_subrc TYPE sy-subrc,
lt_mseg TYPE STANDARD TABLE OF mseg.
CLEAR l_subrc.
* ############################## Create goods movement ##############################
* Build structures
MOVE-CORRESPONDING is_goodsreceipt_head TO ls_header.
ls_code-gm_code = '01'.
LOOP AT it_goodsreceipt_item ASSIGNING <goods_rec_item>.
MOVE-CORRESPONDING <goods_rec_item> TO ls_item.
APPEND ls_item TO lt_item.
ENDLOOP.
* BAPI call
CALL FUNCTION 'BAPI_GOODSMVT_CREATE'
EXPORTING
goodsmvt_header = ls_header
goodsmvt_code = ls_code
IMPORTING
goodsmvt_headret = ls_headret
materialdocument = l_mblnr
TABLES
goodsmvt_item = lt_item
return = lt_return.
* Check errors
READ TABLE lt_return ASSIGNING <return> WITH KEY type = 'E'.
IF sy-subrc = 0.
e_goodsmvt_msg_idno = <return>-id && <return>-number.
ROLLBACK WORK.
RAISE goodsmvt_failed.
ELSE.
e_mblnr = l_mblnr.
COMMIT WORK AND WAIT. "Wait for TO requirements to be created
ENDIF.
* Only proceede if Material Document has been successfully posted
CHECK l_subrc = 0 AND l_mblnr IS NOT INITIAL.
* ############################## Update with Documentary Batch ###################################
DATA: lt_chvw TYPE STANDARD TABLE OF chvw,
ls_chvw TYPE chvw,
lt_mch1 TYPE STANDARD TABLE OF mch1,
ls_mch1 TYPE mch1,
lt_mcha TYPE STANDARD TABLE OF mcha,
ls_mcha TYPE mcha,
lt_mchb TYPE STANDARD TABLE OF mchb,
lt_mska TYPE STANDARD TABLE OF mska,
lt_mspr TYPE STANDARD TABLE OF mspr,
lt_char_num TYPE STANDARD TABLE OF bapi1003_alloc_values_num,
lt_char_char TYPE STANDARD TABLE OF bapi1003_alloc_values_char,
lt_char_curr TYPE STANDARD TABLE OF bapi1003_alloc_values_curr,
l_objkey TYPE bapi1003_key-object,
l_classnum TYPE bapi1003_key-classnum,
l_atnam TYPE atnam.
REFRESH lt_chvw.
* Get material document items
SELECT *
FROM mseg
INTO TABLE lt_mseg
WHERE mblnr = l_mblnr.
* Perpare docubatch registration data
LOOP AT it_goodsreceipt_item ASSIGNING <goods_rec_item>.
* Generate class num and atnam from plant
CONCATENATE 'PI_' <goods_rec_item>-plant INTO l_classnum.
CONCATENATE 'Z_DOC_BATCH_' <goods_rec_item>-plant INTO l_atnam.
* Get material docubatch usage characteristic
REFRESH: lt_return,
lt_char_num,
lt_char_char,
lt_char_curr.
l_objkey(18) = <goods_rec_item>-material.
CALL FUNCTION 'BAPI_OBJCL_GETDETAIL'
EXPORTING
objectkey = l_objkey
objecttable = 'MARA'
classnum = l_classnum
classtype = '001'
TABLES
allocvaluesnum = lt_char_num
allocvalueschar = lt_char_char
allocvaluescurr = lt_char_curr
return = lt_return.
LOOP AT lt_return ASSIGNING <return> WHERE type = 'E'. "Check for errors
* Couldn't read characteristic, assume no docubatch handling
e_docbatch_subrc = '1'.
e_docbatch_msg_idno = <return>-id && <return>-number.
e_classnum = l_classnum.
e_objkey = l_objkey.
CONTINUE.
ENDLOOP.
READ TABLE lt_char_char ASSIGNING <char_char> WITH KEY charact = l_atnam.
IF sy-subrc <> 0 OR <char_char>-value_neutral = 0.
* No docubatch value
CONTINUE.
ENDIF.
* Get associated material document item
READ TABLE lt_mseg ASSIGNING <mseg>
WITH KEY mblnr = ls_headret-mat_doc
mjahr = ls_headret-doc_year
bwart = <goods_rec_item>-move_type
matnr = <goods_rec_item>-material
werks = <goods_rec_item>-plant
menge = <goods_rec_item>-entry_qnt
meins = <goods_rec_item>-entry_uom
hsdat = <goods_rec_item>-prod_date
kzbew = <goods_rec_item>-mvt_ind
lgort = <goods_rec_item>-stge_loc.
IF sy-subrc <> 0.
* No associated material document item
CONTINUE.
ENDIF.
* Check docubatch type
IF <char_char>-value_neutral <> 0.
* Perform basic docubatch actions (MCHA and MCH1)
* Verify that docubatch nr is assigned
IF <goods_rec_item>-vendrbatch IS INITIAL.
* !!!!!!!!!!!!! Venderbatch not filled even though material is docubatch managed, what to do? !!!!!!!!!!!!!!!
CONTINUE.
ENDIF.
* Prepare data for docubatch registration
CLEAR: ls_mch1,
ls_mcha.
ls_mch1-matnr = <goods_rec_item>-material.
ls_mch1-charg = <goods_rec_item>-vendrbatch.
ls_mch1-ersda = sy-datum.
ls_mch1-ernam = sy-uname.
ls_mch1-ersda_tmstp = sy-datum && sy-uzeit.
ls_mch1-ersda_tz_sys = sy-tzone.
ls_mch1-ersda_tz_usr = sy-zonlo.
MOVE-CORRESPONDING ls_mch1 TO ls_mcha. "Same fields from MCH1 are included in MCHA
ls_mcha-werks = <goods_rec_item>-plant.
APPEND: ls_mch1 TO lt_mch1,
ls_mcha TO lt_mcha.
ENDIF.
IF <char_char>-value_neutral = 2. "Also include batch where-used
* Perpare data for batch where-used registration
CLEAR ls_chvw.
ls_chvw-matnr = <goods_rec_item>-material.
ls_chvw-werks = <goods_rec_item>-plant.
ls_chvw-charg = <goods_rec_item>-vendrbatch.
ls_chvw-ebeln = <goods_rec_item>-po_number.
ls_chvw-ebelp = <goods_rec_item>-po_item.
ls_chvw-mblnr = ls_headret-mat_doc.
ls_chvw-mjahr = ls_headret-doc_year.
ls_chvw-zeile = <mseg>-zeile.
ls_chvw-budat = is_goodsreceipt_head-pstng_date.
ls_chvw-shkzg = 'S'. "??? VALUE ???
ls_chvw-bwart = <goods_rec_item>-move_type.
ls_chvw-kzbew = <goods_rec_item>-mvt_ind. "Goods Movement for Purchase Order
ls_chvw-menge = <goods_rec_item>-entry_qnt.
ls_chvw-meins = <goods_rec_item>-entry_uom.
APPEND ls_chvw TO lt_chvw.
ENDIF.
ENDLOOP.
* Perform batch registration
CALL FUNCTION 'VB_INSERT_BATCH'
TABLES
zmch1 = lt_mch1
zmcha = lt_mcha
zmchb = lt_mchb
zmska = lt_mska
zmspr = lt_mspr
.
* Perform batch where-used registration
CALL FUNCTION 'VB_BATCH_WHERE_USED_LIST'
TABLES
xchvw = lt_chvw.
Почему это недостаточно хорошо, и чтоМне нужно
. Это снимок MIGO, сконфигурированный с документированной пакетной обработкой, но не обязательно охватывающий все случаи.
Работает только в контексте документа покупки и не распространяется на другие случаи, такие как заказы и заказы на продажу.
Кроме того, у меня есть только необходимая дата из-за документа материала, созданного непосредственно выше, что не возможно для всех случаев реализации.
Я хотел бы знать, существует ли предполагаемый способвыполнить документальную пакетную обработку из пользовательского кода.