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