здравствуйте коллеги.
консультант поставил задачу создать фоновое задание которое после выполнения само себя перепланирует. я так понял что перепланировать фоновые задания нельзя. можно только удалить старое и создать такое же точно новое.
проблема в том, что новое планирует, а вот само себя удалять не хочет!
написал тестовую программу для того чтобы понять как это делается. программа фонового задания просто удаляет фоновое задание в котором она находится.
сама программа для фонового задания:
REPORT zjob_job_prg.
START-OF-SELECTION.
PERFORM start_of_selection.
*&---------------------------------------------------------------------*
*& Form start_of_selection
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM start_of_selection.
DATA lv_jobname TYPE tbtco-jobname.
DATA lt_tbtco TYPE STANDARD TABLE OF tbtco.
DATA ls_tbtco TYPE tbtco.
************************************************************************
lv_jobname = 'ZJOB_TEST'.
*----------------------------------------------------------------------*
SELECT * FROM tbtco INTO TABLE lt_tbtco
WHERE
jobname EQ lv_jobname.
LOOP AT lt_tbtco INTO ls_tbtco.
CALL FUNCTION 'BP_JOB_DELETE'
EXPORTING
jobname = ls_tbtco-jobname
jobcount = ls_tbtco-jobcount
forcedmode = 'X'
EXCEPTIONS
OTHERS = 99.
ENDLOOP.
COMMIT WORK AND WAIT.
ENDFORM. " START_OF_SELECTION
программа которая его планирует:
REPORT zjob_main.
INITIALIZATION.
PERFORM init.
*&---------------------------------------------------------------------*
*& Form init
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM init.
DATA lv_jobcount TYPE tbtcjob-jobcount.
DATA lv_jobname TYPE tbtcjob-jobname.
lv_jobname = 'ZJOB_TEST'.
*----------------------------------------------------------------------*
* планируем фоновое задание
*----------------------------------------------------------------------*
CALL FUNCTION 'JOB_OPEN'
EXPORTING
jobname = lv_jobname
IMPORTING
jobcount = lv_jobcount
EXCEPTIONS
cant_create_job = 1
invalid_job_data = 2
jobname_missing = 3
OTHERS = 4.
*
CHECK sy-subrc EQ 0.
*
SUBMIT zjob_job_prg VIA JOB lv_jobname NUMBER lv_jobcount AND RETURN.
DATA lv_time TYPE t.
lv_time = sy-uzeit + '000030'.
CALL FUNCTION 'JOB_CLOSE'
EXPORTING
jobcount = lv_jobcount
jobname = lv_jobname
sdlstrtdt = sy-datum
sdlstrttm = lv_time
EXCEPTIONS
cant_start_immediate = 1
invalid_startdate = 2
jobname_missing = 3
job_close_failed = 4
job_nosteps = 5
job_notex = 6
lock_failed = 7
OTHERS = 8.
IF sy-subrc <> 0.
...
ENDIF.
ENDFORM. " INI
проблема в том что если запланировать задание то оно себя не удаляет. если выполнить его через SM36 режиме jdbg то все ОК. исчезает из списка.
Есть работающий пример. Делал первый раз.
Ниже часть программы ZBHR_AUTO_HIRE_JOB, которая планирует в фоновом режиме запуск программы ZBHR_AUTO_HIRE
concatenate 'Z8_' p_refnr '_' p_count into lv_jobname.
call function 'JOB_OPEN'
exporting
delanfrep = ' '
jobgroup = ' '
jobname = lv_jobname
sdlstrtdt = sy-datum
sdlstrttm = sy-uzeit
importing
jobcount = lv_jobcount
exceptions
cant_create_job = 01
invalid_job_data = 02
jobname_missing = 03.
if sy-subrc ne 0.
"error processing
endif.
SUBMIT ZBHR_AUTO_HIRE
WITH p_begda = p_begda
WITH p_refnr = p_refnr
WITH p_werks = p_werks
WITH p_btrtl = ls_btrtl
WITH p_persg = p_persg
WITH p_persk = p_persk
with p_reason = p_reason
with p_count = p_count
"WITH p_orgeh = PSPAR-orgeh
"VIA SELECTION-SCREEN
VIA JOB lv_jobname
NUMBER lv_jobcount
AND RETURN.
starttime-sdlstrtdt = sy-datum .
starttime-sdlstrttm = sy-UZEIT + 150.
call function 'JOB_CLOSE'
exporting
" event_id = starttime-eventid
" event_param = starttime-eventparm
" event_periodic = starttime-periodic
jobcount = lv_jobcount
jobname = lv_jobname
" laststrtdt = starttime-laststrtdt
" laststrttm = starttime-laststrttm
" prddays = 1
" prdhours = 0
" prdmins = 0
" prdmonths = 0
" prdweeks = 0
sdlstrtdt = starttime-sdlstrtdt
sdlstrttm = starttime-sdlstrttm
" strtimmed = starttimeimmediate
" targetsystem = host
exceptions
cant_start_immediate = 01
invalid_startdate = 02
jobname_missing = 03
job_close_failed = 04
job_nosteps = 05
job_notex = 06
lock_failed = 07
others = 99.
В самой программе ZBHR_AUTO_HIRE происходят проверки. В моем случае , если объект был заблокирован, программа в фоне опять "планирует" себя через 5 минут. На всякий случай сделал так, чтобы после 10 попыток программа успокоилась :)
IF ls_bret-type = 'E'.
WRITE / 'Автоматический прием пенсионера не произошел'.
WRITE: / ls_bret-ID, ls_bret-number,ls_bret-message,ls_bret-message_v1,ls_bret-message_v2,ls_bret-message_v3,ls_bret-message_v4.
IF p_count <= 9.
p_count = p_count + 1.
SUBMIT ZBHR_AUTO_HIRE_JOB
WITH p_begda = p_begda
WITH p_refnr = p_refnr
WITH p_werks = p_werks
"WITH p_btrtl = ls_btrtl
WITH p_persg = p_persg
WITH p_persk = p_persk
WITH p_count = p_count
"WITH p_plans = lv_plans
WITH p_reason = p_reason
"VIA SELECTION-SCREEN
"VIA JOB 'z8'
"NUMBER lv_jobcount
AND RETURN.
ELSE.
WRITE / 'Было выполнено 10 попыток приема. Попробуйте сделать вручную через транзакцию PA40'.
ENDIF.
EXIT.
ENDIF.
P.S. Прочитал внимательней вопрос, обнаружил, что на него не ответил :) А зачем удалять старое выполненное задание? Вдруг кто-то лог захочет почитать...
Скорее всего программа в фоне не может удалить задание, которое ее же и запустило. Оно должно выполнится, а потом уже удалять.
дело в том, что имена заданий связаны с объектами в системе, которые обновляются. желательно чтобы на один объект жило только одно фоновое задание иначе они наплодятся кучей.
Цитата: r00xus від Жовтень 17, 2013, 02:00:44 ПП
дело в том, что имена заданий связаны с объектами в системе, которые обновляются. желательно чтобы на один объект жило только одно фоновое задание иначе они наплодятся кучей.
Вообще-то имя задания может повторяться хоть 100 раз, все равно у задания есть уникальный идентификатор... Далее скорее всего действительно у вас не правильные предпосылки на изменение задания. Опять же ну будет их много этих заданий, не вижу проблемы, если в целом.
Старое (выполненное) фоновое задание удалять не обязательно, даже нежелательно, как отмечено коллегой выше, ради лога. Чистка системных таблиц - задача базиса. Я бы сделал так: запланировал на однократное выполнение задание 1, запускающее целевую рабочую программу, содержащую код, отвечающий за перепланировку задания, только и всего. А дальше все автоматом по рельсам пойдет. Главное, корректно программно запланировать задачу по времени. Видел случаи, когда из-за неправильного программного планирования задания, выполнявшегося в фоне около 10-15 минут, запуск оного осуществлялся 1 раз в 5 минут, вместо 1 раз в сутки, из-за чего медленно, но верно, повисал сервер приложений, благо это на тесте выявилось.:)
коллеги спасибо за ответы. понятно что не обязательно удалять старое задание.
вопрос заключается в том почему программа не может удалить задание в котором запланирована через ФМ BP_JOB_DELETE? В то время как если запустить через SM36 режиме отладки задания через ОК-CODE jdbg она его таки удаляет? может я упускаю какие-то нюансы?
Цитата: r00xus від Жовтень 17, 2013, 05:40:19 ПП
вопрос заключается в том почему программа не может удалить задание в котором запланирована через ФМ BP_JOB_DELETE? В то время как если запустить через SM36 режиме отладки задания через ОК-CODE jdbg она его таки удаляет? может я упускаю какие-то нюансы?
Скорее всего из-за того, что нельзя удалить из выполняющегося задания его самое, все происходит в рамках одной задачи (фон). При отладке создается еще и диалоговая задача (процесс).
Цитата: r00xus від Жовтень 17, 2013, 05:40:19 ПП
коллеги спасибо за ответы. понятно что не обязательно удалять старое задание.
Ну Дмитрий вам ответил, а в целом, похоже надо идеологию работы приложения перепроектировать.
Для получения четкой и ясной картины по процессам используйте транзакцию SM50 "Work Process Overview" - обзор рабочих процессов. F1 в поле "Тип" покажет расшифровку используемых сокращений. Вот немного информации (http://www.sap-dev.ru/netweaver/1.3.php) по этой теме.