Как настроить регламентное задание, которое запускается по результату готовности данных?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработки на платформе 1С:Предприятие 8.3 часто возникает потребность в создании сложных цепочек процессов и полноценных конвейеров задач. Типичная ситуация: первое регламентное задание инициирует длительную подготовку данных (например, формирование сложной выборки или запрос к внешней системе), а второе должно обработать этот результат сразу после его готовности. Основная сложность заключается в том, чтобы избежать «холостых» запусков и не занимать ресурсы сервера бессмысленными проверками каждые несколько минут.

В этой статье мы подробно разберем несколько стратегий реализации такой логики: от классических методов с использованием регистров до продвинутых инструментов Библиотеки стандартных подсистем (БСП) и динамического управления фоновыми заданиями.

Метод 1. Использование «Очереди» через регистр сведений

Рассмотрим самый надежный и простой в реализации метод, предложенный участниками сообщества. Суть заключается в использовании промежуточного объекта — Регистра сведений, который будет выступать в роли очереди или флага готовности.

Алгоритм работы:

  1. Первое регламентное задание (Инициатор) завершает подготовку данных (например, сложной модели объекта) и записывает результат (или просто признак готовности) в регистр сведений.
  2. Второе регламентное задание (Обработчик) настроено на запуск с коротким интервалом (например, раз в 1 минуту).
  3. В коде Обработчика первой строкой идет проверка наличия записей в регистре.
  4. Если записей нет — задание мгновенно завершается, не создавая нагрузки.
  5. Если записи есть — выполняется обработка, после чего регистр очищается.

Проанализируем пример кода для обработки такой очереди:


Процедура ВыполнитьОбработкуДанных() Экспорт
    // Проверяем наличие заданий в нашей "очереди"
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |   ОчередьЗаданий.ОбъектДанных,
        |   ОчередьЗаданий.Параметры
        |ИЗ
        |   РегистрСведений.ОчередьОбработкиДанных КАК ОчередьЗаданий";
    
    РезультатЗапроса = Запрос.Выполнить();
    Если РезультатЗапроса.Пустой() Тогда
        Возврат; // Выходим сразу, если работы нет
    КонецЕсли;

    Выборка = РезультатЗапроса.Выбрать();
    Пока Выборка.Следующий() Цикл
        // Основная логика обработки данных
        ОбработатьРезультат(Выборка.ОбъектДанных);
        
        // Очищаем запись, чтобы не обрабатывать повторно
        МенеджерЗаписи = РегистрыСведений.ОчередьОбработкиДанных.СоздатьМенеджерЗаписи();
        МенеджерЗаписи.ОбъектДанных = Выборка.ОбъектДанных;
        МенеджерЗаписи.Удалить();
    КонецЦикла;
КонецПроцедуры

Этот метод хорош тем, что он отказоустойчив. Даже если сервер перезагрузится, запись в регистре останется, и задание выполнится при первой возможности.

Метод 2. Программный запуск фонового задания

Выясним, как сделать систему более динамичной. Если мы не хотим плодить лишние записи в журнале регистрации от постоянно запускающегося регламентного задания, мы можем использовать метод ФоновыеЗадания.Выполнить(). В этом случае второе задание вообще не существует в списке регламентных, а создается «на лету».

Рассмотрим подробнее сценарий: первое задание в конце своей работы вызывает процедуру второго задания напрямую в фоновом потоке.


// Код внутри первого регламентного задания
Процедура ИнициализироватьВыборку() Экспорт
    // ... длительный процесс подготовки данных ...
    РезультатГотов = СформироватьМассивДанных();
    
    Если РезультатГотов Тогда
        // Запускаем обработку немедленно в фоновом режиме
        НаименованиеЗадания = "Обработка подготовленной выборки";
        ПараметрыЗадания = Новый Массив;
        ПараметрыЗадания.Добавить(ИмяЭтойВыборки);
        
        ФоновыеЗадания.Выполнить("МодульОбработки.ВыполнитьДействие", ПараметрыЗадания, , НаименованиеЗадания);
    КонецЕсли;
КонецПроцедуры

Преимущество: Второе задание запускается ровно в тот момент, когда оно нужно. Журнал регистрации будет чистым, а ресурсы сервера будут использоваться максимально эффективно.

Метод 3. Механизм «Очередь заданий» в БСП

Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), настоятельно рекомендуем использовать штатный механизм очереди. Это наиболее профессиональный подход к управлению зависимыми процессами.

Разберем по шагам, как это работает через БСП (включая вызовы из дополнительных обработок):

  1. Вместо прямого вызова фонового задания, вы добавляете запись в таблицу ОчередьЗаданий.
  2. Система сама управляет распределением ресурсов, количеством потоков и повторными попытками в случае ошибки.
  3. Вы можете задать условие, что задание должно выполниться не «сейчас», а, например, через 5 минут после готовности данных, просто указав время начала.

Для реализации используется метод ОчередьЗаданий.ДобавитьЗадание(). Это позволяет избежать ситуации, когда слишком много фоновых процессов запускаются одновременно и «вешают» сервер.

Метод 4. Динамическое управление расписанием

Иногда требуется, чтобы регламентное задание все же существовало в списке, но работало только по сигналу. Мы можем программно управлять свойством Использование объекта РегламентноеЗадание.

Проанализируем ситуацию: второе задание обычно выключено. Первое задание, завершив работу, находит второе в списке и включает его, либо устанавливает ему время следующего запуска на «через 10 секунд».


// Пример изменения расписания другого регламентного задания
МетаданныеЗадания = Метаданные.РегламентныеЗадания.ОбработкаРезультатов;
НайденныеЗадания = РегламентныеЗадания.ПолучитьРегламентныеЗадания(МетаданныеЗадания);

Для Каждого Задание Из НайденныеЗадания Цикл
    // Устанавливаем запуск на текущий момент
    НовоеРасписание = Новый РасписаниеРегламентногоЗадания;
    НовоеРасписание.ДатаНачала = ТекущаяДата();
    
    Задание.Расписание = НовоеРасписание;
    Задание.Использование = Истина;
    Задание.Записать();
КонецЦикла;

Важный момент: второе задание в конце своего выполнения должно снова установить Использование = Ложь, чтобы не зациклиться.

Метод 5. Ожидание завершения (WaitCompletion)

Если подготовка данных запущена как фоновый процесс внутри одного сеанса, можно использовать метод ОжидатьЗавершения(). Это заставляет основной поток «замереть» до тех пор, пока подчиненный процесс не вернет результат.

Важно: Мы не рекомендуем этот метод для очень длительных процессов (более 20-30 минут), так как всё это время за регламентным заданием будет зарезервирован сеанс и лицензия, которые фактически будут простаивать в ожидании.

Подведение итогов

Выбор конкретного метода зависит от архитектуры вашей системы:

Помните, что избыточное количество регламентных заданий, запускающихся раз в секунду, может существенно раздуть Журнал регистрации. Всегда старайтесь минимизировать количество «пустых» прогонов кода.

← На главную