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