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

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

Временная таблица в 1С: создание и практическое применение

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

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

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

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

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

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

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

Создание временной таблицы конструкцией ПОМЕСТИТЬ

Базовый синтаксис прост: в запросе после списка полей добавляется предложение ПОМЕСТИТЬ ИмяТаблицы. Запрос при этом не возвращает результат в выборку — данные уходят во временное хранилище.

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

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

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

"ВЫБРАТЬ

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

| Товары.ВидНоменклатуры КАК Вид

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

|ИЗ

| Справочник.Номенклатура КАК Товары

|ГДЕ

| НЕ Товары.ПометкаУдаления";

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

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

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

"ВЫБРАТЬ

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

| СУММА(Остатки.КоличествоОстаток) КАК Остаток

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура В

| (ВЫБРАТЬ Т.Номенклатура ИЗ ВТ_Товары КАК Т)) КАК Остатки

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

| Остатки.Номенклатура";

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

Обратите внимание: оба запроса выполняются одним и тем же объектом Запрос с назначенным менеджером. Если создать новый объект запроса без менеджера или с другим менеджером, таблица ВТ_Товары будет недоступна, и платформа выдаст ошибку «Таблица не найдена».

Пакет запросов и уничтожение таблиц

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

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

"ВЫБРАТЬ ... ПОМЕСТИТЬ ВТ_Отбор ...;

|ВЫБРАТЬ ... ИЗ ВТ_Отбор ...";

МассивРезультатов = Запрос.ВыполнитьПакет();

ИтоговаяТаблица = МассивРезультатов[1].Выгрузить();

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

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

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

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

ТЗ = Новый ТаблицаЗначений;

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

// ... заполнение ТЗ ...

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

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

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

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

"ВЫБРАТЬ

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

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

|ИЗ

| &ТЗ КАК ТЗ";

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

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

Типичные ошибки
01
Не заданы типы колонок таблицы значений — платформа выдаёт ошибку при помещении параметра во временную таблицу
02
Запрос с временной таблицей выполняется новым объектом Запрос без менеджера — ошибка «Таблица не найдена: ВТ_...»
03
Повторное ПОМЕСТИТЬ в таблицу с тем же именем без УНИЧТОЖИТЬ — ошибка выполнения пакета
04
Соединение с виртуальной таблицей без предварительной фильтрации во временную таблицу — резкое падение производительности на больших базах

Производительность и оптимизация

Временные таблицы ускоряют запросы, когда позволяют один раз отобрать узкое подмножество данных и дальше работать только с ним. Классический приём: сначала во временную таблицу помещается список нужных документов или товаров, а затем виртуальная таблица регистра (остатки, обороты) выбирается с условием Номенклатура В (ВЫБРАТЬ ... ИЗ ВТ_...). Это резко сокращает объём обрабатываемых записей.

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

Также учитывайте, что в файловом режиме временные таблицы обрабатываются на клиенте, а в клиент-серверном — на сервере СУБД (в MS SQL это реальные временные таблицы tempdb). Поведение на больших объёмах может отличаться, поэтому производительность стоит проверять на копии рабочей базы с реальным объёмом данных.

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

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

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

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

Проще для одноразового использования, но при повторении логики дублирует код и может выполняться медленнее

Таблица значений в памяти

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

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

Стандартная проблема: запрос с временными таблицами возвращает пустой результат, и непонятно, на каком шаге теряются данные. Проверить содержимое можно, временно заменив итоговый запрос на выборку из нужной временной таблицы:

Запрос.Текст = "ВЫБРАТЬ * ИЗ ВТ_Отбор";

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

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

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

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

Запрос выполняется без ошибок
Норма

Метод Выполнить() отрабатывает, итоговая выборка содержит строки

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

Ошибка «Таблица не найдена» или «Поле не найдено» — проверьте менеджер и имена таблиц

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

Выборка ВЫБРАТЬ * ИЗ ВТ_... возвращает ожидаемые строки и типы полей

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

Пустой результат или NULL в ключевых полях — ошибка в условиях отбора на этапе ПОМЕСТИТЬ

Память и скорость
Норма

Запрос выполняется за приемлемое время на реальном объёме данных

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

Длительное выполнение — сократите состав полей и отфильтруйте данные раньше

Ограничения и частые вопросы синтаксиса

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

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

Итог

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

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

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

Чем временная таблица отличается от вложенного запроса?

Вложенный запрос существует только внутри одного оператора ВЫБРАТЬ и пересчитывается при каждом обращении. Временная таблица материализуется один раз и может многократно использоваться в последующих запросах пакета, что удобнее для отладки и часто быстрее при повторном обращении к одним и тем же данным.

Можно ли использовать временную таблицу в другом объекте Запрос?

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

Почему возникает ошибка «Таблица не найдена: ВТ_...»?

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

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

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

Нужно ли явно уничтожать временные таблицы?

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

Можно ли создать временную таблицу в запросе динамического списка или СКД?

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