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