К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как передать массив в параметр запроса 1С

Как передать массив в параметр запроса 1С: метод УстановитьПараметр, работа с В(), списком значений и таблицей значений. Примеры кода и типичные ошибки.

Передача массива в параметр запроса — одна из самых частых задач при разработке на платформе 1С. Типичный сценарий: у вас есть список контрагентов, номенклатуры или документов, и нужно одним запросом отобрать данные по всем этим элементам, а не перебирать их в цикле с отдельными запросами.

Механизм прост: запрос 1С поддерживает оператор В (&ИмяПараметра), а сам параметр заполняется методом УстановитьПараметр(), которому можно передать массив, список значений или таблицу значений. Платформа автоматически преобразует коллекцию в набор значений для условия отбора.

Ниже разобраны рабочие примеры кода, отличия между типами коллекций, ограничения механизма и ошибки, которые чаще всего приводят к пустой выборке или падению запроса.

Базовый пример: массив в параметре запроса

Минимальный рабочий сценарий выглядит так: создаём массив, заполняем его ссылками, формируем запрос с условием В (&Параметр) и передаём коллекцию.

МассивКонтрагентов = Новый Массив;

МассивКонтрагентов.Добавить(Контрагент1);

МассивКонтрагентов.Добавить(Контрагент2);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| РеализацияТоваровУслуг.Ссылка КАК Документ

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

|ГДЕ

| РеализацияТоваровУслуг.Контрагент В (&Контрагенты)";

Запрос.УстановитьПараметр("Контрагенты", МассивКонтрагентов);

Результат = Запрос.Выполнить().Выгрузить();

Обратите внимание: имя параметра в методе УстановитьПараметр() указывается без амперсанда, а в тексте запроса — с амперсандом. Перепутать эти два написания — одна из самых распространённых ошибок новичков.

Что можно передать вместо массива

Платформа принимает в параметр, используемый с оператором В, три типа коллекций: массив, список значений и таблицу значений. Выбор зависит от того, в каком виде данные уже есть в вашем коде.

Список значений

Удобен, когда данные приходят из элемента формы или когда нужно дополнительно хранить представления элементов:

СписокНоменклатуры = Новый СписокЗначений;

СписокНоменклатуры.Добавить(Номенклатура1);

СписокНоменклатуры.Добавить(Номенклатура2);

Запрос.УстановитьПараметр("Номенклатура", СписокНоменклатуры);

Таблица значений

Если передать таблицу значений с одной колонкой, платформа возьмёт значения из этой колонки. Если колонок несколько, поведение зависит от контекста, поэтому надёжнее передавать таблицу с единственной колонкой либо выгрузить колонку в массив:

МассивИзТаблицы = ТаблицаТоваров.ВыгрузитьКолонку("Номенклатура");

Запрос.УстановитьПараметр("Номенклатура", МассивИзТаблицы);

Сравнение вариантов

Массив

Универсальный вариант, когда данные собираются в коде вручную или получены из ВыгрузитьКолонку(). Самый предсказуемый тип.

Список значений

Подходит, когда данные уже хранятся в списке значений на форме. Дополнительно несёт представления элементов.

Таблица значений

Оправдана, когда нужно не просто отобрать, а соединить данные запроса с таблицей через временную таблицу. Для простого отбора В избыточна.

Отбор по нескольким условиям и вложенные коллекции

Оператор В поддерживает и составной отбор — когда нужно сравнить сразу несколько полей с наборами значений. Для этого в параметр передаётся массив массивов, а в запросе перечисляются поля в скобках:

МассивПар = Новый Массив;

Пара1 = Новый Массив;

Пара1.Добавить(Склад1);

Пара1.Добавить(Номенклатура1);

МассивПар.Добавить(Пара1);

Запрос.Текст =

"ВЫБРАТЬ

| ТоварыНаСкладах.КоличествоОстаток

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладах

|ГДЕ

| (ТоварыНаСкладах.Склад, ТоварыНаСкладах.Номенклатура) В (&Пары)";

Запрос.УстановитьПараметр("Пары", МассивПар);

Такой приём полезен, когда нужно отобрать остатки по конкретным сочетаниям «склад + товар», а не по всем комбинациям двух независимых списков. Однако на практике для составных условий чаще используют временные таблицы — запрос получается читабельнее и лучше оптимизируется СУБД.

Передача массива через временную таблицу

Когда массив большой (тысячи элементов) или по нему нужно соединение с другими данными, правильнее поместить коллекцию во временную таблицу через менеджер временных таблиц:

ТаблицаОтбора = Новый ТаблицаЗначений;

ТаблицаОтбора.Колонки.Добавить("Номенклатура",

Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));

Для Каждого Элемент Из МассивНоменклатуры Цикл

Строка = ТаблицаОтбора.Добавить();

Строка.Номенклатура = Элемент;

КонецЦикла;

Запрос = Новый Запрос;

Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

Запрос.Текст =

"ВЫБРАТЬ

| Отбор.Номенклатура КАК Номенклатура

|ПОМЕСТИТЬ ВТ_Отбор

|ИЗ

| &ТаблицаОтбора КАК Отбор

|;

|ВЫБРАТЬ

| Остатки.КоличествоОстаток

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Отбор КАК Отбор

| ПО Остатки.Номенклатура = Отбор.Номенклатура";

Запрос.УстановитьПараметр("ТаблицаОтбора", ТаблицаОтбора);

