Менеджер временных таблиц: подключение в коде, настройка сервера и ошибки

· 9 мин

Содержание

Менеджер временных таблиц в 1С не нужно скачивать и устанавливать: это встроенный объект платформы 1С:Предприятие 8.3. Чтобы его «включить», достаточно создать его в коде строкой Новый МенеджерВременныхТаблиц и присвоить запросу через свойство МенеджерВременныхТаблиц.

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

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

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

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

Чем он полезен на практике:

  • 🔁 одну тяжёлую выборку (например, список номенклатуры по фильтру) считают один раз и используют в трёх-четырёх запросах;
  • 🧩 сложный запрос дробят на понятные шаги, которые проще отлаживать;
  • 📥 таблицу значений из кода загружают в запрос и соединяют с данными базы;
  • 🧭 менеджер передают параметром в другие процедуры: каждая дописывает свои таблицы.

Объект доступен в серверном контексте: в модулях с директивой &НаСервере, в серверных общих модулях, во внешнем соединении и в толстом клиенте. В тонком и веб-клиенте его создать нельзя — код с ним выносят на сервер.

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

Подготовка: платформа, СУБД и окружение

Отдельной установки не требуется, но временные таблицы физически где-то хранятся, и от этого зависит скорость работы.

Вариант базыГде лежат временные таблицыЧто проверить
ФайловаяВ памяти и во временных файлах процесса 1ССвободное место на диске с каталогом временных файлов, объём оперативной памяти
Клиент-сервер, MS SQL ServerВ системной базе tempdbРазмер и диск tempdb, число её файлов
Клиент-сервер, PostgreSQLВо временной схеме сеанса СУБДПараметр temp_buffers, свободное место в каталоге данных

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

  1. Убедитесь, что конфигурация открыта в Конфигураторе на платформе 8.3 и что модуль, где вы пишете код, серверный.
  2. Для MS SQL Server проверьте, что tempdb лежит на быстром диске и имеет запас места. При больших выборках она растёт быстро, а заполненный диск останавливает все запросы базы, не только ваш.
  3. Для MS SQL Server с многоядерным процессором обычно делают несколько файлов tempdb одинакового размера — это стандартная рекомендация администраторов СУБД против конкуренции за служебные страницы.
  4. Для PostgreSQL посмотрите значение temp_buffers: при маленьком значении временные таблицы чаще уходят на диск.
  5. В файловой базе оцените, сколько строк реально попадёт во временную таблицу. Сотни тысяч строк в файловом варианте — повод пересмотреть алгоритм.

Менять параметры СУБД и перезапускать её службу нужно в окно обслуживания: перезапуск оборвёт сеансы всех пользователей 1С. Перед этим предупредите людей и дождитесь, пока они выйдут из базы.

Подключение менеджера временных таблиц к запросу: пошагово

Шаг 1. Создайте менеджер и привяжите к первому запросу

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

Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст =
"ВЫБРАТЬ
|	Номенклатура.Ссылка КАК Номенклатура
|ПОМЕСТИТЬ ВТ_Товары
|ИЗ
|	Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|	НЕ Номенклатура.ЭтоГруппа
|	И НЕ Номенклатура.ПометкаУдаления
|
|ИНДЕКСИРОВАТЬ ПО
|	Номенклатура";
Запрос.Выполнить();

После Выполнить() таблица ВТ_Товары хранится в менеджере, а не в запросе.

Шаг 2. Используйте таблицу в другом запросе

Второй запрос — отдельный объект, но с тем же менеджером:

Запрос2 = Новый Запрос;
Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос2.Текст =
"ВЫБРАТЬ
|	Товары.Номенклатура КАК Номенклатура,
|	ЕСТЬNULL(Цены.Цена, 0) КАК Цена
|ИЗ
|	ВТ_Товары КАК Товары
|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
|		ПО Товары.Номенклатура = Цены.Номенклатура";
Результат = Запрос2.Выполнить();

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

Шаг 3. Передайте менеджер в другую процедуру

Менеджер — обычная переменная, её передают параметром:

Процедура ДобавитьОстатки(МенеджерВТ)
	Запрос = Новый Запрос;
	Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	Товары.Номенклатура КАК Номенклатура
	|ПОМЕСТИТЬ ВТ_ТоварыДляОстатков
	|ИЗ
	|	ВТ_Товары КАК Товары";
	Запрос.Выполнить();
КонецПроцедуры

Процедура видит ВТ_Товары, созданную раньше, и добавляет свою таблицу в тот же менеджер.

Шаг 4. Загрузите таблицу значений во временную таблицу

Частый приём — соединить данные из кода (например, из загруженного файла) с данными базы:

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
// ... заполнение строк ...

Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.УстановитьПараметр("ТаблицаЗагрузки", ТЗ);
Запрос.Текст =
"ВЫБРАТЬ
|	Т.Номенклатура КАК Номенклатура,
|	Т.Количество КАК Количество
|ПОМЕСТИТЬ ВТ_Загрузка
|ИЗ
|	&ТаблицаЗагрузки КАК Т";
Запрос.Выполнить();

У каждой колонки таблицы значений должен быть явно задан тип. Без описания типов запрос из параметра-таблицы не выполнится.

Шаг 5. Освободите ресурсы

Когда таблицы больше не нужны, закройте менеджер:

МенеджерВТ.Закрыть();

