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