При программной работе с бизнес-процессами в 1С разработчики часто сталкиваются с двумя важными задачами: дозаполнением реквизитов сформированных задач сразу после старта процесса и организацией автозапуска бизнес-процесса по индивидуальному расписанию для конкретных справочников. Рассмотрим подробно способы решения обеих задач.
Разберем ситуацию, когда бизнес-процесс успешно создан и запущен программно методом Старт(), но после этого требуется автоматически заполнить определенные реквизиты у сформированных задач.
Существует несколько основных подходов к решению этой проблемы:
Выборка сформированных задач с помощью запроса. Этот вариант подходит, если дозаполнение реквизитов выполняется из внешнего модуля (например, обработки) сразу после старта бизнес-процесса, а обработчики самой задачи по каким-то причинам использовать нельзя.
Посмотрим, как выполнить выборку активных задач по ссылке на бизнес-процесс и заполнить их реквизиты:
// Получаем задачи, сформированные для созданного бизнес-процесса
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Задача.Ссылка КАК Ссылка
|ИЗ
| Задача.ЗадачаИсполнителя КАК Задача
|ГДЕ
| Задача.БизнесПроцесс = &БизнесПроцесс
| И Задача.Выполнена = ЛОЖЬ";
Запрос.УстановитьПараметр("БизнесПроцесс", СсылкаНаБП);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
ОбъектЗадача = Выборка.Ссылка.ПолучитьОбъект();
// Заполняем необходимые реквизиты задачи
ОбъектЗадача.Описание = "Дополнительная информация";
ОбъектЗадача.Записать();
КонецЦикла;
Использование обработчиков событий бизнес-процесса и задач. Это наиболее правильный с точки зрения архитектуры подход. В модуле бизнес-процесса предусмотрены специальные процедурные события точки маршрута, такие как ПередСозданиемЗадач и ПриСозданииЗадач.
В этих обработчиках передается параметр ФормируемыеЗадачи — массив еще не записанных объектов задач (ЗадачаОбъект). Это позволяет напрямую заполнять реквизиты, приоритеты и параметры адресации до фактического помещения задач в базу данных:
Процедура Точка1ПриСозданииЗадач(ТочкаМаршрута, ФормируемыеЗадачи, СтандартнаяОбработка)
Для Каждого ЗадачаОбъект Из ФормируемыеЗадачи Цикл
ЗадачаОбъект.Важность = Перечисления.ВариантыВажностиЗадачи.Высокая;
ЗадачаОбъект.Описание = "Сформировано автоматически при старте процесса";
КонецЦикла;
КонецПроцедуры
Заполнение при инициализации задачи в обработчике ОбработкаЗаполнения. В модуле объекта самой задачи можно переопределить процедуру ОбработкаЗаполнения, чтобы при вызове метода Заполнить() или явной генерации задачи реквизиты заполнялись на основании передаваемых параметров или структуры данных бизнес-процесса.
Проанализируем вторую задачу: требуется связать бизнес-процесс с конкретным элементом справочника, чтобы бизнес-процесс запускался по индивидуальному расписанию, настроенному для этого элемента.
Рассмотрим два возможных архитектурных подхода к реализации данного механизма:
Создание индивидуальных регламентных заданий для каждого элемента справочника. При записи элемента справочника программно создается уникальное регламентное задание (объект РегламентноеЗадание), а его идентификатор (GUID) сохраняется в реквизите элемента. Пользователю предоставляется диалоговое окно ДиалогРасписанияРегламентногоЗадания для комфортной настройки расписания.
Важно: Данный подход целесообразен только при небольшом числе элементов справочника. Если справочник содержит сотни или тысячи записей, создавать отдельные регламентные задания не рекомендуется, так как это создает избыточную нагрузку на менеджер фоновых заданий платформы.
Использование единого регламентного задания и хранилища расписания (рекомендуемый способ). Более универсальное и масштабируемое решение заключается в следующем:
1. В справочнике добавляется реквизит с типом ХранилищеЗначения для сохранения объекта расписания, настроенного через ДиалогРасписанияРегламентногоЗадания.
2. Создается одно общее регламентное задание, которое запускается с частой периодичностью (например, раз в 1–5 минут).
3. Процедура регламентного задания выбирает все элементы справочника с включенным автозапуском, извлекает объект расписания и проверяет необходимость запуска вызовом метода Расписание.ТребуетсяВыполнить(ТекущаяДата()).
4. Если метод возвращает значение Истина, фоновое задание программно создает и стартует связанный бизнес-процесс, после чего фиксирует дату последнего запуска.
Выясним, как выглядит пример проверки расписания в процедуре единого регламентного задания:
// Пример проверки расписания в процедуре единого регламентного задания
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Спр.Ссылка КАК Ссылка,
| Спр.РасписаниеЗапуска КАК ХранилищеРасписания,
| Спр.ДатаПоследнегоЗапуска КАК ДатаПоследнегоЗапуска
|ИЗ
| Справочник.Проекты КАК Спр
|ГДЕ
| Спр.ИспользоватьАвтозапуск = ИСТИНА";
Выборка = Запрос.Выполнить().Выбрать();
ТекущаяМомент = ТекущаяДата();
Пока Выборка.Следующий() Цикл
Расписание = Выборка.ХранилищеРасписания.Получить();
Если Расписание <> Неопределено Тогда
// Проверяем, наступило ли время запуска
Если Расписание.ТребуетсяВыполнить(ТекущаяМомент, Выборка.ДатаПоследнегоЗапуска) Тогда
// Программно создаем и запускаем бизнес-процесс
БП = БизнесПроцессы.Согласование.СоздатьБизнесПроцесс();
БП.Предмет = Выборка.Ссылка;
БП.Записать();
БП.Старт();
// Фиксируем дату последнего запуска в справочнике
ОбъектСпр = Выборка.Ссылка.ПолучитьОбъект();
ОбъектСпр.ДатаПоследнегоЗапуска = ТекущаяМомент;
ОбъектСпр.Записать();
КонецЕсли;
КонецЕсли;
КонецЦикла;
Таким образом, комбинируя штатные обработчики событий бизнес-процессов с регулярной проверкой расписаний через единое фоновое задание, можно построить надежную и гибкую архитектуру автоматизации процессов в 1С.