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

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

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

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

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

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

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

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

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

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

Способ 1: загрузить таблицу значений как параметр запроса

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

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

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

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

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

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

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

"ВЫБРАТЬ

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

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

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

|ИЗ

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

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

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

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

Способ 2: поместить результат запроса во временную таблицу

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

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

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

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

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

"ВЫБРАТЬ

| Реализация.Ссылка КАК Документ,

| Реализация.Контрагент КАК Контрагент

|ПОМЕСТИТЬ ВТ_Документы

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода

| И Реализация.Проведен";

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

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

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

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

Пакетный запрос: несколько временных таблиц в одном тексте

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

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

"ВЫБРАТЬ

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

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

|ИЗ

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

|;

|ВЫБРАТЬ

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

| Остатки.КоличествоОстаток КАК Остаток

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Отбор КАК Отбор

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

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

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

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

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

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

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

Проверка.Текст = "ВЫБРАТЬ * ИЗ ВТ_Товары КАК ВТ";

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

Сообщить("Строк во временной таблице: " + Выгрузка.Количество());

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

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

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

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

Выборка возвращает строки или пустой результат без исключения

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

Ошибка «Таблица не найдена» — менеджер не назначен или таблица не создана

Количество строк во временной таблице
Норма

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

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

Ноль строк — параметр пустой или таблица значений не заполнена

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

Соединение возвращает ожидаемые совпадения

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

Пустой результат — несовпадение типов полей или значений ключей

Типичные ошибки и ограничения

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

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

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

Типичные ошибки
01
Запросу не назначен МенеджерВременныхТаблиц — временная таблица исчезает сразу после выполнения, следующий запрос получает ошибку «Таблица не найдена»
02
Имена колонок таблицы значений не совпадают с полями в тексте запроса — ошибка «Поле не найдено» при выполнении
03
Менеджер создан внутри функции и потерян после возврата — временные таблицы недоступны в вызывающем коде
04
Передача огромной таблицы значений параметром — рост потребления памяти и замедление вместо ускорения

Когда какой способ выбирать

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

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

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

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

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

Частые вопросы

Итог

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

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

Почему возникает ошибка «Таблица не найдена» при обращении к временной таблице?

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

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

Да. Выгрузите табличную часть в таблицу значений методом Выгрузить() и передайте её параметром, как обычную таблицу значений. Дальше в тексте запроса опишите выборку из параметра с ПОМЕСТИТЬ во временную таблицу.

Как удалить временную таблицу, когда она больше не нужна?

Добавьте в текст запроса оператор УНИЧТОЖИТЬ с именем таблицы, например: УНИЧТОЖИТЬ ВТ_Товары. Либо закройте весь менеджер методом Закрыть() — тогда удалятся все его временные таблицы. В файловом режиме это менее критично, в клиент-серверном помогает освободить память СУБД.

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

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

Видна ли временная таблица в другом сеансе или другом пользователю?

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

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

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