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