Менеджер временных таблиц: подключение в коде, настройка сервера и ошибки
Содержание
Менеджер временных таблиц в 1С не нужно скачивать и устанавливать: это встроенный объект платформы 1С:Предприятие 8.3. Чтобы его «включить», достаточно создать его в коде строкой Новый МенеджерВременныхТаблиц и присвоить запросу через свойство МенеджерВременныхТаблиц.
Типичная ситуация: разработчик пишет отчёт, делит большой запрос на две части, и второй запрос падает с ошибкой Таблица не найдена "ВТ_Остатки". Причина почти всегда одна — у второго запроса нет общего менеджера с первым.
Что такое менеджер временных таблиц и почему его не устанавливают
Временная таблица — это выборка, которую запрос сохраняет командой ПОМЕСТИТЬ, чтобы потом обратиться к ней как к обычной таблице. Пока такая таблица живёт внутри одного пакетного запроса, менеджер не нужен: платформа создаёт его неявно и уничтожает вместе с запросом.
Менеджер временных таблиц нужен, когда таблицу надо использовать в нескольких разных запросах. Он хранит набор временных таблиц и отдаёт их любому запросу, к которому подключён.
Чем он полезен на практике:
- 🔁 одну тяжёлую выборку (например, список номенклатуры по фильтру) считают один раз и используют в трёх-четырёх запросах;
- 🧩 сложный запрос дробят на понятные шаги, которые проще отлаживать;
- 📥 таблицу значений из кода загружают в запрос и соединяют с данными базы;
- 🧭 менеджер передают параметром в другие процедуры: каждая дописывает свои таблицы.
Объект доступен в серверном контексте: в модулях с директивой &НаСервере, в серверных общих модулях, во внешнем соединении и в толстом клиенте. В тонком и веб-клиенте его создать нельзя — код с ним выносят на сервер.
Если вы ищете «менеджер временных таблиц» как обработку или компонент в каталоге — такой отдельной программы нет. Обработки с похожими названиями из интернета обычно оказываются консолями запросов, которые просто умеют показывать содержимое временных таблиц.
Подготовка: платформа, СУБД и окружение
Отдельной установки не требуется, но временные таблицы физически где-то хранятся, и от этого зависит скорость работы.
| Вариант базы | Где лежат временные таблицы | Что проверить |
|---|---|---|
| Файловая | В памяти и во временных файлах процесса 1С | Свободное место на диске с каталогом временных файлов, объём оперативной памяти |
| Клиент-сервер, MS SQL Server | В системной базе tempdb | Размер и диск tempdb, число её файлов |
| Клиент-сервер, PostgreSQL | Во временной схеме сеанса СУБД | Параметр temp_buffers, свободное место в каталоге данных |
Что сделать до того, как код с временными таблицами пойдёт в рабочую базу:
- Убедитесь, что конфигурация открыта в Конфигураторе на платформе 8.3 и что модуль, где вы пишете код, серверный.
- Для MS SQL Server проверьте, что
tempdbлежит на быстром диске и имеет запас места. При больших выборках она растёт быстро, а заполненный диск останавливает все запросы базы, не только ваш. - Для MS SQL Server с многоядерным процессором обычно делают несколько файлов
tempdbодинакового размера — это стандартная рекомендация администраторов СУБД против конкуренции за служебные страницы. - Для PostgreSQL посмотрите значение
temp_buffers: при маленьком значении временные таблицы чаще уходят на диск. - В файловой базе оцените, сколько строк реально попадёт во временную таблицу. Сотни тысяч строк в файловом варианте — повод пересмотреть алгоритм.
Менять параметры СУБД и перезапускать её службу нужно в окно обслуживания: перезапуск оборвёт сеансы всех пользователей 1С. Перед этим предупредите людей и дождитесь, пока они выйдут из базы.
Подключение менеджера временных таблиц к запросу: пошагово
Шаг 1. Создайте менеджер и привяжите к первому запросу
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Номенклатура
|ПОМЕСТИТЬ ВТ_Товары
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ЭтоГруппа
| И НЕ Номенклатура.ПометкаУдаления
|
|ИНДЕКСИРОВАТЬ ПО
| Номенклатура";
Запрос.Выполнить();
После Выполнить() таблица ВТ_Товары хранится в менеджере, а не в запросе.
Шаг 2. Используйте таблицу в другом запросе
Второй запрос — отдельный объект, но с тем же менеджером:
Запрос2 = Новый Запрос;
Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос2.Текст =
"ВЫБРАТЬ
| Товары.Номенклатура КАК Номенклатура,
| ЕСТЬNULL(Цены.Цена, 0) КАК Цена
|ИЗ
| ВТ_Товары КАК Товары
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК Цены
| ПО Товары.Номенклатура = Цены.Номенклатура";
Результат = Запрос2.Выполнить();
Имя регистра цен в типовых конфигурациях отличается, поэтому в своём коде подставьте регистр из вашей базы. Сам принцип — один менеджер на оба запроса — не меняется.
Шаг 3. Передайте менеджер в другую процедуру
Менеджер — обычная переменная, её передают параметром:
Процедура ДобавитьОстатки(МенеджерВТ)
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Номенклатура КАК Номенклатура
|ПОМЕСТИТЬ ВТ_ТоварыДляОстатков
|ИЗ
| ВТ_Товары КАК Товары";
Запрос.Выполнить();
КонецПроцедуры
Процедура видит ВТ_Товары, созданную раньше, и добавляет свою таблицу в тот же менеджер.
Шаг 4. Загрузите таблицу значений во временную таблицу
Частый приём — соединить данные из кода (например, из загруженного файла) с данными базы:
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗ.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
// ... заполнение строк ...
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.УстановитьПараметр("ТаблицаЗагрузки", ТЗ);
Запрос.Текст =
"ВЫБРАТЬ
| Т.Номенклатура КАК Номенклатура,
| Т.Количество КАК Количество
|ПОМЕСТИТЬ ВТ_Загрузка
|ИЗ
| &ТаблицаЗагрузки КАК Т";
Запрос.Выполнить();
У каждой колонки таблицы значений должен быть явно задан тип. Без описания типов запрос из параметра-таблицы не выполнится.
Шаг 5. Освободите ресурсы
Когда таблицы больше не нужны, закройте менеджер:
МенеджерВТ.Закрыть();
Метод уничтожает все временные таблицы менеджера. Если нужно удалить только одну, выполните запрос с текстом УНИЧТОЖИТЬ ВТ_Товары, подключённый к тому же менеджеру.
Как сделать то же в конструкторе запроса
В Конфигураторе конструктор запроса умеет создавать временную таблицу без ручного текста. На вкладке «Дополнительно» переключите тип запроса на создание временной таблицы и укажите её имя. Вкладка «Пакет запросов» показывает все запросы пакета: там удобно добавить следующий запрос, который читает созданную таблицу.
Права доступа и пользователи
Отдельной роли или права «использовать временные таблицы» в 1С нет. Если у пользователя есть права на данные, которые читает запрос, он может работать и с временными таблицами.
Что действительно влияет на доступ:
- 🔐 Ограничение доступа на уровне записей (RLS). Оно срабатывает в момент, когда данные кладут во временную таблицу. Сама временная таблица ограничений не имеет: что в неё попало, то и прочитают следующие запросы. Поэтому слово
РАЗРЕШЕННЫЕставят в запрос, который заполняет таблицу. - 🛡️ Привилегированный режим. Если таблицу заполнили в привилегированном модуле или после
УстановитьПривилегированныйРежим(Истина), в ней окажутся данные без ограничений. Выводить их пользователю без фильтра нельзя. - 🗄️ Пользователь СУБД. В клиент-серверной базе таблицы создаёт пользователь, под которым кластер 1С подключается к СУБД. Создание временных таблиц — базовая возможность СУБД, отдельно её почти никогда не выдают, но при жёстко урезанных правах на сервере стоит проверить доступ к
tempdbили к временным схемам. - 👥 Изоляция сеансов. Временные таблицы видны только в том сеансе и в том менеджере, где созданы. Два бухгалтера, одновременно формирующие один отчёт, не мешают друг другу, даже если имена таблиц совпадают.
Самая коварная ошибка с правами — таблица заполнена без РАЗРЕШЕННЫЕ у пользователя с ограничениями. Запрос падает с ошибкой нарушения прав доступа, хотя сам код верный. Добавьте РАЗРЕШЕННЫЕ в первый запрос пакета, где читаются ограниченные таблицы.
Ошибки при работе с временными таблицами и их причины
Ещё одна частая ловушка — попытка сохранить менеджер в реквизит формы или передать его с сервера на клиент. Менеджер временных таблиц не сериализуется: между вызовами сервера он не живёт. Если данные нужны форме, выгрузите результат в таблицу значений и поместите её в реквизит, а менеджер создавайте заново при каждом серверном вызове.
Как проверить, какие таблицы есть в менеджере
При отладке полезно увидеть содержимое менеджера. В актуальных версиях платформы 8.3 у него есть свойство Таблицы — коллекция временных таблиц:
Для Каждого ВремТаблица Из МенеджерВТ.Таблицы Цикл
КоличествоКолонок = ВремТаблица.Колонки.Количество();
Сообщить(СтрШаблон("%1: колонок %2", ВремТаблица.ПолноеИмя, Формат(КоличествоКолонок, "ЧГ=0")));
КонецЦикла;
Проверить наличие конкретной таблицы можно через МенеджерВТ.Таблицы.Найти("ВТ_Товары"): если таблицы нет, вернётся Неопределено. Метод ПолучитьДанные() у элемента коллекции возвращает результат запроса, который можно выгрузить и посмотреть в отладчике.
Если свойства Таблицы в синтакс-помощнике вашей платформы нет, самый простой способ посмотреть таблицу — временно выполнить запрос ВЫБРАТЬ * ИЗ ВТ_Товары с тем же менеджером и выгрузить результат.
Производительность временных таблиц: практика
Временные таблицы ускоряют запросы, только если ими пользоваться аккуратно. Несколько правил, которые реально дают эффект:
- Кладите только нужные колонки и строки. Фильтр по периоду, организации и виду номенклатуры ставьте уже в запрос с
ПОМЕСТИТЬ. Таблица из 5 000 строк вместо 500 000 — это разница в порядки по нагрузке наtempdb. - Индексируйте поля соединения. Если по полю
Номенклатуратаблицу дальше соединяют с регистром, добавьтеИНДЕКСИРОВАТЬ ПО Номенклатура. Для маленьких таблиц на десятки строк индекс не нужен — его построение дороже выигрыша. - Не создавайте временные таблицы в цикле. Один запрос на всю выборку быстрее сотни запросов по одной строке.
- Заменяйте вложенные запросы. Вложенный запрос в соединении СУБД иногда выполняет неоптимально; тот же отбор, вынесенный во временную таблицу с индексом, обычно работает стабильнее.
- Освобождайте менеджер. Вызов
Закрыть()илиУНИЧТОЖИТЬв конце длинной обработки сразу освобождает место вtempdb, а не ждёт завершения сеанса. - Не держите менеджер дольше нужного. Глобальные переменные модуля сеанса с открытым менеджером копят таблицы до выхода пользователя.
Когда что использовать:
| Приём | Когда подходит | Минусы |
|---|---|---|
| Временная таблица в пакете без менеджера | Все шаги умещаются в один пакетный запрос | Таблицы не доступны другим запросам |
| Явный менеджер временных таблиц | Выборку используют несколько запросов или процедур | Нужно следить за закрытием и именами |
| Вложенный запрос | Небольшой отбор, используется один раз | На больших объёмах план запроса бывает неудачным |
| Таблица значений в памяти | Обработка строк кодом, вывод в форму | Не соединяется с данными базы без загрузки в запрос |
Для замеров в клиент-серверной базе используйте замер производительности в Конфигураторе в режиме отладки и технологический журнал. Они покажут, какой запрос с временной таблицей занимает больше всего времени.