Здесь таблица значений передаётся как источник данных в конструкции ИЗ &ТаблицаОтбора — это отдельный механизм, отличный от оператора В. Он требует явного описания колонок с типами, иначе платформа не сможет построить временную таблицу.

Порядок действий
  1. 1
    Сформируйте массив нужных значений (ссылок, строк, чисел)
  2. 2
    В тексте запроса добавьте условие ГДЕ Поле В (&ИмяПараметра)
  3. 3
    Вызовите Запрос.УстановитьПараметр("ИмяПараметра", Массив) без амперсанда в имени
  4. 4
    Выполните запрос и проверьте, что выборка не пустая
  5. 5
    Если элементов очень много или нужно соединение — перенесите отбор во временную таблицу

Типичные ошибки и ограничения

Первая частая проблема — пустой массив. Условие Поле В (&Параметр) с пустой коллекцией не даёт ошибку, но и не возвращает ни одной строки. Если параметр заполняется динамически, всегда проверяйте Массив.Количество() > 0 или добавляйте в запрос альтернативное условие.

Вторая ошибка — смешение типов внутри массива. Если в коллекции одновременно лежат ссылки разных типов или ссылки вперемешку со строками, отбор может работать не так, как ожидается, а на некоторых СУБД запрос завершится ошибкой. Перед передачей приводите элементы к одному типу.

Третий момент — производительность. Очень большие списки в операторе В разворачиваются в громоздкое условие, что увеличивает время компиляции запроса на СУБД. При объёмах от нескольких тысяч элементов переходите на временные таблицы.

Типичные ошибки
01
Амперсанд в имени параметра: УстановитьПараметр("&Контрагенты", ...) — параметр не найдётся, запрос упадёт с ошибкой
02
Равенство вместо В: Поле = &Массив — ошибка исполнения, так как поле нельзя сравнить с коллекцией
03
Передача незаполненного массива без проверки — запрос молча возвращает пустой результат
04
Дубли в массиве — не ломают запрос, но увеличивают условие отбора; перед передачей полезно свернуть массив
05
Передача таблицы значений без описания типов колонок во временную таблицу — платформа не сможет определить типы полей

Как проверить, что параметр сработал правильно

Самый быстрый способ — вывести результат запроса и сопоставить с ожиданиями. Если выборка пустая, проверьте три вещи: не пуст ли массив, совпадают ли типы значений в массиве с типом поля отбора и правильно ли записано имя параметра в обоих местах.

Для отладки удобно временно заменить отбор на вывод самого параметра через временную таблицу или выполнить запрос в консоли запросов с теми же параметрами. В управляемом приложении также помогает вывод содержимого массива в журнал регистрации перед выполнением запроса.

Контрольные точки

Как проверить результат

Состав выборки
Норма

Возвращены строки по всем элементам массива, по которым есть данные

Тревожный признак

Выборка пустая хотя данные точно есть — проверяйте типы и имя параметра

Типы значений
Норма

Все элементы массива одного типа, совпадающего с типом поля отбора

Тревожный признак

Смешаны ссылки разных видов или ссылки со строками

Объём отбора
Норма

Запрос выполняется быстро, план запроса использует индекс по полю

Тревожный признак

Заметная задержка при тысячах элементов — переходите на временную таблицу

Частые вопросы

Можно ли передать массив в параметр динамического списка?

Да, но через отбор динамического списка, а не через параметр запроса: используйте элемент отбора с видом сравнения «В списке» и передайте список значений в правое значение. Если список построен на произвольном запросе с параметром, параметр устанавливается через свойство Параметры динамического списка.

Что произойдёт, если передать пустой массив?

Ошибки не будет, но условие В не выполнится ни для одной строки — запрос вернёт пустой результат. Если пустой отбор должен означать «без ограничений», добавьте в запрос конструкцию вида ГДЕ (&ИспользоватьОтбор = ЛОЖЬ ИЛИ Поле В (&Массив)) с дополнительным булевым параметром.

Работает ли передача массива в СКД?

Да. В схеме компоновки данных параметр, используемый в условии В, может принимать массив или список значений. В настройках СКД для такого параметра обычно включают флаг «Доступен список значений», чтобы пользователь мог выбрать несколько элементов в отчёте.

Можно ли передать массив структур или массив массивов?

Структуры передать нельзя — параметр запроса принимает только простые значения, ссылки и коллекции простых значений. Массив массивов допустим, но только для составного условия вида (Поле1, Поле2) В (&Параметр), где каждый вложенный массив задаёт одну комбинацию значений.

Есть ли ограничение на количество элементов в массиве?

Жёсткого документированного лимита со стороны платформы нет, но практическая граница определяется СУБД: при очень больших списках растёт время компиляции запроса и возможны ошибки из-за слишком длинного текста запроса на сервере баз данных. При объёмах от нескольких тысяч элементов надёжнее использовать временные таблицы.

Чем отличается В от В ИЕРАРХИИ при работе с массивом?

Оператор В ИЕРАРХИИ отбирает не только сами элементы из массива, но и все их подчинённые элементы в иерархическом справочнике. Массив передаётся точно так же — через УстановитьПараметр, меняется только текст условия.

Итог

Что важно запомнить

Массив передаётся через УстановитьПараметр и используется только с оператором В. Имя параметра пишется без амперсанда в коде и с амперсандом в тексте запроса. Проверяйте массив на пустоту и единообразие типов, а при больших объёмах данных переходите на временные таблицы.