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