Как выбрать несколько значений в параметре запроса 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке на платформе 1С часто возникает ситуация, когда необходимо отфильтровать данные в запросе не по одному конкретному значению (например, одному складу), а сразу по нескольким. Проанализируем ситуацию, с которой сталкиваются многие разработчики: в тексте запроса используется оператор В ИЕРАРХИИ, но при попытке передать параметр стандартным образом фильтрация срабатывает только по одному элементу, и пользователь не может выбрать нужный список. Разберем по шагам, как правильно модифицировать запрос и интерфейс, чтобы дать возможность выбора произвольного количества элементов.

Использование массива для передачи нескольких параметров

Если нам нужно программно сформировать список элементов и передать его в запрос, самым простым и логичным решением будет использование объекта Массив. Рассмотрим подробнее этот подход. Оператор языка запросов В ИЕРАРХИИ, как и оператор В, отлично умеет работать с коллекциями.

Посмотрим на пример реализации в коде, протестировать который поможет Консоль запросов для управляемых форм 8.3 (поможет универсальная консоль запросов для управляемых форм):


МассивСкладов = Новый Массив;
МассивСкладов.Добавить(Склад1);
МассивСкладов.Добавить(Склад2);

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ПеремещениеТоваров.Ссылка КАК Документ,
    |    ПеремещениеТоваров.СкладПолучатель КАК СкладПолучатель
    |ИЗ
    |    Документ.ПеремещениеТоваров КАК ПеремещениеТоваров
    |ГДЕ
    |    ПеремещениеТоваров.СкладПолучатель В ИЕРАРХИИ(&МассивСкладов)";

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

В этом случае платформа сама развернет массив и применит условие ко всем переданным складам и их подчиненным элементам. Для быстрой генерации подобных конструкций пригодится Консоль кода + ИИ-помощник (GigaChat) — есть готовый ИИ-ассистент для написания кода и запросов.

Использование списка значений для интерактивного выбора

Выясним причину, почему первый вариант не всегда подходит. Если список складов (или других объектов) должен определять сам пользователь перед выполнением запроса, использовать массив неудобно, так как массив не имеет визуального представления для формы. В таком случае мы применим СписокЗначений.

Рассмотрим, как настроить интерфейс:

  1. Создайте реквизит формы с типом СписокЗначений.
  2. В свойствах этого реквизита в поле «Тип значения» укажите нужный тип, например, СправочникСсылка.Склады.
  3. Выведите этот реквизит на форму. Платформа автоматически создаст элемент управления, в котором пользователь сможет нажимать кнопку «Подбор» и добавлять произвольное количество складов.

Интересная особенность платформы заключается в том, что вам не нужно перебирать СписокЗначений циклом, чтобы переложить ссылки в Массив. Запрос корректно отработает, если передать список значений в параметр напрямую:


// РеквизитФормыСписокСкладов - это заполненный пользователем СписокЗначений
Запрос.УстановитьПараметр("МассивСкладов", РеквизитФормыСписокСкладов);

Опасность пустых коллекций: почему запросы начинают тормозить

Проанализируем важный технический нюанс, который нельзя игнорировать при работе с коллекциями в параметрах запроса. Для программной модификации условий полезно использовать Процессор схемы запроса. Перед тем как передавать Массив или СписокЗначений в запрос, обязательно проверяйте их на заполненность.

Если передать в конструкцию В ИЕРАРХИИ или просто В пустую коллекцию, это может привести к серьезным проблемам. В зависимости от версии платформы, запрос может либо выдать ошибку, либо начать сканировать таблицы на принадлежность к пустой ссылке. Это вызывает катастрофическое падение производительности.

Правильный подход выглядит так:


Если РеквизитФормыСписокСкладов.Количество() = 0 Тогда
    // Обработка ситуации: прерываем выполнение или динамически удаляем условие из текста запроса
    Возврат;
КонецЕсли;

Как это работает на уровне СУБД

Разберем, что происходит «под капотом», когда вы используете В ИЕРАРХИИ с коллекцией значений. В классическом SQL нет прямого аналога этому оператору. Когда 1С транслирует ваш запрос в SQL, для оператора В ИЕРАРХИИ создаются временные таблицы. Платформа выполняет рекурсивные выборки, чтобы собрать все дочерние узлы для каждого из переданных родителей.

Если вы передаете очень большой список элементов или дерево справочника имеет огромную вложенность, выполнение такого запроса займет много времени. Поэтому при проектировании старайтесь ограничивать размер списка, который может выбрать пользователь.

Оптимальное решение: Использование СКД или Динамических списков

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

Воспользуйтесь Системой Компоновки Данных (СКД). Посмотрим на преимущества этого подхода:

  1. Вам достаточно написать простейший запрос без жестко заданных условий в секции ГДЕ.
  2. В настройках СКД вы выводите поле «Склад» в пользовательские настройки.
  3. Пользователь сам выбирает вид сравнения: В списке или В группе из списка.
  4. Платформа автоматически сгенерирует удобный интерфейс с подбором значений и сформирует наиболее оптимальный SQL-запрос к базе данных.

Таким образом, использование встроенных механизмов СКД избавляет разработчика от лишнего кода. Например, можно реализовать скрытие пустых столбцов в СКД, если данных нет.

← На главную