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