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

· 9 мин

Содержание

Временная таблица живёт только в памяти сервера, у неё нет ни формы списка, ни пункта в навигации. Поэтому, чтобы посмотреть временные таблицы 1С, нужно либо вынуть данные запросом к ней же, либо поймать момент в отладчике, либо записать содержимое в лог. Других «окон» в платформе нет.

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

Как устроены временные таблицы: что нужно знать до отладки

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

Из этого следуют три вывода:

  • 🔹 чтобы таблица пережила один вызов, запросу нужен явный менеджер: Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
  • 🔹 второй запрос увидит таблицу, только если ему передан тот же объект менеджера;
  • 🔹 таблицу можно убрать раньше срока оператором УНИЧТОЖИТЬ ВТ_Товары.

Минимальный пример, на котором дальше удобно тренироваться:

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

Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МВТ;
Запрос.Текст =
"ВЫБРАТЬ
|	Номенклатура.Ссылка КАК Ссылка,
|	Номенклатура.Наименование КАК Наименование
|ПОМЕСТИТЬ ВТ_Товары
|ИЗ
|	Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|	НЕ Номенклатура.ЭтоГруппа";
Запрос.Выполнить();

После этого в переменной МВТ лежит готовая таблица ВТ_Товары, и её можно рассматривать любым из способов ниже.

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

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

Пакет запросов в одном окне

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

ВЫБРАТЬ
	Номенклатура.Ссылка КАК Ссылка,
	Номенклатура.Наименование КАК Наименование
ПОМЕСТИТЬ ВТ_Товары
ИЗ
	Справочник.Номенклатура КАК Номенклатура
ГДЕ
	НЕ Номенклатура.ЭтоГруппа;

ВЫБРАТЬ
	*
ИЗ
	ВТ_Товары

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

Если нужно посмотреть промежуточную таблицу из середины пакета

Допустим, в пакете пять запросов, и в сомнительное место попадает третья таблица. Поступайте так:

  1. Скопируйте пакет в новую закладку консоли.
  2. Оставьте запросы до нужной таблицы включительно.
  3. Последним запросом добавьте ВЫБРАТЬ * ИЗ ВТ_Нужная.
  4. Выполните и сравните результат с ожидаемым.

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

Не оставляйте УНИЧТОЖИТЬ в копии пакета для отладки. Иначе таблица исчезнет до того, как вы на неё посмотрите.

Способ 2. Отладчик: смотрим менеджер временных таблиц на лету

Когда запрос живёт в коде (проведение документа, отчёт, обработка), консоль не поможет: у неё нет вашего менеджера и ваших параметров. Здесь работает отладчик.

Подготовка

  1. Убедитесь, что менеджер временных таблиц задан явно и записан в переменную. Если его создаёт сама платформа, достучаться до него не получится.
  2. Поставьте точку останова (клавиша F9) на строке сразу после Запрос.Выполнить() пакета, который создаёт нужную таблицу.
  3. Запустите отладку и воспроизведите действие, например проведите документ.

Что делать на точке останова

Откройте окно вычисления выражения (в конфигураторе Shift+F9) и выполните выборку по таблице отдельным запросом с тем же менеджером. Для этого удобно держать под рукой готовую строку:

Выборка = Новый Запрос("ВЫБРАТЬ * ИЗ ВТ_Товары");

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

ЗапросОтладка = Новый Запрос("ВЫБРАТЬ * ИЗ ВТ_Товары");
ЗапросОтладка.МенеджерВременныхТаблиц = МВТ;
ТаблицаОтладка = ЗапросОтладка.Выполнить().Выгрузить();

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

Вычисление выражения с запросом в отладчике выполняет код в вашем сеансе. Не вызывайте там ничего, что пишет в базу или меняет состояние объекта: проведение, запись, изменение реквизитов.

Сравнение двух способов

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

Способ 3. Технологический журнал и замеры: когда нужен SQL, а не таблица значений

Иногда интересует не содержимое, а то, во что запрос превратился на стороне СУБД. Для этого годится технологический журнал сервера 1С: в нём можно включить события обращения к СУБД и увидеть текст SQL, время выполнения и количество строк. Настройка делается в файле logcfg.xml в каталоге конфигурации сервера.

При работе на Microsoft SQL Server временные таблицы платформы видны в тексте SQL под служебными именами вида #tt1, #tt2. Ваше имя ВТ_Товары СУБД не знает: соответствие между ними вы находите по порядку и тексту запросов.

