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

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

Как передать таблицу значений в запрос в 1С 8

Как передать таблицу значений в запрос 1С 8 через параметр, поместить во временную таблицу и использовать в выборке. Примеры кода, ошибки и ограничения.

Передача таблицы значений в запрос — стандартный приём в 1С 8.3, который позволяет отфильтровать данные по произвольному списку значений, сопоставить данные из внешних источников с базой или выполнить пакетную обработку без обхода в цикле. Механизм прост: таблица передаётся как параметр запроса, помещается во временную таблицу, а дальше с ней работают как с обычной таблицей в тексте запроса.

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

Зачем передавать таблицу значений в запрос

Типовой сценарий — фильтрация по списку, который нельзя получить из базы напрямую. Например, пользователь отобрал в обработке 500 номенклатурных позиций, и нужно одним запросом получить по ним остатки, цены и резервы. Передача таблицы в запрос заменяет 500 обращений в цикле одним обращением к СУБД.

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

Третий сценарий — передача в запрос табличной части документа или таблицы формы для проверки корректности заполнения: дубли строк, наличия ссылок, соответствия остаткам.

Базовый код: передача и помещение во временную таблицу

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

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

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

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

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

"ВЫБРАТЬ

| ТЗ.Номенклатура КАК Номенклатура,

| ТЗ.Количество КАК Количество

|ПОМЕСТИТЬ ВТ_Данные

|ИЗ

| &ТЗ КАК ТЗ";

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

Запрос.Выполнить();

После выполнения этого запроса временная таблица ВТ_Данные живёт в менеджере и доступна следующим запросам, у которых назначен тот же МенеджерВременныхТаблиц. Это ключевой момент: один менеджер — одна «сессия» временных таблиц.

Порядок действий
  1. 1
    Создайте таблицу значений и явно опишите типы колонок через ОписаниеТипов
  2. 2
    Создайте объект МенеджерВременныхТаблиц и назначьте его запросу
  3. 3
    Передайте таблицу параметром: Запрос.УстановитьПараметр("ТЗ", ТаблицаЗначений)
  4. 4
    В тексте запроса используйте ВЫБРАТЬ ... ПОМЕСТИТЬ ВТ_Имя ИЗ &ТЗ КАК ТЗ
  5. 5
    Выполните запрос и используйте временную таблицу в следующих запросах пакета
  6. 6
    После работы уничтожьте временные таблицы или закройте менеджер

Требования к таблице значений перед передачей

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

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

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

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

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

Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));

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

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

Использование временной таблицы в пакете запросов

После помещения таблицы во временную её соединяют с таблицами базы. Пример — получение остатков по списку номенклатуры:

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

"ВЫБРАТЬ

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

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

|ИЗ

| ВТ_Данные КАК ВТ

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

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

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

Левое соединение здесь принципиально: оно гарантирует, что все строки переданной таблицы попадут в результат, даже если по позиции нет остатков. Внутреннее соединение «съест» отсутствующие позиции, и проверка полноты данных станет невозможной.

Если по временной таблице строится соединение по индексируемому полю, имеет смысл добавить в первый запрос индексацию: ИНДЕКСИРОВАТЬ ПО Номенклатура после секции ПОМЕСТИТЬ. На больших таблицах это заметно ускоряет соединение.

Альтернатива: фильтрация по списку без временной таблицы

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

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

// в тексте запроса:

// ГДЕ Номенклатура В (&СписокНоменклатуры)

Этот вариант проще и быстрее, но работает только для фильтрации по одному полю. Как только к каждой строке списка нужно привязать дополнительные данные (количество, цену, номер строки), без полноценной таблицы значений не обойтись.

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

Массив + оператор В

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

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

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

Табличная часть или результат запроса через Выгрузить()

Удобно для передачи данных между запросами: типы колонок уже корректны. Не подходит для данных, которых нет в базе.

Частые ошибки и их признаки

Самая распространённая ошибка — «Временная таблица не найдена». Она возникает, когда второй запрос выполняется без назначенного менеджера временных таблиц или с другим менеджером. Лечится передачей одного экземпляра МенеджерВременныхТаблиц всем запросам пакета.

Вторая ошибка — дубли строк в результате соединения. Если во временной таблице есть повторяющиеся значения ключа, соединение умножит строки результата. Перед передачей сверните таблицу: ТаблицаЗначений.Свернуть("Номенклатура", "Количество") — или добавьте группировку в запрос.

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

Типичные ошибки
01
Не назначен МенеджерВременныхТаблиц — второй запрос падает с ошибкой «таблица не найдена»
02
Колонки без явного типа — ошибка определения типа на пустой таблице или непредсказуемое поведение
03
Дубли ключей в таблице — умножение строк результата после соединения
04
Несовпадение типов полей соединения — пустой результат без сообщения об ошибке
05
Внутреннее соединение вместо левого — потеря строк, отсутствующих в регистре

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

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

Временные таблицы занимают память на сервере, пока жив менеджер. В длительных обработках явно удаляйте ненужные таблицы запросом УНИЧТОЖИТЬ ВТ_Данные или присваивайте переменной менеджера Неопределено после завершения работы.

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

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

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

Совпадает с числом уникальных строк переданной таблицы (при левом соединении)

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

Строк больше (дубли) или меньше (потери при соединении)

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

Все колонки типизированы через ОписаниеТипов

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

Колонки без типа, смешанные типы значений

Выполнение второго запроса пакета
Норма

Запрос видит временную таблицу и возвращает данные

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

Ошибка «временная таблица не найдена»

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

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

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

Как передать в запрос табличную часть документа?

Используйте метод Выгрузить() табличной части: Документ.Товары.Выгрузить() вернёт таблицу значений с типизированными колонками, которую можно сразу передать параметром. При необходимости оставьте только нужные колонки через ВыгрузитьКолонки или свёртку.

Есть ли ограничение на размер передаваемой таблицы?

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

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

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

Можно ли использовать параметр-таблицу в условии ГДЕ без ПОМЕСТИТЬ?

Нет, обратиться к параметру-таблице можно только как к источнику данных в секции ИЗ. Поэтому стандартный паттерн — сначала ПОМЕСТИТЬ во временную таблицу, затем соединять или фильтровать по ней.

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

Выполните запрос с текстом «УНИЧТОЖИТЬ ВТ_Данные» через тот же менеджер временных таблиц. Альтернатива — обнулить переменную менеджера, тогда все его таблицы будут удалены целиком.

Итог

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

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