Содержимое временной таблицы запроса: где его увидеть при отладке
Содержание
Временная таблица живёт только в памяти сервера, у неё нет ни формы списка, ни пункта в навигации. Поэтому, чтобы посмотреть временные таблицы 1С, нужно либо вынуть данные запросом к ней же, либо поймать момент в отладчике, либо записать содержимое в лог. Других «окон» в платформе нет.
Ниже три рабочих способа, от самого простого к самому тяжёлому. Все они опираются на одно правило: временная таблица видна только тому менеджеру временных таблиц, в котором её создали.
Как устроены временные таблицы: что нужно знать до отладки
Временная таблица создаётся оператором ПОМЕСТИТЬ ВТ_Товары и существует, пока жив объект МенеджерВременныхТаблиц, к которому привязан запрос. Если менеджер не задан, платформа создаёт его внутри Запрос.Выполнить(), а после выполнения пакета уничтожает вместе со всеми таблицами. Заглянуть в такую таблицу снаружи уже нельзя.
Из этого следуют три вывода:
- 🔹 чтобы таблица пережила один вызов, запросу нужен явный менеджер:
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; - 🔹 второй запрос увидит таблицу, только если ему передан тот же объект менеджера;
- 🔹 таблицу можно убрать раньше срока оператором
УНИЧТОЖИТЬ ВТ_Товары.
Минимальный пример, на котором дальше удобно тренироваться:
МВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МВТ;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ПОМЕСТИТЬ ВТ_Товары
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ЭтоГруппа";
Запрос.Выполнить();
После этого в переменной МВТ лежит готовая таблица ВТ_Товары, и её можно рассматривать любым из способов ниже.
Способ 1. Консоль запросов: пакет и выборка из временной таблицы
Консоль запросов — это внешняя обработка (их несколько разных авторов), в самой платформе её нет. Отсюда и разница в интерфейсах, но принцип у всех одинаков.
Пакет запросов в одном окне
Самый простой путь: пишете в консоли пакет, где первый запрос кладёт данные во временную таблицу, а последний выбирает из неё всё.
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Наименование КАК Наименование
ПОМЕСТИТЬ ВТ_Товары
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
НЕ Номенклатура.ЭтоГруппа;
ВЫБРАТЬ
*
ИЗ
ВТ_Товары
Запросы в пакете разделяются точкой с запятой. Консоль выполнит их одним вызовом с общим менеджером, и вы увидите результат последнего запроса. Это и есть «просмотр» временной таблицы.
Если нужно посмотреть промежуточную таблицу из середины пакета
Допустим, в пакете пять запросов, и в сомнительное место попадает третья таблица. Поступайте так:
- Скопируйте пакет в новую закладку консоли.
- Оставьте запросы до нужной таблицы включительно.
- Последним запросом добавьте
ВЫБРАТЬ * ИЗ ВТ_Нужная. - Выполните и сравните результат с ожидаемым.
Многие консоли умеют сами показывать результат каждого запроса пакета отдельной закладкой. Если у вашей так, достаточно найти закладку с нужным именем таблицы.
Не оставляйте УНИЧТОЖИТЬ в копии пакета для отладки. Иначе таблица исчезнет до того, как вы на неё посмотрите.
Способ 2. Отладчик: смотрим менеджер временных таблиц на лету
Когда запрос живёт в коде (проведение документа, отчёт, обработка), консоль не поможет: у неё нет вашего менеджера и ваших параметров. Здесь работает отладчик.
Подготовка
- Убедитесь, что менеджер временных таблиц задан явно и записан в переменную. Если его создаёт сама платформа, достучаться до него не получится.
- Поставьте точку останова (клавиша
F9) на строке сразу послеЗапрос.Выполнить()пакета, который создаёт нужную таблицу. - Запустите отладку и воспроизведите действие, например проведите документ.
Что делать на точке останова
Откройте окно вычисления выражения (в конфигураторе Shift+F9) и выполните выборку по таблице отдельным запросом с тем же менеджером. Для этого удобно держать под рукой готовую строку:
Выборка = Новый Запрос("ВЫБРАТЬ * ИЗ ВТ_Товары");
Но надёжнее другой приём: временно добавьте в код две строки, которые складывают содержимое в обычную переменную, и просто смотрите её в окне локальных переменных.
ЗапросОтладка = Новый Запрос("ВЫБРАТЬ * ИЗ ВТ_Товары");
ЗапросОтладка.МенеджерВременныхТаблиц = МВТ;
ТаблицаОтладка = ЗапросОтладка.Выполнить().Выгрузить();
Остановитесь на следующей строке, раскройте ТаблицаОтладка в локальных переменных или вычислите её в окне выражений. Таблица значений раскрывается строками и колонками, так что содержимое видно целиком. После отладки эти три строки удалите.
Вычисление выражения с запросом в отладчике выполняет код в вашем сеансе. Не вызывайте там ничего, что пишет в базу или меняет состояние объекта: проведение, запись, изменение реквизитов.
Сравнение двух способов
| Способ | Когда подходит | Минус |
|---|---|---|
| Консоль запросов | Запрос можно вынуть из кода вместе с параметрами | Нет вашего контекста, параметры приходится задавать вручную |
| Отладчик с выгрузкой | Запрос в коде, нужны реальные данные момента | Нужен доступ к конфигуратору и перезапуск сеанса |
| Запись в лог | Ошибка воспроизводится у пользователя, отладчика нет | Нужна правка кода и публикация |
Способ 3. Технологический журнал и замеры: когда нужен SQL, а не таблица значений
Иногда интересует не содержимое, а то, во что запрос превратился на стороне СУБД. Для этого годится технологический журнал сервера 1С: в нём можно включить события обращения к СУБД и увидеть текст SQL, время выполнения и количество строк. Настройка делается в файле logcfg.xml в каталоге конфигурации сервера.
При работе на Microsoft SQL Server временные таблицы платформы видны в тексте SQL под служебными именами вида #tt1, #tt2. Ваше имя ВТ_Товары СУБД не знает: соответствие между ними вы находите по порядку и тексту запросов.
Что полезно искать в журнале:
- 📌 запросы, создающие временные таблицы, и их длительность;
- 📌 повторное создание одной и той же таблицы в цикле;
- 📌 обращения без индекса к большим временным таблицам.
Для оценки времени отдельных участков кода пригодится замер производительности: он покажет, на каком запросе пакета теряется время. Это не просмотр данных, а поиск тяжёлой строки, поэтому используйте его вместе с первыми двумя способами.
Технологический журнал за день на нагруженной базе вырастает до десятков гигабайт. Включайте нужные события на короткое время и ограничивайте их по продолжительности. Включение и отключение журнала не обрывает сеансы, но правку logcfg.xml лучше делать вне пикового часа.
Видимость и имена: почему таблицу «не видно»
Самая частая причина, по которой пользователь не может посмотреть временную таблицу, — не отладка, а область видимости. Четыре правила:
- Менеджер у каждой таблицы свой. Запрос с другим менеджером обращается к этой же таблице как к несуществующей, и платформа выдаёт ошибку вида «Таблица не найдена».
- Имя уникально в пределах менеджера. Повторный
ПОМЕСТИТЬ ВТ_Товарыв тот же менеджер безУНИЧТОЖИТЬдаёт ошибку повторного создания. - Таблица живёт до уничтожения менеджера. Вышли из процедуры, где он создан, и объект исчез вместе с таблицами. В общих модулях с повторным использованием возвращаемых значений такой менеджер хранить нельзя.
- Клиент менеджера не получает.
МенеджерВременныхТаблицсуществует на сервере; на клиенте его создать и передать нельзя, поэтому всё содержимое смотрите через серверную процедуру.
Хорошая привычка: давайте таблицам понятные префиксы (ВТ_Остатки, ВТ_Документы). Тогда в журнале и в отладке сразу ясно, чьи это данные.
Как вывести содержимое временной таблицы в лог программно
Когда ошибка возникает у пользователя и подключить отладчик нельзя, пишите содержимое в журнал регистрации. Короткая функция превращает таблицу значений в текст:
Функция ТаблицаВТекст(Таблица, МаксСтрок = 50)
Текст = "";
Счётчик = 0;
Для Каждого Строка Из Таблица Цикл
Если Счётчик >= МаксСтрок Тогда
Текст = Текст + "... и ещё " + (Таблица.Количество() - МаксСтрок) + " строк";
Прервать;
КонецЕсли;
Фрагменты = Новый Массив;
Для Каждого Колонка Из Таблица.Колонки Цикл
Фрагменты.Добавить(Колонка.Имя + "=" + Строка[Колонка.Имя]);
КонецЦикла;
Текст = Текст + СтрСоединить(Фрагменты, "; ") + Символы.ПС;
Счётчик = Счётчик + 1;
КонецЦикла;
Возврат Текст;
КонецФункции
И вызов в нужном месте:
ЗапросЛог = Новый Запрос("ВЫБРАТЬ * ИЗ ВТ_Товары");
ЗапросЛог.МенеджерВременныхТаблиц = МВТ;
ЗаписьЖурналаРегистрации("Отладка.ВТ_Товары", УровеньЖурналаРегистрации.Информация,,,
ТаблицаВТекст(ЗапросЛог.Выполнить().Выгрузить()));
Запись появится в журнале регистрации (открывается из раздела Администрирование в 1С:Предприятии, в блоке обслуживания) по событию Отладка.ВТ_Товары. Фильтр по событию оставит только ваши записи.
Три ограничения, которые экономят нервы:
- Лимит на размер комментария события в журнале ограничен, поэтому пишите не больше нескольких десятков строк, а выборку сужайте условием.
- В продуктивной базе в лог попадают персональные данные: ФИО, паспорта, зарплаты. Выводите только идентификаторы и суммы.
- После разбора вызов уберите из кода: он оставляет лишний запрос в каждом проведении.
Для повторяющихся задач вынесите отладочный вывод в отдельную процедуру общего серверного модуля и включайте её по флагу, например по константе «Режим отладки». Тогда не придётся каждый раз править код проведения, а в рабочей базе вывод по умолчанию выключен и ничего не стоит.
В файловой базе или при локальной проверке достаточно Сообщить(ТаблицаВТекст(...)): сообщение появится в окне сообщений.
Типичные ошибки при работе с временными таблицами
Эти ситуации не пересказывают шаги выше, а отвечают на вопрос «почему не получается».
Запрос.МенеджерВременныхТаблиц = МВТ. Проверьте, что МВТ не пересоздаётся между вызовами.УНИЧТОЖИТЬ ВТ_Имя или используйте другое имя. Если таблица в пакете создаётся в цикле, уничтожайте её в конце каждого прохода.УНИЧТОЖИТЬ и новый ПОМЕСТИТЬ. Поставьте точку останова раньше, сразу после нужного Выполнить().Отдельный случай: одинаковые строки в таблице. Если в ВТ_ попали дубли после соединения, поможет ВЫБРАТЬ РАЗЛИЧНЫЕ либо группировка, а до этого проверьте в отладке, на каком соединении строки размножились.
Если не помогло
Бывает, что таблица вроде бы есть, а данные выглядят неверно. Проверьте по порядку:
- Выполните тот же запрос в консоли с теми же параметрами. Если результат другой, проблема в параметрах или в контексте.
- Замените
ПОМЕСТИТЬна обычныйВЫБРАТЬи посмотрите результат по частям. Сложный запрос удобно разбирать от внутренней части наружу. - Проверьте права: при работе под ограничением прав на уровне записей запрос видит не все строки. Для диагностики используйте
ВЫБРАТЬ РАЗРЕШЕННЫЕосознанно, а не по привычке. - Сверьте поле «дата» и «период» с параметрами отбора: чаще всего «потерянные» строки отсекает граница периода, которая включает конец дня или нет.
Если расхождение держится, выгрузите временную таблицу в табличный документ или таблицу значений и сохраните в файл. Так результат можно показать коллеге или приложить к обращению, не передавая базу.
Частые вопросы
Можно ли посмотреть временную таблицу после завершения работы запроса?
МенеджерВременныхТаблиц и он ещё жив. Без явного менеджера таблицы уничтожаются сразу после выполнения.Есть ли в 1С специальное окно для временных таблиц?
ВЫБРАТЬ * ИЗ ВТ_Имя с тем же менеджером, через отладчик или в логе.Как узнать имена всех таблиц в менеджере?
ПОМЕСТИТЬ, поэтому проще вести их список в комментарии к процедуре. Использовать общие префиксы (ВТ_) помогает искать их в тексте модуля поиском.