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

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

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

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

В языке запросов 1С нет типа «массив», поэтому напрямую использовать массив как таблицу нельзя. Однако есть несколько рабочих приёмов: передать массив параметром и отфильтровать данные оператором В, либо преобразовать массив в таблицу значений и поместить её во временную таблицу запроса через конструкцию ПОМЕСТИТЬ. Выбор зависит от задачи: для простой фильтрации достаточно параметра, а для соединений и сложной логики нужна именно таблица значений.

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

Почему массив нельзя использовать как таблицу напрямую

Язык запросов 1С оперирует таблицами: физическими таблицами базы данных, виртуальными таблицами регистров и временными таблицами. Тип «Массив» существует только во встроенном языке и не имеет представления в запросе. Поэтому конструкция вида ИЗ &Массив КАК Таб вызовет ошибку ещё на этапе проверки текста запроса.

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

Способ 1: фильтрация через параметр с массивом

Самый простой вариант — передать массив параметром и отфильтровать выборку условием В. Платформа автоматически раскроет массив в перечень значений.

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

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

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка,

| Номенклатура.Наименование КАК Наименование

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Ссылка В (&СписокНоменклатуры)";

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

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

Важные условия: все элементы массива должны быть сравнимы с полем отбора по типу (ссылки со ссылками, строки со строками), массив не должен быть пустым — иначе результат будет пустым, а в некоторых сценариях с составными типами возможна ошибка. Если массив может оказаться пустым, заранее проверьте его количество и либо пропустите выполнение запроса, либо подставьте заведомо «пустое» значение.

Условие можно инвертировать через НЕ В (&Массив) — так исключают из выборки уже обработанные элементы. Для составных полей (например, поле типа «документ нескольких видов») фильтрация по массиву работает, но индексация может быть менее эффективной, о чём стоит помнить на больших таблицах.

Способ 2: преобразование массива в таблицу значений

Когда массив нужен как полноценная таблица — для соединений, группировок, сохранения порядка или передачи нескольких колонок — его преобразуют в таблицу значений. Создаётся таблица с одной колонкой нужного типа, затем в цикле добавляются строки.

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

ТаблицаЗначений.Колонки.Добавить("Ссылка",

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

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

НоваяСтрока = ТаблицаЗначений.Добавить();

НоваяСтрока.Ссылка = Элемент;

КонецЦикла;

Описание типов колонки задавайте явно и максимально точно. Если оставить колонку без типа или с составным типом «что угодно», запрос может работать медленнее, а при помещении во временную таблицу платформа не сможет построить оптимальный план. Для строковых колонок указывайте длину строки — неограниченная строка в параметре запроса приводит к ограничениям при сравнении и соединениях.

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

Помещение таблицы значений во временную таблицу запроса

Таблица значений передаётся в запрос обычным параметром, а в тексте запроса помещается во временную таблицу через ПОМЕСТИТЬ. Дальше с ней работают как с любой таблицей: соединяют, группируют, фильтруют.

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

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

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

"ВЫБРАТЬ

| Таб.Ссылка КАК Ссылка

|ПОМЕСТИТЬ ВТ_Номенклатура

|ИЗ

| &ТаблицаНоменклатуры КАК Таб

|;

|

|ВЫБРАТЬ

| ВТ.Ссылка КАК Ссылка,

| ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток

|ИЗ

| ВТ_Номенклатура КАК ВТ

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

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

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

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

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

Порядок передачи массива как таблицы
  1. 1
    Создайте таблицу значений с колонками точных типов
  2. 2
    Заполните её в цикле из массива
  3. 3
    Создайте запрос и менеджер временных таблиц
  4. 4
    В тексте запроса поместите параметр-таблицу во временную таблицу через ПОМЕСТИТЬ
  5. 5
    Используйте временную таблицу в соединениях и отборах
  6. 6
    Проверьте результат через Выгрузить() и количество строк

Сравнение подходов и типичные ошибки

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

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

Параметр с массивом и условие В

Подходит для простой фильтрации по одному полю. Нельзя соединять, группировать и передавать несколько колонок.

Таблица значений во временную таблицу

Подходит для соединений, группировок и многоколоночных данных. Требует больше кода и точного описания типов колонок.

Менеджер временных таблиц между запросами

Подходит, когда набор данных используется в нескольких запросах подряд. Требует освобождения ресурсов после работы.

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

Типичные ошибки
01
Передача пустого массива в условие В — запрос возвращает пустой результат, и это выглядит как «данные пропали»
02
Колонка таблицы значений без типа или с неограниченной строкой — ошибки сравнения и медленные соединения
03
Обращение к временной таблице из другого запроса без общего менеджера временных таблиц — ошибка «таблица не найдена»
04
Дубли в массиве при соединении — задвоение строк результата; уберите дубли через свёртку или РАЗЛИЧНЫЕ
05
Смешение типов в массиве (ссылки разных справочников) — неочевидные пропуски строк при фильтрации

Проверка результата и отладка

После выполнения запроса первичная проверка — количество строк результата относительно количества элементов исходного массива. Если передали 100 ссылок, а получили 97, значит часть ссылок не прошла отбор или не нашла пары в соединении. Для поиска «потерянных» элементов удобно выгрузить результат в таблицу значений и свернуть по полю ссылки, а затем сравнить с исходным массивом в цикле.

Для отладки временных таблиц используйте отдельный запрос к менеджеру временных таблиц: текст ВЫБРАТЬ * ИЗ ВТ_Номенклатура с тем же менеджером покажет содержимое временной таблицы после выполнения основного пакета. В консоли запросов конфигуратора параметр-таблицу можно заполнить вручную и проверить текст запроса до переноса в код.

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

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

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

Количество строк результата
Норма

Совпадает с ожиданием с учётом соединений

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

Строк больше — дубли; меньше — потеряны элементы

Содержимое временной таблицы
Норма

Все загруженные значения присутствуют

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

Часть значений отсутствует или NULL

Типы колонок
Норма

Тип колонки совпадает с типом поля соединения

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

Составной тип или неограниченная строка

Ограничения и альтернативы

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

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

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

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

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

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

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

Видна ли временная таблица в следующем запросе?

Только если оба запроса используют один и тот же менеджер временных таблиц. Создайте менеджер один раз и присвойте его каждому объекту запроса. После завершения работы вызовите метод Закрыть() у менеджера.

Почему соединение с временной таблицей работает медленно?

Частые причины: колонка без точного описания типов, неограниченная длина строки, дубли значений и отсутствие индекса по полю соединения в основной таблице. Задайте типы явно, уберите дубли и проверьте план запроса.

Как сохранить порядок элементов исходного массива?

Добавьте в таблицу значений числовую колонку с номером элемента и заполняйте её в цикле. В запросе отсортируйте результат по этой колонке через УПОРЯДОЧИТЬ ПО.

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

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

Итог

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

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