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