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

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

Временные таблицы в 1С: что это и как с ними работать

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

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

Механизм встроен в язык запросов 1С и доступен во всех типовых и самописных конфигурациях. Временные таблицы хранятся в оперативной памяти сервера (или клиента в файловом варианте) и автоматически удаляются при закрытии менеджера временных таблиц — они не попадают в базу данных и не требуют отдельной очистки вручную при корректной работе.

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

Где хранятся временные таблицы и как долго они живут

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

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

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

Как создать временную таблицу: конструкция ПОМЕСТИТЬ

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

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

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

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

"ВЫБРАТЬ

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

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

|ПОМЕСТИТЬ ВТ_ТоварыСЦенами

|ИЗ

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

|ГДЕ

| Товары.Цена > 0";

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

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

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

"ВЫБРАТЬ

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

| ВТ.Цена * 1.2 КАК ЦенаСНаценкой

|ИЗ

| ВТ_ТоварыСЦенами КАК ВТ";

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

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

Пакетные запросы и передача таблиц между запросами

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

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

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

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

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

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

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

"ВЫБРАТЬ

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

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

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

|ИЗ

| &ТаблицаДанных КАК Т";

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

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

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

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

Отдельный риск — помещение во временную таблицу очень большого объёма без фильтрации. Таблица на сотни тысяч строк занимает память сервера и может замедлить работу всего сеанса. Всегда накладывайте отбор ГДЕ на этапе создания, а не после.

Выбор подхода

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

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

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

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

Виртуальная таблица регистра

Оптимальна для остатков и оборотов на дату; не заменяет многократное использование одного отбора

Уничтожение временных таблиц и управление памятью

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

Запрос.Текст = "УНИЧТОЖИТЬ ВТ_ТоварыСЦенами";

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

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

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

Типичные ошибки при работе с временными таблицами

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

Вторая группа ошибок связана с типами полей. Если во временную таблицу попадают значения разных типов в одно поле, последующие соединения по этому полю могут работать медленно или давать неожиданный результат. Используйте ВЫРАЗИТЬ для приведения типов на этапе создания таблицы.

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

Типичные ошибки
01
Забыли присвоить запросу МенеджерВременныхТаблиц — получили ошибку «Таблица не найдена»
02
Создают таблицу без отбора ГДЕ — в память попадают лишние тысячи строк
03
Не используют ИНДЕКСИРОВАТЬ ПО — соединения больших временных таблиц тормозят
04
Не уничтожают таблицы в цикле — растёт потребление памяти сеансом
05
Передают таблицу значений с нетипизированными колонками — запрос падает на этапе выполнения
Контрольные точки

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

Выполнение запроса
Норма

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

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

Ошибка «Таблица не найдена» — проверьте менеджер и порядок выполнения

Объём данных
Норма

Во временную таблицу попадают только нужные строки благодаря отбору ГДЕ

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

Таблица содержит всю базу без фильтрации

Скорость соединений
Норма

Соединения идут по полям из ИНДЕКСИРОВАТЬ ПО

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

Запрос «зависает» на соединении больших временных таблиц

Частые вопросы о временных таблицах в 1С

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

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

Чем временная таблица отличается от таблицы значений?

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

Нужно ли удалять временные таблицы вручную?

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

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

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

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

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

Можно ли создать временную таблицу в запросе динамического списка или СКД?

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

Итог

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

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