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