Что полезно искать в журнале:

  • 📌 запросы, создающие временные таблицы, и их длительность;
  • 📌 повторное создание одной и той же таблицы в цикле;
  • 📌 обращения без индекса к большим временным таблицам.

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

Технологический журнал за день на нагруженной базе вырастает до десятков гигабайт. Включайте нужные события на короткое время и ограничивайте их по продолжительности. Включение и отключение журнала не обрывает сеансы, но правку logcfg.xml лучше делать вне пикового часа.

Видимость и имена: почему таблицу «не видно»

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

  1. Менеджер у каждой таблицы свой. Запрос с другим менеджером обращается к этой же таблице как к несуществующей, и платформа выдаёт ошибку вида «Таблица не найдена».
  2. Имя уникально в пределах менеджера. Повторный ПОМЕСТИТЬ ВТ_Товары в тот же менеджер без УНИЧТОЖИТЬ даёт ошибку повторного создания.
  3. Таблица живёт до уничтожения менеджера. Вышли из процедуры, где он создан, и объект исчез вместе с таблицами. В общих модулях с повторным использованием возвращаемых значений такой менеджер хранить нельзя.
  4. Клиент менеджера не получает. МенеджерВременныхТаблиц существует на сервере; на клиенте его создать и передать нельзя, поэтому всё содержимое смотрите через серверную процедуру.

Хорошая привычка: давайте таблицам понятные префиксы (ВТ_Остатки, ВТ_Документы). Тогда в журнале и в отладке сразу ясно, чьи это данные.

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

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

Функция ТаблицаВТекст(Таблица, МаксСтрок = 50)
	Текст = "";
	Счётчик = 0;
	Для Каждого Строка Из Таблица Цикл
		Если Счётчик >= МаксСтрок Тогда
			Текст = Текст + "... и ещё " + (Таблица.Количество() - МаксСтрок) + " строк";
			Прервать;
		КонецЕсли;
		Фрагменты = Новый Массив;
		Для Каждого Колонка Из Таблица.Колонки Цикл
			Фрагменты.Добавить(Колонка.Имя + "=" + Строка[Колонка.Имя]);
		КонецЦикла;
		Текст = Текст + СтрСоединить(Фрагменты, "; ") + Символы.ПС;
		Счётчик = Счётчик + 1;
	КонецЦикла;
	Возврат Текст;
КонецФункции

И вызов в нужном месте:

ЗапросЛог = Новый Запрос("ВЫБРАТЬ * ИЗ ВТ_Товары");
ЗапросЛог.МенеджерВременныхТаблиц = МВТ;
ЗаписьЖурналаРегистрации("Отладка.ВТ_Товары", УровеньЖурналаРегистрации.Информация,,,
	ТаблицаВТекст(ЗапросЛог.Выполнить().Выгрузить()));

Запись появится в журнале регистрации (открывается из раздела Администрирование в 1С:Предприятии, в блоке обслуживания) по событию Отладка.ВТ_Товары. Фильтр по событию оставит только ваши записи.

Три ограничения, которые экономят нервы:

  • Лимит на размер комментария события в журнале ограничен, поэтому пишите не больше нескольких десятков строк, а выборку сужайте условием.
  • В продуктивной базе в лог попадают персональные данные: ФИО, паспорта, зарплаты. Выводите только идентификаторы и суммы.
  • После разбора вызов уберите из кода: он оставляет лишний запрос в каждом проведении.

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

В файловой базе или при локальной проверке достаточно Сообщить(ТаблицаВТекст(...)): сообщение появится в окне сообщений.

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

Эти ситуации не пересказывают шаги выше, а отвечают на вопрос «почему не получается».

Диагностика: выберите симптом

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

Если не помогло

Бывает, что таблица вроде бы есть, а данные выглядят неверно. Проверьте по порядку:

  1. Выполните тот же запрос в консоли с теми же параметрами. Если результат другой, проблема в параметрах или в контексте.
  2. Замените ПОМЕСТИТЬ на обычный ВЫБРАТЬ и посмотрите результат по частям. Сложный запрос удобно разбирать от внутренней части наружу.
  3. Проверьте права: при работе под ограничением прав на уровне записей запрос видит не все строки. Для диагностики используйте ВЫБРАТЬ РАЗРЕШЕННЫЕ осознанно, а не по привычке.
  4. Сверьте поле «дата» и «период» с параметрами отбора: чаще всего «потерянные» строки отсекает граница периода, которая включает конец дня или нет.

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

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

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