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