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