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

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

Как сделать временную таблицу в 1С

Как создать временную таблицу в запросе 1С: синтаксис ПОМЕСТИТЬ, менеджер временных таблиц, примеры кода, типичные ошибки и проверка результата.

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

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

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

Что такое временная таблица и когда она нужна

Временная таблица — это материализованный результат запроса, который платформа сохраняет во временном хранилище сервера СУБД (или в памяти файловой базы). В отличие от вложенного запроса, временная таблица вычисляется один раз и дальше используется как обычный источник данных: её можно соединять, фильтровать и группировать.

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

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

Создание временной таблицы через ПОМЕСТИТЬ

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

ВЫБРАТЬ

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

Товары.Цена КАК Цена

ПОМЕСТИТЬ ВТ_Товары

ИЗ

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

ГДЕ

Товары.Цена > 1000

;

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

ВЫБРАТЬ

Продажи.Номенклатура КАК Номенклатура,

СУММА(Продажи.Количество) КАК Количество

ИЗ

РегистрНакопления.Продажи.Обороты КАК Продажи

ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Товары КАК Товары

ПО Продажи.Номенклатура = Товары.Номенклатура

СГРУППИРОВАТЬ ПО

Продажи.Номенклатура

;

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

Менеджер временных таблиц: зачем он и как настроить

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

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

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

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

Запрос1.Текст = "ВЫБРАТЬ ... ПОМЕСТИТЬ ВТ_Товары ...";

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

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

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

Запрос2.Текст = "ВЫБРАТЬ * ИЗ ВТ_Товары";

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

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

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

Частая задача — отфильтровать запрос по списку значений, сформированному в коде (например, по строкам табличной части). Для этого таблица значений передаётся параметром и помещается во временную таблицу.

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

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

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

"ВЫБРАТЬ

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

|ПОМЕСТИТЬ ВТ_Список

|ИЗ

| &СписокТоваров КАК Список

|;

|ВЫБРАТЬ

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

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

|ИЗ

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

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Список КАК Список

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

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

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

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

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

Индексирование и уничтожение временных таблиц

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

ВЫБРАТЬ

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

ПОМЕСТИТЬ ВТ_Товары

ИЗ

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

ИНДЕКСИРОВАТЬ ПО

Номенклатура

;

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

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

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

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

Существование таблицы
Норма

Запрос к ВТ выполняется без ошибки «Таблица не найдена»

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

Ошибка обращения — таблица не создана или уже уничтожена

Состав данных
Норма

Число строк во ВТ совпадает с ожидаемой выборкой

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

Пустая таблица или лишние строки — проверьте отбор и соединения

Скорость выполнения
Норма

Соединение с ВТ работает быстро на больших объёмах

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

Запрос «зависает» — вероятно, нет индекса по полям связи

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

Самая частая ошибка — обращение к временной таблице из запроса без общего менеджера. Каждый объект Запрос по умолчанию имеет свой менеджер, поэтому таблица, созданная в одном запросе, невидима для другого. Решение — явно создать менеджер и назначить его всем запросам цепочки.

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

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

Типичные ошибки
01
Забыли назначить общий МенеджерВременныхТаблиц — второй запрос не видит таблицу и падает с ошибкой
02
Повторное ПОМЕСТИТЬ с тем же именем без УНИЧТОЖИТЬ — ошибка выполнения запроса
03
Соединение большой ВТ без ИНДЕКСИРОВАТЬ ПО — резкое падение производительности
04
Передача нетипизированной таблицы значений параметром — пустой результат соединения
05
Накопление десятков ВТ без уничтожения — рост нагрузки на tempdb и память сервера

Временная таблица против вложенного запроса: что выбрать

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

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

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

Вложенный запрос

Подходит для разового использования; не требует менеджера, но может вычисляться повторно и хуже читается

Временная таблица в пакете

Оптимальна при многократном использовании данных в одном запросе; поддерживает индексы

ВТ через МенеджерВременныхТаблиц

Нужна при обращении из нескольких объектов Запрос; требует явной очистки

Таблица значений без запроса

Подходит для небольших списков в коде; не участвует в соединениях на стороне СУБД

Итог

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

Временная таблица создаётся конструкцией ПОМЕСТИТЬ, живёт внутри пакета или общего МенеджерВременныхТаблиц, индексируется через ИНДЕКСИРОВАТЬ ПО и удаляется командой УНИЧТОЖИТЬ. Используйте её при повторном обращении к промежуточным данным и всегда очищайте после работы.

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

Можно ли использовать временную таблицу в другом сеансе или фоновом задании?

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

Как посмотреть содержимое временной таблицы при отладке?

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

Что произойдёт, если не уничтожить временную таблицу?

Таблица будет удалена автоматически при уничтожении менеджера (завершении процедуры). Но в длинных обработках накопление таблиц расходует память и ресурсы tempdb, поэтому явное УНИЧТОЖИТЬ — хорошая практика.

Можно ли поместить во временную таблицу результат с итогами и группировкой?

Да, ПОМЕСТИТЬ работает с любыми выборками, включая СГРУППИРОВАТЬ ПО, итоги и виртуальные таблицы регистров. Это стандартный приём для многоэтапных расчётов оборотов и остатков.

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

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

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

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