При работе в среде управляемого приложения, особенно в таких сложных конфигурациях, как 1С:Зарплата и управление персоналом 3.1, разработчики часто сталкиваются с необходимостью отладки огромных запросов. Ситуация осложняется тем, что запросы выполняются на сервере, а визуализировать данные (например, просмотреть содержимое временных таблиц) хочется в удобном интерфейсе. Однако метод ОткрытьФорму() доступен только на клиенте, что создает определенный барьер. Разберем подробно, как решить эту задачу и какие инструменты отладки предлагает платформа.
Прежде всего, проанализируем причину ограничения. Платформа 1С строго разделяет контексты выполнения. Сервер отвечает за работу с данными и бизнес-логику, у него нет «экрана», на который можно вывести форму. Клиент отвечает за взаимодействие с пользователем. Когда мы находимся внутри серверной процедуры (например, в общем модуле или модуле менеджера), попытка вызвать ОткрытьФорму() приведет к ошибке, так как сервер «не знает», в каком сеансе и на каком мониторе нужно отобразить это окно.
Начнем с самого простого и штатного метода, который не требует написания сложного кода. Начиная с версии платформы 8.3.8, у объекта Запрос и МенеджерВременныхТаблиц появились методы, позволяющие быстро получить данные.
Рассмотрим ситуацию: у нас есть объект Запрос, в котором уже инициализирован МенеджерВременныхТаблиц и выполнены промежуточные части пакета. Чтобы посмотреть содержимое конкретной временной таблицы в режиме отладки, выполним следующие шаги:
// Где "ВТ_ДанныеСотрудников" - имя вашей временной таблицы
Запрос.МенеджерВременныхТаблиц.Таблицы.Найти("ВТ_ДанныеСотрудников").ПолучитьДанные().Выгрузить()
Платформа выполнит неявный запрос к менеджеру временных таблиц и вернет ТаблицуЗначений. Нажав на кнопку «Показать значения в отдельном окне» (лупа), мы увидим содержимое таблицы в виде таблицы. Это избавляет от необходимости открывать какие-либо формы программно.
Если временных таблиц много (как это часто бывает в регламентированной отчетности ЗУП), просматривать их по одной в отладчике неудобно. Рассмотрим вариант автоматизации, предложенный участниками сообщества. Мы можем создать общий модуль (например, НТХ_Отладка) с признаком «Сервер» и «Вызов сервера».
Создадим функцию, которая будет собирать все временные таблицы в одну структуру:
Функция ВыгрузитьВсеВременныеТаблицы(МенеджерВременныхТаблиц) Экспорт
РезультатСтруктура = Новый Структура;
Для Каждого Элемент Из МенеджерВременныхТаблиц.Таблицы Цикл
ТекстЗапроса = "ВЫБРАТЬ * ИЗ " + Элемент.ПолноеИмя;
ЗапросДебаг = Новый Запрос(ТекстЗапроса);
ЗапросДебаг.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Попытка
РезультатСтруктура.Вставить(Элемент.ПолноеИмя, ЗапросДебаг.Выполнить().Выгрузить());
Исключение
// Обработка случая, если таблица пуста или еще не инициализирована
Продолжить;
КонецПопытки;
КонецЦикла;
Возврат РезультатСтруктура;
КонецФункции
Теперь в любой момент отладки в окне «Вычислить выражение» достаточно написать НТХ_Отладка.ВыгрузитьВсеВременныеТаблицы(Запрос.МенеджерВременныхТаблиц). Мы получим структуру, где ключи — это названия таблиц, а значения — их содержимое. Это гораздо нагляднее при анализе цепочки сложных расчетов.
Если ваша цель — не просто посмотреть данные в отладчике, а именно вывести их в специализированную форму (например, универсальный отчет), необходимо реализовать «двухэтапную» схему. Поскольку сервер не может открыть форму, он должен подготовить данные и «сообщить» об этом клиенту.
Разберем алгоритм реализации:
ТаблицуЗначений.ОткрытьФорму(), передавая адрес хранилища в параметрах.Пример кода на сервере:
АдресХранилища = ПоместитьВоВременноеХранилище(ТаблицаСДанными, ЭтаФорма.УникальныйИдентификатор);
Возврат АдресХранилища;
Пример кода на клиенте:
Адрес = ПодготовитьДанныеНаСервере(); // Вызов серверной функции
ПараметрыФормы = Новый Структура("АдресДанных", Адрес);
ОткрытьФорму("ОбщаяФорма.МояФормаПросмотраВТ", ПараметрыФормы);
Иногда запрос выполняется в фоновом задании, где нет прямой связи с клиентским сеансом в реальном времени. В этом случае участники форума рекомендуют сохранять промежуточные результаты в файл или ТабличныйДокумент.
Проанализируем пример: мы можем программно сформировать ТабличныйДокумент, вывести в него результаты всех ВТ и сохранить его на диск в формате .mxl. Позже этот файл можно открыть любым сеансом 1С для детального анализа. Это особенно полезно при отладке интеграций или тяжелых ночных расчетов.
ТабДок = Новый ТабличныйДокумент;
// ... Заполнение ТабДок данными из ВТ ...
ТабДок.Записать("C:\Debug\Result.mxl", ТипФайлаТабличногоДокумента.MXL);
Выясним, какой еще штатный инструмент есть у объекта Запрос. Метод ВыполнитьПакетСПромежуточнымиДанными() возвращает массив результатов выполнения всех запросов в пакете, включая временные таблицы. Это самый «чистый» способ получить данные всех ВТ одним вызовом, не перебирая менеджер вручную.
Рассмотрим пример:
МассивРезультатов = Запрос.ВыполнитьПакетСПромежуточнымиДанными();
// МассивРезультатов содержит РезультатЗапроса для каждого запроса в пакете
Для Каждого ТекРезультат Из МассивРезультатов Цикл
Если Не ТекРезультат.Пустой() Тогда
ТаблицаДанных = ТекРезультат.Выгрузить();
// Теперь таблицу можно анализировать
КонецЕсли;
КонецЦикла;
Мы рассмотрели несколько подходов к решению проблемы. Если вам нужно быстро посмотреть данные «здесь и сейчас», используйте вычисление выражений в отладчике с методом ПолучитьДанные(). Если вы занимаетесь глубокой разработкой сложных отчетов в ЗУП, лучше всего внедрить вспомогательный отладочный модуль, который будет готовить данные для вывода на клиент через временное хранилище. Помните, что архитектура управляемого приложения требует четкого разделения: сервер готовит данные, клиент их отображает.