Sapforum.Biz
Инструменты => ABAP - Инструментальные средства => Тема розпочата: tanyxa від Вересень 04, 2018, 10:33:20 ДП
Всем доброго времени суток!
Уважаемые эксперты, помогите разобраться с поведением программы. Имеется некий многопозиционный Z документ (каждая позиция содержит отпускающую и принимающую партию, № произв. заказа, значения признаков партии и т.д. ), нужно в цикле пройтись по всем позициям и:
а) обновить классификацию партии указаной в позиции
б) создать подтверждение для произв. заказа. (в данном случае для 2 позиций один и тот же № заказа)
Если все это было успешно сделано - сохранить сам Z документ, иначе вывалить окошко c возникшими ошибками.
Кусок кода:
LOOP AT mt_pcaitm ASSIGNING FIELD-SYMBOL(<fs_item>).
"Проверка блокировки партии
DO 300 TIMES.
CALL FUNCTION 'ENQUEUE_EMMCH1E'
EXPORTING
mode_mch1 = 'V'
matnr = <fs_item>-mantr
charg = <fs_item>-charg
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc = 0.
EXIT.
ELSE.
WAIT UP TO 1 SECONDS.
ENDIF.
ENDDO.
SET UPDATE TASK LOCAL.
".... Читаем классификацию, присваиваем значения признаков и т.д.
"Обновляем
CALL FUNCTION 'BAPI_OBJCL_CHANGE'
EXPORTING
objectkey = l_objectkey
objecttable = l_objecttable
classnum = l_classnum
classtype = l_classtype
TABLES
allocvaluesnumnew = lt_allocvaluesnum
allocvaluescharnew = lt_allocvalueschar
allocvaluescurrnew = lt_allocvaluescurr
return = lt_ret.
IF bapiret_has_errors( lt_ret ) IS NOT INITIAL.
ycx_static=>raise_bapiret2( it_ret = lt_ret ).
ENDIF.
"Далее работаем с заказом
CALL FUNCTION 'Z_CREATE_HDR'
EXPORTING
i_aunfr = <fs_item>-manuf_aufnr
i_date = get_pstng_date( ms_pca )
i_lmnga = l_lmnga
i_tplnr = <fs_item>-tplnr
i_schgrup = get_brig_line( <fs_item>-brig_l )-schgrup
i_kaptprog = get_brig_line( <fs_item>-brig_l )-kaptprog
i_batch_in = <fs_item>-charg_pp
i_lgort_in = ms_pca-lgort
i_batch_out = <fs_item>-charg
i_lgort_out = ms_pca-lgort
i_commit = ' '
i_testrun = ' '
IMPORTING
et_return = lt_return1.
LOOP AT lt_return1 TRANSPORTING NO FIELDS WHERE type CA 'EAX'.
EXIT.
ENDLOOP.
IF sy-subrc = 0.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
MESSAGE e076 WITH |{ <fs_item>-confir }/{ <fs_item>-confco }| INTO dummy.
ycx_static=>raise_sy( ).
ENDIF.
zcl_doc_stc=>change(
EXPORTING
i_send_int = 'X'
i_no_commit = 'X'
is_header = ms_header
it_item = mt_pcaitm ).
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
DO 300 TIMES.
CALL FUNCTION 'ENQUEUE_ESORDER'
EXPORTING
mode_aufk = 'V'
aufnr = <fs_item>-manuf_aufnr
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc = 0.
EXIT.
ELSE.
WAIT UP TO 1 SECONDS.
ENDIF.
ENDDO.
SELECT SINGLE rsnum FROM rkpf INTO @DATA(l_rsnum)
WHERE aufnr = @<fs_item>-manuf_aufnr.
IF sy-subrc = 0.
DO 300 TIMES.
CALL FUNCTION 'ENQUEUE_EMRKPF'
EXPORTING
mode_rkpf = 'V'
rsnum = l_rsnum
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc = 0.
EXIT.
ELSE.
WAIT UP TO 1 SECONDS.
ENDIF.
ENDDO.
ENDIF.
ENDLOOP.
Внутри FM Z_CREATE_HDR следующий код (сам FM обычный - не RFC и не модуль обновления) :
SET UPDATE TASK LOCAL.
"....Промежуточные разные вычисления, специфичные для позиции Z документа
CALL FUNCTION 'BAPI_PRODORDCONF_CREATE_HDR'
EXPORTING
testrun = i_testrun
IMPORTING
return = ls_return
TABLES
detail_return = lt_detailreturn
athdrlevels = lt_athdrlevels
goodsmovements = lt_goodsmovements
link_conf_goodsmov = lt_link_conf_goodsmov.
LOOP AT et_return TRANSPORTING NO FIELDS WHERE type CA 'EAX'.
EXIT.
ENDLOOP.
IF sy-subrc NE 0.
IF i_commit EQ abap_true.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
ENDIF.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ENDIF.
Странность поведения в том, что на второй итерации LOOP вылетает ошибка блокировки заказа ( объект ESORDER ) , хотя цикл проверки рассчитан аж на 5 минут, по времени выполнения видно что блокировки снимаются гораздо быстрее. Почему так может быть и как правильно дождаться окончания работы BAPI_PRODORDCONF_CREATE_HDR?
А зачем вы сами блокировки выставляете? BAPI-сама вызовет блокировку и сама ее снимет. Попробуйте убрать собственные блокировки, а оставить только проверку на блокирование.
Так я собственную блокировку и не устанавливаю, CALL FUNCTION 'ENQUEUE_ESORDER' EXPORTING mode_aufk = 'V' это же собственно и есть проверка (физически блокировка не устанавливается при этом) . Т.е. если получилось проэмулировать блокирование заказа - то можно переходить к следующей итерации.
Цитата: tanyxa від Вересень 04, 2018, 12:00:03 ПП
Так я собственную блокировку и не устанавливаю, CALL FUNCTION 'ENQUEUE_ESORDER' EXPORTING mode_aufk = 'V' это же собственно и есть проверка
Да не обратил внимание на параметр V. ну в общем проверку сделайте так:
CALL FUNCTION 'ENQUEUE_EMMCH1E'
EXPORTING
mode_mch1 = 'V'
matnr = <fs_item>-mantr
charg = <fs_item>-charg
_wait = abap_true
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
И уберите цикл, оно с параметром _wait, теоретически само будет выжидать где-то до 5 секунд (зависти от настройки профиля системы) пока не получится поставить блокировку, после чего пойдет дальше.
Uukrul, спасибо за подсказку, но будет ли установка параметра _wait существенно отличаться от варианта с циклом?
Суть проблемы в том что проверка на блокировку отрабатывает и отрабатывает быстро, я вижу что прога не задумывается на 5 минут. Мне неважно сколько времени займет ожидание (ну в разумных пределах конечно), главное чтобы подтверждение заказа для позиции Z документа завершилось.
Но фактически получается похоже процесс обновления еще работает. Я оставила в цикле только BAPI_PRODORDCONF_CREATE_HDR и проверку ESORDER, но на второй итерации периодически вылетаю с ошибкой блокировки заказа (т.е. этого самого ESORDER)
Цитата: tanyxa від Вересень 04, 2018, 08:09:15 ПП
Uukrul, спасибо за подсказку, но будет ли установка параметра _wait существенно отличаться от варианта с циклом?
Ну теоретически будет и будет более правильно. Как минимум по скорости работы это 100% Далее это все уже получается управляемым, а не прибитым гвоздями в коде программы.
Кстати, если это не поможет, другой вариант идти и говорить с базисом, если блокировка медленно снимается, вполне возможно, что есть какие-то проблемы в настройке таблицы блокировок. Была у меня ситуация когда таблица была очень большой и при определенных параметрах это вызвало проблемы с медленным процессом снятия блокирования.
Цитата: tanyxa від Вересень 04, 2018, 08:09:15 ПП
Uukrul, спасибо за подсказку
Как говориться пожалуйста, но хотелось бы узнать конечный результат всех действий 8)
Цитата: Uukrul від Вересень 08, 2018, 01:58:51 ПП
Как говориться пожалуйста, но хотелось бы узнать конечный результат всех действий 8)
Прошу прощения за задержку, не хотела мешать экспериментами другому разработчику. В общем сделала с параметром _wait, параметр enque/delay_max установлен 5 секунд. Результат особенно не изменился, подтверждение заказа успешно создается, но иногда.. не каждый раз, ( закономерность не поддается определению ) возникают аналогичные грабли - проверка блокировки вроде бы успешно пройдена, но при выполнении BAPI_PRODORDCONF_CREATE_HDR вылетаю с блокировкой заказа. Пока решила проблему следующим образом:
LOOP ... " Цикл по позициям Z документа
CALL FUNCTION 'BAPI_PRODORDCONF_CREATE_HDR' " Создаю подтверждение
.....
CALL FUNCTION 'ENQUEUE_ESORDER'
EXPORTING
mode_aufk = 'V'
aufnr = <fs_item>-manuf_aufnr
_wait = abap_true
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc = 2.
"Если блокировка все не снялась, возможно заказ заблокирован другим пользователем
"читаем с помощью ENQUEUE_READ и проверяем кто именно заблокировал его
ELSEIF ( sy-subrc = 1 ) or ( sy-subrc = 3 )
zcx_static=>raise_sy( ).
ELSEIF sy-subrc = 0.
WAIT UP TO 2 SECONDS.
ENDIF.
ENDLOOP.
Цитата: tanyxa від Вересень 10, 2018, 10:53:24 ДП
"Если блокировка все не снялась, возможно заказ заблокирован другим пользователем
"читаем с помощью ENQUEUE_READ и проверяем кто именно заблокировал его
Т.е. есть вероятность что заказ блокируется пользователем?
Цитата: Uukrul від Вересень 10, 2018, 01:53:09 ПП
Т.е. есть вероятность что заказ блокируется пользователем?
Этой вероятности нельзя исключать, правда в тестовой системе я не попадала так что кому-то ещё захотелось этот же заказ поредактировать, но в проде всяко возможно. А так проблема блокирования мной же ушла, после того как я добавила 2 секундную паузу после успешной проверки на блокировку