Метод уничтожает все временные таблицы менеджера. Если нужно удалить только одну, выполните запрос с текстом УНИЧТОЖИТЬ ВТ_Товары, подключённый к тому же менеджеру.

Как сделать то же в конструкторе запроса

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

Права доступа и пользователи

Отдельной роли или права «использовать временные таблицы» в 1С нет. Если у пользователя есть права на данные, которые читает запрос, он может работать и с временными таблицами.

Что действительно влияет на доступ:

  • 🔐 Ограничение доступа на уровне записей (RLS). Оно срабатывает в момент, когда данные кладут во временную таблицу. Сама временная таблица ограничений не имеет: что в неё попало, то и прочитают следующие запросы. Поэтому слово РАЗРЕШЕННЫЕ ставят в запрос, который заполняет таблицу.
  • 🛡️ Привилегированный режим. Если таблицу заполнили в привилегированном модуле или после УстановитьПривилегированныйРежим(Истина), в ней окажутся данные без ограничений. Выводить их пользователю без фильтра нельзя.
  • 🗄️ Пользователь СУБД. В клиент-серверной базе таблицы создаёт пользователь, под которым кластер 1С подключается к СУБД. Создание временных таблиц — базовая возможность СУБД, отдельно её почти никогда не выдают, но при жёстко урезанных правах на сервере стоит проверить доступ к tempdb или к временным схемам.
  • 👥 Изоляция сеансов. Временные таблицы видны только в том сеансе и в том менеджере, где созданы. Два бухгалтера, одновременно формирующие один отчёт, не мешают друг другу, даже если имена таблиц совпадают.

Самая коварная ошибка с правами — таблица заполнена без РАЗРЕШЕННЫЕ у пользователя с ограничениями. Запрос падает с ошибкой нарушения прав доступа, хотя сам код верный. Добавьте РАЗРЕШЕННЫЕ в первый запрос пакета, где читаются ограниченные таблицы.

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

Диагностика: выберите симптом

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

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

При отладке полезно увидеть содержимое менеджера. В актуальных версиях платформы 8.3 у него есть свойство Таблицы — коллекция временных таблиц:

Для Каждого ВремТаблица Из МенеджерВТ.Таблицы Цикл
	КоличествоКолонок = ВремТаблица.Колонки.Количество();
	Сообщить(СтрШаблон("%1: колонок %2", ВремТаблица.ПолноеИмя, Формат(КоличествоКолонок, "ЧГ=0")));
КонецЦикла;

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

Если свойства Таблицы в синтакс-помощнике вашей платформы нет, самый простой способ посмотреть таблицу — временно выполнить запрос ВЫБРАТЬ * ИЗ ВТ_Товары с тем же менеджером и выгрузить результат.

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

Временные таблицы ускоряют запросы, только если ими пользоваться аккуратно. Несколько правил, которые реально дают эффект:

  1. Кладите только нужные колонки и строки. Фильтр по периоду, организации и виду номенклатуры ставьте уже в запрос с ПОМЕСТИТЬ. Таблица из 5 000 строк вместо 500 000 — это разница в порядки по нагрузке на tempdb.
  2. Индексируйте поля соединения. Если по полю Номенклатура таблицу дальше соединяют с регистром, добавьте ИНДЕКСИРОВАТЬ ПО Номенклатура. Для маленьких таблиц на десятки строк индекс не нужен — его построение дороже выигрыша.
  3. Не создавайте временные таблицы в цикле. Один запрос на всю выборку быстрее сотни запросов по одной строке.
  4. Заменяйте вложенные запросы. Вложенный запрос в соединении СУБД иногда выполняет неоптимально; тот же отбор, вынесенный во временную таблицу с индексом, обычно работает стабильнее.
  5. Освобождайте менеджер. Вызов Закрыть() или УНИЧТОЖИТЬ в конце длинной обработки сразу освобождает место в tempdb, а не ждёт завершения сеанса.
  6. Не держите менеджер дольше нужного. Глобальные переменные модуля сеанса с открытым менеджером копят таблицы до выхода пользователя.

Когда что использовать:

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

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

Перед выкладкой кода с временными таблицами
Выполнено: 0 / 6

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

Нужно ли устанавливать менеджер временных таблиц на сервер 1С?
Нет. Это объект встроенного языка платформы 8.3, он есть в любой базе. Нужно только создать его в коде и подключить к запросу.
Можно ли использовать менеджер временных таблиц в схеме компоновки данных?
Внутри текста запроса набора данных СКД можно создавать временные таблицы через пакетный запрос. Передать внешний менеджер в стандартный вывод СКД напрямую нельзя: обычно готовят таблицу значений и передают её как внешний набор данных.
Сколько живёт временная таблица?
До вызова Закрыть() у менеджера, команды УНИЧТОЖИТЬ или пока существует переменная с менеджером. После завершения серверного вызова менеджер и его таблицы уничтожаются.
Влияет ли менеджер на лицензии или число сеансов?
Нет. Временные таблицы создаются в текущем сеансе пользователя и не занимают дополнительных лицензий.
Можно ли сделать запрос к временной таблице из внешней обработки?
Да, если обработка выполняет код на сервере и получает тот же менеджер параметром. Создать менеджер в одной процедуре и обратиться к нему из другого серверного вызова нельзя — он не сохраняется между вызовами.