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