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

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

Как создать временную таблицу в запросе 1С

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

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

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

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

Что такое временная таблица и когда она нужна

Временная таблица — это результат запроса, сохранённый под именем и доступный для обращения из последующих запросов пакета. Физически данные хранятся на сервере (в памяти или во временном хранилище СУБД) и не попадают в основную базу. После завершения пакета или уничтожения менеджера временных таблиц они удаляются автоматически.

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

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

Базовый синтаксис: ключевое слово ПОМЕСТИТЬ

Создание временной таблицы выполняется добавлением конструкции ПОМЕСТИТЬ с именем таблицы после предложения ВЫБРАТЬ и перед указанием источника данных. Имя должно быть уникальным в рамках пакета и не совпадать с именами таблиц базы данных.

ВЫБРАТЬ

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

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

ПОМЕСТИТЬ ВТ_Продажи

ИЗ

РегистрНакопления.Продажи КАК Продажи

ГДЕ

Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода

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

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

;

ВЫБРАТЬ

ВТ_Продажи.Номенклатура,

ВТ_Продажи.Количество,

Спр.Артикул

ИЗ

ВТ_Продажи КАК ВТ_Продажи

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Спр

ПО ВТ_Продажи.Номенклатура = Спр.Ссылка

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

Принятое соглашение об именовании — префикс ВТ_ (или ВТ) перед смысловым именем. Это не требование платформы, а практика, которая упрощает чтение кода и исключает случайное совпадение имён с реальными таблицами.

Менеджер временных таблиц: зачем он нужен

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

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

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

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

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

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

"ВЫБРАТЬ

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

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

|ПОМЕСТИТЬ ВТ_Продажи

|ИЗ

| РегистрНакопления.Продажи КАК Продажи

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

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

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

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

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

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

"ВЫБРАТЬ

| ВТ_Продажи.Номенклатура,

| ВТ_Продажи.Количество

|ИЗ

| ВТ_Продажи КАК ВТ_Продажи";

Результат = Запрос2.Выполнить().Выгрузить();

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

Порядок действий с менеджером
  1. 1
    Создайте объект Новый МенеджерВременныхТаблиц
  2. 2
    Присвойте его свойству МенеджерВременныхТаблиц первого запроса
  3. 3
    Выполните запрос с конструкцией ПОМЕСТИТЬ
  4. 4
    Присвойте тот же менеджер второму запросу и обратитесь к таблице по имени
  5. 5
    Проверьте результат через Выполнить().Выгрузить()

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

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

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

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

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

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

"ВЫБРАТЬ

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

| ТаблицаТоваров.Количество КАК Количество

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

|ИЗ

| &ТаблицаТоваров КАК ТаблицаТоваров";

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

При таком подходе важно помнить об ограничении: состав и типы колонок таблицы значений определяют структуру временной таблицы. Если колонка не типизирована (создана без описания типов), платформа может не корректно определить тип поля, и соединение с таблицей базы даст ошибку или неверный результат. Всегда создавайте колонки таблицы значений с явным описанием типов.

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

Индексация и уничтожение временных таблиц

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

ВЫБРАТЬ

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

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

ПОМЕСТИТЬ ВТ_Продажи

ИЗ

РегистрНакопления.Продажи КАК Продажи

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

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

ИНДЕКСИРОВАТЬ ПО

Номенклатура

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

Когда временная таблица больше не нужна, её стоит уничтожить явно: УНИЧТОЖИТЬ ВТ_Продажи. Это особенно важно в длинных пакетах с несколькими большими таблицами — своевременное удаление освобождает память сервера. Уничтожение выполняется отдельным запросом пакета или отдельным вызовом Выполнить() с текстом УНИЧТОЖИТЬ.

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

Как проверить результат

Создание таблицы
Норма

Запрос выполняется без ошибок, таблица видна в МенеджерВТ.Таблицы

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

Ошибка «Таблица уже существует» или пустой менеджер

Содержимое таблицы
Норма

ПолучитьДанные() возвращает ожидаемое число строк

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

Таблица пуста при наличии данных в источнике — проверьте условия отбора

Соединение с таблицей
Норма

Итоговый запрос возвращает строки без дублирования

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

Размножение строк — не хватает условий связи в соединении

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

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

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

Третья группа ошибок связана с типами данных: соединение поля временной таблицы с полем базы при несовпадении типов (например, строка переменной длины против фиксированной) может не давать совпадений. При передаче таблицы значений из кода типизируйте колонки через ОписаниеТипов.

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

Альтернативы и критерии выбора подхода

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

Объединение через ОБЪЕДИНИТЬ подходит, когда нужно склеить однородные наборы, но не заменяет фильтрацию и соединение. Табличные части и отборы параметрами виртуальных таблиц часто вообще устраняют необходимость во временной таблице: если задача — отобрать остатки по списку складов, правильнее передать список в параметр виртуальной таблицы Остатки, чем строить временную таблицу и соединяться с ней.

Сравнение вариантов

Временная таблица (ПОМЕСТИТЬ)

Подходит для многоэтапной логики и повторного использования результата; требует менеджера и расходует память сервера

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

Подходит для одноразового простого подзапроса; при глубокой вложенности трудно читать и отлаживать

Параметры виртуальных таблиц

Оптимальны для отборов по спискам значений без соединений; не подходят для сложных вычислений над промежуточными данными

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

Маршрут решения

Как выбрать действие

Промежуточные данные нужны в нескольких запросахСоздайте МенеджерВременныхТаблиц и используйте ПОМЕСТИТЬ
Нужен отбор по списку значений из кодаПередайте список параметром в условие В или в параметр виртуальной таблицы
Таблица большая и по ней идёт соединениеДобавьте ИНДЕКСИРОВАТЬ ПО по полям связи
В пакете накопилось несколько ненужных таблицУничтожьте их конструкцией УНИЧТОЖИТЬ до финального запроса

Частые вопросы о временных таблицах в 1С

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

Да, если таблица создаётся и используется внутри одного пакета запросов, разделённого точкой с запятой. Платформа сама создаст неявный менеджер. Явный менеджер нужен только для обмена таблицами между разными объектами Запрос.

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

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

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

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

Почему запрос с временной таблицей работает медленнее, чем без неё?

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

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

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

Как передать временную таблицу из одной функции в другую?

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

Итог

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

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