Разработка механизмов автоматизации в среде «1С:Предприятие» часто требует динамического управления фоновыми процессами. Одним из наиболее гибких инструментов для этого является программное создание регламентных заданий. Однако многие разработчики сталкиваются с неприятной проблемой: после выполнения программного кода по созданию и настройке регламентного задания планировщик 1С игнорирует заданное расписание. Задание упрямо не желает запускаться автоматически, хотя при этом отлично отрабатывает при ручном запуске или после интерактивного пересохранения в консоли заданий.
В этой статье мы подробно разберем, почему возникает такое поведение платформы, проанализируем скрытые механизмы планировщика 1С и БСП (Библиотеки стандартных подсистем), а также рассмотрим проверенные способы решения этой проблемы с примерами готового кода.
Рассмотрим самую распространенную ошибку, связанную с фундаментальным пониманием работы платформы 1С с предопределенными объектами. В свойствах метаданных каждого регламентного задания в конфигураторе существует флаг «Предопределенное».
Выясним, как ведет себя платформа в зависимости от этого флага:
Проанализируем ошибочный код, который часто используют разработчики:
НовоеЗадание = РегламентныеЗадания.СоздатьРегламентноеЗадание(Метаданные.РегламентныеЗадания.ВыполнитьТестовоеЗаданиеПрограммно);
НовоеЗадание.ИмяПользователя = "Администратор";
// Настройка расписания...
НовоеЗадание.Использование = Истина;
НовоеЗадание.Записать();
Если для метаданных ВыполнитьТестовоеЗаданиеПрограммно в конфигураторе стоит признак «Предопределенное», то вызов метода СоздатьРегламентноеЗадание() пытается создать в базе данных второй (непредопределенный) экземпляр этого же задания. Это приводит к конфликту в планировщике фоновых заданий 1С: в системе оказывается два элемента, ссылающихся на один метод метаданных, причем планировщик ожидает работы с единственным предопределенным объектом. В результате созданный экземпляр зависает и не стартует по расписанию.
Как решить эту проблему правильно:
Если задание должно быть предопределенным, мы не должны вызывать метод СоздатьРегламентноеЗадание(). Вместо этого необходимо найти уже созданный платформой системный экземпляр, изменить его настройки (например, задать новое расписание) и записать изменения. Рассмотрим пример правильного кода:
ИмяЗадания = "ВыполнитьТестовоеЗаданиеПрограммно";
ПредопределенноеЗадание = РегламентныеЗадания.НайтиПредопределенное(Метаданные.РегламентныеЗадания[ИмяЗадания]);
Если ПредопределенноеЗадание <> Неопределено Тогда
// Настраиваем существующее предопределенное задание
ПредопределенноеЗадание.Использование = Истина;
// Создаем и назначаем расписание
НовоеРасписание = Новый РасписаниеРегламентногоЗадания;
НовоеРасписание.ПериодПовтораВТечениеДня = 60; // каждые 60 секунд
НовоеРасписание.ПериодНедель = 1;
ПредопределенноеЗадание.Расписание = НовоеРасписание;
ПредопределенноеЗадание.Записать();
КонецЕсли;
Если же вашей задаче действительно требуется создавать множество однотипных заданий с разными параметрами (например, под разные организации или разные узлы обмена), то в конфигураторе для этого регламентного задания флаг «Предопределенное» должен быть строго выключен.
Вторая частая причина кроется в особенностях инициализации объекта РасписаниеРегламентногоЗадания. Давайте детально посмотрим на то, как разработчики обычно заполняют расписание программно:
Расписание = Новый РасписаниеРегламентногоЗадания;
Расписание.ПериодПовтораВТечениеДня = 60;
Расписание.ВремяНачала = ТекущаяДата() + 300; // запуск через 5 минут
Расписание.ПериодНедель = 1;
НовоеЗадание.Расписание = Расписание;
На первый взгляд, все параметры указаны логично. Однако планировщик 1С очень чувствителен к незаполненным системным полям расписания. В некоторых версиях платформы, если вы явно не указываете периодичность повторения по дням (свойство ПериодПовтораДней) или дни недели (ДниНедели), планировщик инициализирует их значениями по умолчанию, которые могут интерпретироваться системой как «0 повторений» или «пустой список дней выполнения».
Почему ручная перезапись решает проблему?
Когда вы открываете это задание в стандартной «Консоли регламентных заданий» или любой другой внешней обработке администрирования, форма интерактивной настройки считывает незаполненные поля расписания и при сохранении принудительно подставляет валидные дефолтные значения (например, проставляет признак выполнения «Каждый день» и ПериодПовтораДней = 1). После сохранения интерактивной формой расписание становится корректным, и планировщик запускает задание.
Чтобы избежать этой проблемы, при программном формировании расписания всегда явно задавайте базовые календарные параметры выполнения:
Расписание = Новый РасписаниеРегламентногоЗадания;
Расписание.ПериодПовтораВТечениеДня = 60;
Расписание.ВремяНачала = ТекущаяДата() + 120;
// Явно задаем параметры повторения по дням и дни недели
Расписание.ПериодПовтораДней = 1; // Повторять каждый день
МассивДнейНедели = Новый Массив;
Для НомерДня = 1 По 7 Цикл
МассивДнейНедели.Добавить(НомерДня);
КонецЦикла;
Расписание.ДниНедели = МассивДнейНедели;
НовоеЗадание.Расписание = Расписание;
Современные конфигурации 1С практически никогда не работают на «чистой» платформе — они строятся на базе БСП. Подсистема «Регламентные задания» в БСП накладывает собственные жесткие правила администрирования поверх стандартных механизмов платформы.
БСП осуществляет сквозной мониторинг всех фоновых процессов через свои служебные регистры сведений и справочники. Если вы создаете задание «в обход» механизмов БСП стандартным методом платформы РегламентныеЗадания.СоздатьРегламентноеЗадание(), внутренняя программная среда конфигурации может заблокировать запуск этого задания или просто «не знать» о его существовании в своей очереди.
В ходе обсуждения на форуме было замечено, что вызов метода БСП РегламентныеЗаданияСервер.УстановитьИспользованиеРегламентногоЗадания() мгновенно решает проблему автоматического старта. Разберем по шагам, почему это происходит.
Под капотом данный метод БСП делает гораздо больше, чем простая запись объекта:
ВызватьИсключениеЕслиНетПраваАдминистрирования).Рекомендация: Если ваша конфигурация разработана на базе БСП (а это практически все типовые решения: ЕРП, КА, УТ, БП, ЗУП, УНФ), всегда выполняйте операции с регламентными заданиями через программный интерфейс (API) БСП. Используйте общий модуль РегламентныеЗаданияСервер вместо прямого обращения к глобальному контексту платформы.
// Пример корректной работы через БСП
ПараметрыЗадания = Новый Структура;
ПараметрыЗадания.Вставить("Использование", Истина;
ПараметрыЗадания.Вставить("Расписание", НовоеРасписание);
ПараметрыЗадания.Вставить("Параметры", МассивПараметров);
// БСП сама создаст или найдет задание, настроит его свойства и корректно зарегистрирует в планировщике
РегламентныеЗаданияСервер.ИзменитьРегламентноеЗадание(УникальныйИдентификаторЗадания, ПараметрыЗадания);
Еще один скрытый нюанс, который часто упускают из виду программисты — это выполнение кода создания регламентного задания внутри транзакции базы данных. Например, если вы создаете задание в обработчике события ПриЗаписи справочника или документа, весь ваш код выполняется в едином транзакционном блоке.
Выясним физику процесса на уровне СУБД:
НовоеЗадание.Записать(), запись физически фиксируется в системных таблицах базы данных только после успешного завершения всей транзакции (Commit).По этой причине старайтесь выносить программное создание и изменение регламентных заданий за пределы транзакционных блоков (например, выполняйте эти действия в обработчиках событий формы после записи объекта или используйте обработчики ожидания).
Если вы ведете разработку или тестирование механизма в файловой базе данных, необходимо учитывать специфику работы планировщика фоновых заданий в этом режиме:
Подведем итоги. Если ваше программно созданное регламентное задание не стартует само, выполните следующие шаги для локализации и устранения проблемы:
РегламентныеЗадания.НайтиПредопределенное() вместо СоздатьРегламентноеЗадание().РасписаниеРегламентногоЗадания, включая свойства ПериодПовтораДней и ДниНедели.РегламентныеЗаданияСервер.Соблюдение этих простых правил и понимание внутренней архитектуры платформы 1С позволит вам создавать надежные и стабильно работающие механизмы автоматизации бизнес-процессов.