К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как получить текущий бизнес-процесс в 1С

Как программно получить текущий бизнес-процесс в 1С из задачи, документа или формы: методы БизнесПроцессы, ПолучитьСсылку, проверка результата и типовые ошибки.

Получить текущий бизнес-процесс в 1С чаще всего нужно в двух ситуациях: когда из задачи требуется выйти на породивший её процесс, и когда из документа или другого объекта нужно найти запущенный по нему процесс. В обоих случаях работа ведётся через встроенный язык: у задачи есть реквизит БизнесПроцесс, а поиск по ведущему объекту выполняется запросом по реквизитам процесса.

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

Откуда можно получить ссылку на бизнес-процесс

Существует четыре типовых источника, из которых разработчик получает текущий бизнес-процесс. Первый — задача: у каждой задачи, созданной механизмом бизнес-процессов, обязательно заполнен реквизит БизнесПроцесс. Второй — объект-основание: у многих процессов есть реквизит типа «Предмет», «Документ» или «Заявка», по которому процесс ищется запросом. Третий — параметр сеанса или дополнительное свойство объекта, куда прикладной код сам сохранил ссылку на процесс. Четвёртый — карта маршрута и точки, через которые можно найти активные экземпляры.

Выбор источника зависит от контекста, в котором выполняется код. В обработчике задачи естественно брать процесс из реквизита задачи. В обработчике документа — искать процесс запросом. В регламентном задании или внешней обработке обычно перебирают все незавершённые процессы вида и фильтруют их дополнительно.

Получение процесса из задачи

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

ЗадачаСсылка = Параметры.Задача; // задача, с которой работаем

ТекущийПроцесс = ЗадачаСсылка.БизнесПроцесс;

Если ТекущийПроцесс.Пустая() Тогда

// задача не связана с процессом — такое бывает у задач, созданных вручную

Возврат;

КонецЕсли;

Если нужно не просто получить ссылку, а прочитать или изменить реквизиты процесса, вызывайте ПолучитьОбъект(). Помните, что это открывает объект для записи: изменения попадут в базу только после Записать(), а при конкурентной работе нескольких пользователей возможны блокировки.

Частая ситуация — получение процесса в форме задачи. Там ссылка доступна через реквизит формы: Объект.БизнесПроцесс. Дополнительно у задачи есть реквизит ТочкаМаршрута, который показывает, на каком шаге процесса находится выполнение — это удобно для проверки, та ли это стадия, которая ожидается.

bsl
ПроцессОбъект = ЗадачаСсылка.БизнесПроцесс.ПолучитьОбъект();
Если Не ПроцессОбъект.Завершен Тогда
    ПроцессОбъект.Комментарий = "Обновлено из задачи";
    ПроцессОбъект.Записать();
КонецЕсли;

Поиск процесса по документу или предмету

Когда код выполняется в контексте документа (например, в обработчике ПриЗаписи), задачи под рукой нет, и процесс ищут запросом по реквизиту-связке. Имя этого реквизита зависит от конфигурации: в типовых решениях встречаются «Предмет», «ДокументОснование», «Заявка» и другие варианты. Точное имя смотрите в метаданных конкретного вида бизнес-процесса.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Согласование.Ссылка КАК Процесс

|ИЗ

| БизнесПроцесс.СогласованиеЗаявки КАК Согласование

|ГДЕ

| Согласование.Предмет = &Предмет

| И НЕ Согласование.Завершен

| И НЕ Согласование.ПометкаУдаления";

Запрос.УстановитьПараметр("Предмет", ДокументСсылка);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

ТекущийПроцесс = Выборка.Процесс;

КонецЕсли;

Обратите внимание на фильтры: отсекать завершённые и помеченные на удаление процессы нужно почти всегда, иначе при повторных запусках по одному документу вы рискуете получить старый, уже закрытый экземпляр. Если по одному предмету допустимо несколько активных процессов, уберите ПЕРВЫЕ 1 и обрабатывайте выборку в цикле.

Получение списка активных процессов пользователя или вида

Для мониторинга и регламентных обработок нужен не один процесс, а все текущие экземпляры определённого вида. Запрос строится аналогично, но без отбора по предмету:

Запрос.Текст =

"ВЫБРАТЬ

| Процесс.Ссылка,

| Процесс.Дата,

| Процесс.Автор

|ИЗ

| БизнесПроцесс.СогласованиеЗаявки КАК Процесс

|ГДЕ

| Процесс.Стартован

| И НЕ Процесс.Завершен";

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

Порядок действий при поиске процесса по документу
  1. 1
    Откройте в конфигураторе вид бизнес-процесса и найдите реквизит, связывающий его с документом (Предмет, Основание и т.п.)
  2. 2
    Напишите запрос к таблице БизнесПроцесс.<Вид> с отбором по этому реквизиту
  3. 3
    Добавьте условия НЕ Завершен и НЕ ПометкаУдаления
  4. 4
    Выполните запрос и проверьте, что выборка не пуста
  5. 5
    Проверьте полученную ссылку: Пустая(), Завершен, Стартован
  6. 6
    Только после проверок вызывайте ПолучитьОбъект() и изменяйте данные

