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

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

В практике разработки на платформе 1С:Предприятие 8 часто возникает задача отойти от одного общего регламентного задания, которое обрабатывает все записи справочника скопом, в пользу индивидуальных заданий для каждого конкретного элемента. Это позволяет пользователям гибко настраивать расписание для каждой отдельной настройки, правила или объекта. Рассмотрим детально, как реализовать такой механизм на примере конфигурации Управление торговлей 10.3 (или любой другой на обычных формах).

Постановка задачи и архитектурный подход

Представим, что у нас есть справочник НастройкиИнтеграции. Ранее существовало одно предопределенное регламентное задание, которое раз в час обходило все элементы этого справочника. Теперь бизнес требует, чтобы для каждой настройки пользователь мог задать свое расписание (например, одну выгрузку делать раз в 15 минут, а другую — только ночью).

Для реализации этой схемы нам потребуется решить три основные задачи:

  1. Хранить связь между элементом справочника и регламентным заданием в базе данных.
  2. Реализовать интерфейс для настройки расписания пользователем.
  3. Обеспечить передачу ссылки на конкретный элемент справочника в процедуру-обработчик задания.

Шаг 1. Подготовка метаданных

Прежде всего, проанализируем, как мы будем идентифицировать «свое» задание. Самый надежный способ — хранить уникальный идентификатор (GUID) регламентного задания непосредственно в справочнике. Добавим в наш справочник новый реквизит:

Также нам понадобится не предопределенное регламентное задание в дереве метаданных (например, с именем ВыполнитьОбработкуНастройки), в котором мы укажем метод — экспортную процедуру в общем модуле.

Шаг 2. Программное создание и настройка задания

Разберем процесс создания задания при нажатии пользователем кнопки «Настроить расписание». Нам нужно проверить, создано ли задание ранее, и если нет — создать новое. Рассмотрим следующий пример кода:


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

    // Вызываем диалог настройки расписания
    Диалог = Новый ДиалогРасписанияРегламентногоЗадания(Задание.Расписание);
    Если Диалог.ОткрытьМодально() Тогда
        Задание.Расписание = Диалог.Расписание;
        Задание.Использование = Истина;
        Задание.Записать();
    КонецЕсли;

КонецПроцедуры

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

Шаг 3. Реализация обработчика в общем модуле

Теперь выясним, как принять этот параметр в самой процедуре выполнения. Процедура, указанная в метаданных регламентного задания, должна быть экспортной и находиться в серверном общем модуле. Количество формальных параметров в объявлении процедуры должно строго соответствовать количеству элементов в массиве Задание.Параметры.


// Общий модуль: МойМодульОбработки (Сервер, Внешнее соединение)
Процедура ВыполнитьОбработкуНастройки(СсылкаНаНастройку) Экспорт
    
    // Проверяем, что ссылка валидна
    Если СсылкаНаНастройку.Пустая() Тогда
        Возврат;
    КонецЕсли;
    
    // Основная логика обработки
    ЗаписьЖурналаРегистрации("РегламентноеЗадание", УровеньЖурналаРегистрации.Информация, , , 
        "Запущена обработка по настройке: " + Строка(СсылкаНаНастройку));
        
    // Здесь ваш код работы с элементом справочника...
    
КонецПроцедуры

Шаг 4. Управление жизненным циклом задания

Работа с программными заданиями требует аккуратности. Рассмотрим важные нюансы, которые часто упускают из виду:

1. Удаление задания: Если пользователь удаляет элемент справочника, регламентное задание останется в системе как «сирота» и будет продолжать запускаться, вызывая ошибки. Выясним, как этого избежать. В модуле объекта справочника следует добавить обработчик события ПередУдалением:


Процедура ПередУдалением(Отказ)
    Если ЗначениеЗаполнено(ИдентификаторРегламентногоЗадания) Тогда
        Попытка
            Задание = РегламентныеЗадания.НайтиПоУникальномуИдентификатору(Новый УникальныйИдентификатор(ИдентификаторРегламентногоЗадания));
            Если Задание <> Неопределено Тогда
                Задание.Удалить();
            КонецЕсли;
        Исключение
            // Обработка ошибки, если задание уже удалено или нет прав
        КонецПопытки;
    КонецЕсли;
КонецПроцедуры

2. Копирование элементов: При копировании элемента справочника значение GUID также скопируется. Это приведет к тому, что новый элемент будет управлять расписанием старого. Проанализируем решение: в обработчике ПриУстановкеНовогоКода или ПриКопировании необходимо очищать реквизит ИдентификаторРегламентногоЗадания.

3. Активность задания: Рекомендуется добавить в справочник флаг ИспользоватьРасписание. Синхронизируйте его со свойством Использование объекта РегламентноеЗадание. Это позволит пользователю временно отключать задание, не удаляя настройки расписания.

Ограничения и производительность

Хотя создание множества заданий кажется простым, рассмотрим технические риски:

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

← На главную