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