Проверка результата перед использованием

Полученная ссылка на бизнес-процесс требует обязательной проверки, иначе код будет падать в неочевидных местах. Минимальный набор проверок: ссылка не пустая, процесс не завершён, процесс стартован (если вы планируете работать с его задачами), объект существует в базе — ссылка не «битая».

Битая ссылка возникает, когда процесс был удалён, а ссылка на него осталась в другом объекте. Проверить её можно через ОбщегоНазначения.СсылкаСуществует() в типовых конфигурациях на БСП либо попыткой обращения к реквизиту в попытке-исключении. В самописных конфигурациях надёжнее обернуть обращение к объекту в Попытка ... Исключение и залогировать ошибку.

Контрольные точки

Как проверить полученный процесс

Ссылка не пустая
Норма

ТекущийПроцесс.Пустая() = Ложь

Тревожный признак

Пустая ссылка — задача без процесса или документ без запущенного согласования

Состояние процесса
Норма

Стартован = Истина, Завершен = Ложь

Тревожный признак

Завершен = Истина — процесс закрыт, изменять его поздно

Целостность ссылки
Норма

Реквизиты читаются без исключения

Тревожный признак

Ошибка обращения — объект удалён, ссылка битая

Точка маршрута задачи
Норма

ТочкаМаршрута соответствует ожидаемой стадии

Тревожный признак

Задача относится к другому шагу — логика обработчика неприменима

Типичные ошибки и ограничения

Самая распространённая ошибка — обращение Задача.БизнесПроцесс.Реквизит «через точку» к нескольким полям подряд. Каждое такое обращение через ссылку — отдельный запрос к базе. Если нужно прочитать несколько реквизитов процесса, получите объект один раз или выберите поля запросом.

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

Типичные ошибки
01
Чтение реквизитов процесса через точку от ссылки в цикле — множественные запросы к базе и падение производительности
02
Отсутствие фильтра по Завершен — получение старого закрытого экземпляра вместо текущего
03
ПолучитьОбъект() без последующей проверки Завершен — попытка изменить закрытый процесс
04
Игнорирование пометки удаления — в выборку попадают удалённые процессы
05
Поиск по реквизиту с именем, взятым 'по памяти' — в конкретной конфигурации реквизит может называться иначе

Частые вопросы

Можно ли получить бизнес-процесс из документа без запроса?

Только если в документе есть явный реквизит со ссылкой на процесс — тогда читайте его напрямую. Стандартного «обратного» механизма, по которому документ сам знает свой процесс, в платформе нет: связь хранится на стороне процесса, поэтому без специального реквизита в документе поиск выполняется запросом.

Чем отличается БизнесПроцессСсылка от БизнесПроцессОбъект?

Ссылка — лёгкий идентификатор, достаточный для сравнений, отборов и передачи между процедурами. Объект — загруженные в память данные процесса, которые можно читать и изменять. Получайте объект только когда нужно читать много реквизитов или что-то менять: это дороже и создаёт риск блокировок.

Как найти все задачи текущего бизнес-процесса?

Запросом к таблице Задача.<ВидЗадачи> с условием БизнесПроцесс = &Процесс. Добавьте отбор Выполнена = Ложь, если нужны только активные задачи. Сортировка по дате поможет определить текущую точку маршрута.

Почему реквизит БизнесПроцесс у задачи пустой?

Так бывает с задачами, созданными не механизмом процессов, а программно или вручную, если вид задачи в принципе допускает самостоятельное создание. Также проверьте, что задача относится к виду, связанному с бизнес-процессами в метаданных: у «свободных» задач этот реквизит может не заполняться по умолчанию.

Как получить текущий процесс в обработчике ПередЗаписью документа?

Через запрос по реквизиту-связке, отбирая по Ссылка документа. Учтите нюанс: при записи нового документа ссылка уже существует, но процесс мог быть запущен позже — проверяйте результат на пустоту. Если процесс стартует из этого же обработчика, сохраните полученную ссылку в ДополнительныеСвойства, чтобы не искать её повторно в подписанных обработчиках.

Что делать, если по документу найдено несколько активных процессов?

Это признак либо штатной ситуации (параллельные согласования), либо ошибки запуска — дублирования экземпляров. Разберитесь в логике старта: если по одному предмету должен быть один процесс, добавьте при запуске проверку существующего активного экземпляра тем же запросом, что описан в статье, и не создавайте новый.

Итог

Что важно запомнить

Из задачи текущий бизнес-процесс берётся через реквизит БизнесПроцесс, из документа — запросом по реквизиту-связке с обязательными фильтрами по Завершен и ПометкаУдаления. Полученную ссылку проверяйте на пустоту и состояние, а объект получайте только для чтения нескольких полей или изменения. Имя реквизита-связки всегда уточняйте в метаданных конкретной конфигурации.