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