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

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

Для чего нужен менеджер временных таблиц в 1С

Разбираем, для чего нужен менеджер временных таблиц в 1С, как создавать и переиспользовать временные таблицы в запросах, типичные ошибки и приёмы оптимизации.

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

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

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

Что такое менеджер временных таблиц и как он работает

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

Физически временные таблицы размещаются на сервере СУБД (в клиент-серверном режиме) или в памяти файловой базы и живут до тех пор, пока существует менеджер или пока таблицу явно не уничтожить командой УНИЧТОЖИТЬ. Данные в них не попадают в постоянное хранилище и не видны другим сеансам.

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

Какие задачи решает менеджер временных таблиц

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

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

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

Запрос с 3+ уровнями вложенностиВысокая сложность

Разбейте на этапы через ПОМЕСТИТЬ — код станет читаемее и отлаживаемее

Повторное вычисление одних данныхДублирование работы

Вынесите общий результат во временную таблицу и используйте повторно

Передача таблицы значений в запросВнешний источник

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

Простой запрос к одной таблицеИзбыточность

Менеджер не нужен — он добавляет накладные расходы без выгоды

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

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

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

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

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

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

"ВЫБРАТЬ

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

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

|ПОМЕСТИТЬ ВТ_Обороты

|ИЗ

| РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ) КАК Продажи

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

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

Запрос.УстановитьПараметр("Начало", НачалоПериода);

Запрос.УстановитьПараметр("Конец", КонецПериода);

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

Далее второй запрос с тем же менеджером обращается к ВТ_Обороты как к обычной таблице: ИЗ ВТ_Обороты КАК Обороты. Важно, что параметры каждый запрос получает свои — параметры первого запроса не «протекают» во второй автоматически.

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

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

Отдельный распространённый сценарий — поместить во временную таблицу данные, которых нет в базе: строки табличной части формы, загруженный из файла список, результат расчёта на клиенте. Для этого таблица значений передаётся параметром и помещается конструкцией вида ВЫБРАТЬ Т.Поле ПОМЕСТИТЬ ВТ ИЗ &ТЗ КАК Т.

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

"ВЫБРАТЬ

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

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

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

|ИЗ

| &Товары КАК Т";

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

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

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

Управление жизненным циклом и производительность

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

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

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

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

Как проверить корректность работы

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

Запрос с ПОМЕСТИТЬ выполнен без ошибок, таблица доступна в следующем запросе

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

Ошибка 'Таблица не найдена' — запросы используют разные менеджеры

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

Выборка из временной таблицы возвращает ожидаемое число строк

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

Пустой результат — проверьте параметры и отборы исходного запроса

Производительность
Норма

Повторные обращения к таблице выполняются быстро

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

Запросы тормозят — добавьте ИНДЕКСИРОВАТЬ ПО по полям соединений

Типичные ошибки при работе с менеджером

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

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

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

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

Альтернативы и границы применения

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

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

Способы организации промежуточных выборок

Менеджер временных таблиц

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

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

Подходят для одноразовой логики в одном запросе. Быстро теряют читаемость при росте вложенности

Пакетный запрос

Несколько запросов одним вызовом с массивом результатов. Удобен для независимых выборок

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

Гибкая программная обработка, но обходы в цикле проигрывают запросам по скорости на больших объёмах

Часто задаваемые вопросы

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

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

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

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

Можно ли передать менеджер временных таблиц в другую процедуру или общий модуль?

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

Почему запрос выдаёт ошибку «Таблица не найдена», хотя ПОМЕСТИТЬ выполнялся?

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

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

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

Итог

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

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