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