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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

"ВЫБРАТЬ

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

| Товары.Количество

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

|ИЗ

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

|ГДЕ

| Товары.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);

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

// Читаем временную таблицу

ЧтениеВТ = Новый Запрос;

ЧтениеВТ.МенеджерВременныхТаблиц = МенеджерВТ;

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

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

Переменная Результат теперь содержит таблицу значений с полным содержимым временной таблицы. Её можно посмотреть в отладчике через «Вычислить выражение», вывести в сообщение или обработать в цикле.

Порядок действий
  1. 1
    Создайте объект МенеджерВременныхТаблиц и сохраните его в отдельной переменной
  2. 2
    Выполните основной запрос с ПОМЕСТИТЬ, привязанный к этому менеджеру
  3. 3
    Создайте второй запрос и установите ему тот же менеджер
  4. 4
    Выполните ВЫБРАТЬ * ИЗ ИмяВременнойТаблицы и выгрузите результат
  5. 5
    Проверьте содержимое в отладчике или выведите в табличный документ

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

Если код уже написан и вы просто хотите посмотреть, что попало во временную таблицу, необязательно переписывать модуль. Остановитесь точкой останова после выполнения запроса и в окне «Вычислить выражение» (Shift+F9) выполните обращение к менеджеру.

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

// Список имён временных таблиц в менеджере

Для Каждого ОписаниеТаблицы ИЗ МенеджерВТ.Таблицы Цикл

Сообщить(ОписаниеТаблицы.Имя);

КонецЦикла;

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

ТЗ = МенеджерВТ.Таблицы.Найти("ВТ_Товары").ПолучитьДанные();

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

Способ 3: консоль запросов с временными таблицами

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

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

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

Сравнение способов чтения

Отдельный запрос к менеджеру

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

Отладчик и ПолучитьДанные()

Самый быстрый для разовой диагностики без изменения кода. Не подходит для автоматизированной обработки.

Консоль запросов

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

Как проверить, что таблица создана и не пуста

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

Проверка существования делается через коллекцию МенеджерВТ.Таблицы.Найти("ИмяТаблицы"): если метод вернул Неопределено, таблицы нет. Проверка наполненности — либо через ПолучитьДанные().Количество(), либо запросом ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ ВТ_Товары. Второй вариант быстрее на больших таблицах, так как не выгружает все строки на клиент.

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

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

Таблица есть в менеджере
Норма

Таблицы.Найти() вернул объект описания

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

Вернул Неопределено — таблица не создана или менеджер другой

Таблица заполнена
Норма

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

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

Ноль строк — проверяйте условия ГДЕ и соединения в исходном запросе

Чтение выполняется
Норма

Запрос ВЫБРАТЬ * ИЗ ВТ выполняется без ошибок

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

Ошибка «Таблица не найдена» — запрос привязан к другому менеджеру

Типичные ошибки при чтении временных таблиц

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

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

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

Типичные ошибки
01
Чтение через новый менеджер временных таблиц — ошибка «Таблица не найдена», хотя таблица создавалась
02
Попытка прочитать таблицу после УНИЧТОЖИТЬ или закрытия менеджера — данные уже удалены
03
Поиск временной таблицы в результате Выполнить() — там только финальная выборка пакета
04
Потеря менеджера при выходе из процедуры — таблицы недоступны вызывающему коду
05
Опечатка в имени таблицы при чтении — имена регистронезависимы, но должны совпадать посимвольно

Производительность и ограничения

Выгрузка временной таблицы целиком через ВЫБРАТЬ * или ПолучитьДанные() переносит все строки в память сервера или клиента. Для отладки на копии базы это приемлемо, но в продуктивном коде так делать не стоит без необходимости: временные таблицы тем и хороши, что данные остаются на стороне СУБД и участвуют в соединениях без передачи по сети.

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

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

FAQ: частые вопросы о временных таблицах в 1С

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

Да, если передать туда тот же экземпляр МенеджерВременныхТаблиц параметром. Без менеджера временная таблица недоступна — она не существует вне его контекста.

Чем посмотреть список всех временных таблиц в менеджере?

Свойством МенеджерВТ.Таблицы — это коллекция описаний с именами таблиц. В отладчике достаточно вычислить это свойство и развернуть коллекцию.

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

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

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

Конструкцией УНИЧТОЖИТЬ ИмяТаблицы в тексте запроса, выполненном с тем же менеджером. Это освобождает ресурсы СУБД и рекомендуется для крупных таблиц в длинных пакетах.

Можно ли изменить данные во временной таблице?

Напрямую нет — временные таблицы доступны только для чтения. Чтобы изменить состав, выполните новый запрос: выберите данные из старой таблицы с нужными преобразованиями и поместите результат в новую таблицу, а старую уничтожьте.

В чём разница между Выполнить() и ВыполнитьПакет() при отладке?

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

Итог

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

Временная таблица живёт только внутри своего менеджера временных таблиц. Читается она отдельным запросом ВЫБРАТЬ * ИЗ ИмяТаблицы с тем же менеджером, либо через МенеджерВТ.Таблицы.Найти().ПолучитьДанные() в отладчике. Главные причины проблем — другой менеджер, уничтоженная таблица и ожидание данных в результате пакета вместо менеджера.