Изначальная постановка задачи сводилась к тому, что в системе необходим еженедельный автоматический запуск транзакции ASKB. Ничего сложного.
Загвоздка первая: транзакция ASKB полно и продуктивно работает только в фоновом режиме. На всякий пожарный случай от греха подальше.
Загвоздка вторая: транзакция ASKB не умеет работать с несколькими БЕ. Экран выбора не оставляет выбора. Если бы на нашем проекте было бы мало БЕ (одна-две-три), то можно было бы просто создать напрямую несколько фоновых заданий и дело в шляпе. Но если у нас сотня БЕ, то уже необходима собственная запускалка, раз стандартной нет никакой.
Отлично, приступаем к реализации.
Сначала необходимо собрать список БЕ. Есть варианты:
- собрать все БЕ в системе (таблица T001)
- собрать все БЕ в системе для которых настроены модуль FI-AA и периодические проводки ASKB (таблица T093 + таблица T093C). В первой берём BUHBKT = 2, вторая содержит указание БЕ. План оценки — совсем не то же самое что и балансовая единица, хотя во многих сценариях так оно и бывает.
В моём случае достаточно первого варианта.
Затем надо определиться, каким образом обрабатывать список БЕ:
- дёргать безусловно каждую БЕ безо всяких предварительных проверок
- предварительно выяснять необходимо ли запускать ASKB
В моём случае БЕ много, операций мало, засорять журнал заданий пустыми вызовами не хочется. Я выбираю второй путь.
Если заглянуть внутрь транзакции ASKB, то можно посмотреть как она определяет надо ли запускаться:
- сначала по таблице TABAS берём максимальное значение временной метки
- затем по таблице ANEK проверяем наличие документов в требуемой области оценки с временными метками после временной метки в TABAS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
loop at gt_process assigning <fs_process>. select * from tabas into table lt_tabas up to 1 rows where bukrs = <fs_process>-bukrs order by cpudt descending cputm descending blnrt descending. if sy-subrc = 0. read table lt_tabas index 1. <fs_process>-tabas_cpudt = lt_tabas-cpudt. <fs_process>-tabas_cputm = lt_tabas-cputm. endif. select single * from anek into ls_anek where bukrs = <fs_process>-bukrs and ( cpudt > <fs_process>-tabas_cpudt or cpudt = <fs_process>-tabas_cpudt and cputm > <fs_process>-tabas_cputm ). if sy-subrc = 0. <fs_process>-anek_cpudt = ls_anek-cpudt. <fs_process>-anek_cputm = ls_anek-cputm. <fs_process>-action = 'I'. endif. endloop. |
Вот мы и выяснили, какие БЕ надо обрабатывать. Значит можно приступить к следующему шагу: сформировать фоновое задание. Сначала смотрим, что за программа стоит за транзакцией ASKBN – это RAPERB2000. Самая обыкновенная программа типа REPORT, которую можно дёрнуть просто через SUBMIT REPORT.
Значит, нам требуется следующая последовательность действий по каждой БЕ:
- сформировать имя для фонового задания
- открыть фоновое задание
- сформулировать задание по данной БЕ
- закрыть фоновое задание
Приступим:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
loop at gt_process where action = 'I'. concatenate 'RAPERB2000' gt_process-bukrs into lv_jobname separated by '_'. call function 'JOB_OPEN' exporting jobname = lv_jobname importing jobcount = lv_jobcount exceptions others = 99. submit raperb2000 with p_bukrs = gt_process-bukrs with p_test = p_test with p_einzel = 'X' with p_einzld = 'X' with p_normal = 'X' with p_rstart = ' ' via job lv_jobname number lv_jobcount and return. call function 'JOB_CLOSE' exporting jobcount = lv_jobcount jobname = lv_jobname strtimmed = 'X' exceptions others = 99. endloop. |
Всё просто. И что получается в итоге? Мы не задаём дополнительные параметры, это значит параметры печати будут по умолчанию, и что задание будет запущено немедленно. Меня это полностью устраивает.
А вот читатель мне возразит: “Но если сформировать 100 заданий в один момент времени, то будет очень неприятная пиковая нагрузка”. Тут всё просто: сервер не запускает немедленно сразу все задания, а будет обрабатывать их небольшими порциями. Следовательно, проблемы перегрузки не возникнет.
Уже можно идти в планировщик, но не хватает контроля результатов. На практике ASKB может упасть с ошибкой. Следовательно, финальными штрихами станет отслеживание результатов запуска.
Для отслеживания ситуации есть два направления:
- Можно посмотреть в таблице APERB_PROT. Там появляются записи, когда случаются проблемы
- Можно подождать пока фоновое задание выполнится,и проверить, как там всё сложилось
Второе направление мне видится предпочтительней и перспективней. Приступаем:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
do. wait up to 6 seconds. lv_count = lv_count + 1. call function 'SHOW_JOBSTATE' exporting jobcount = lv_jobcount jobname = lv_jobname importing finished = lv_finished exceptions others = 99. if lv_finished = 'X'. exit. elseif lv_count > 50. exit. endif. enddo. call function 'BP_JOBLOG_READ' exporting jobcount = lv_jobcount jobname = lv_jobname tables joblogtbl = lt_joblog[] exceptions others = 99. |
Последний ФМ нам вернул простую и понятную таблицу со списком возникших ошибок. Сам спул читать не обязательно – это очень радует.
Здесь уже возможны разные варианты:
- Показать списком результаты
- Перед продуктивным прогоном запускать тестовый прогон
- При наличии проблем отправить оповещение на почту
Для большой красоты можно реализовать всё сразу. Но это уже потом, на досуге, если будет время.
PS. Обработка ошибок и определения переменных убраны для простоты чтения кода.