Разработка сложных отчетов на Системе Компоновки Данных (СКД) часто приводит к ситуации, когда итоговый результат не соответствует ожиданиям. В отчете могут использоваться десятки временных таблиц, сложные соединения и множество параметров, устанавливаемых программно. Чтобы найти ошибку, нам часто требуется «вытащить» запрос из макета и выполнить его в обычной консоли. Однако напрямую получить объект Запрос из набора данных СКД нельзя — там хранится только текст.
В этой статье мы подробно разберем, как эффективно отладить такой отчет, получить текст запроса вместе со значениями параметров и перенести все это в консоль.
Когда мы работаем с СКД, схема компоновки данных содержит наборы данных. В наборе данных типа "Запрос" есть свойство Запрос, которое содержит строку с текстом SQL-подобного запроса 1С. Также в настройках компоновки или параметрах данных есть значения параметров.
Сложность заключается в том, что:
НаборДанных нет готового метода, который вернул бы нам объект Запрос с заполненными параметрами.Рассмотрим несколько способов решения этой задачи: от использования готовых инструментов до написания собственного кода.
Если вы находитесь в процессе отладки кода (например, поставили точку останова в модуле объекта или формы отчета), вы можете воспользоваться функцией-оберткой. Суть метода заключается в том, чтобы программно взять текст запроса из схемы и "скормить" ему параметры из коллекции значений параметров макета.
Автор темы предложил простое и элегантное решение — функцию, которую можно разместить, например, в общем модуле расширения или во временной обработке.
Рассмотрим код функции:
Функция ПолучитьЗапросИзНабораДанных(СтрЗапрос, ЗначенияПараметров) Экспорт
// Создаем новый объект Запрос на основе текста из СКД
Запрос = Новый Запрос(СтрЗапрос);
// Перебираем коллекцию параметров и устанавливаем их в запрос
Для каждого Параметр Из ЗначенияПараметров Цикл
Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение);
КонецЦикла;
Возврат Запрос;
КонецФункции
Как этим пользоваться при отладке:
СхемаКомпоновкиДанных.НаборыДанных.ИмяВашегоНабора.Запрос и коллекцию параметров (например, из КомпоновщикМакета.ЗначенияПараметров или подготовленной структуры).Важное замечание: Данный код работает идеально для простых типов параметров (Число, Строка, Ссылка, Дата). Однако, если в параметрах СКД используется СтандартныйПериод, то в тексте запроса обычно используются параметры &Период.ДатаНачала и &Период.ДатаОкончания (или схожие конструкции), а в коллекции значений может лежать сам объект периода. В таких случаях может потребоваться доработка функции для разложения сложных типов. Если требуется не только посмотреть сформированный запрос, но и пошагово пройти код непосредственно в режиме «1С:Предприятие», для этого можно использовать отладчик OneDebugger с точками останова, просмотром переменных и вычислением выражений в контексте остановки.
Это наиболее профессиональный подход, который экономит массу времени. Вместо того чтобы пытаться вычленить "чистый" запрос, лучше отлаживать саму СКД целиком.
Многие современные инструменты (например, универсальные консоли СКД с Инфостарта) умеют загружать схему и настройки и показывать итоговый запрос.
Давайте разберем алгоритм действий:
ЗаписьXML и СериализаторXDTO).После этого консоль сама сформирует макет компоновки. Большинство таких инструментов имеют вкладку "Макет" или "Запрос", где можно увидеть итоговый текст запроса, который реально отправляется в СУБД. Это критически важно, так как СКД часто модифицирует исходный текст запроса:
ГДЕ.Если у вас нет под рукой мощных инструментов, но нужно увидеть реальный запрос, который сформировала система с учетом всех галочек пользователя, мы можем получить его программно. Запрос в НаборыДанных — это "черновик". "Чистовик" находится в макете.
Посмотрим, как получить реальный исполняемый текст:
// 1. Получаем настройки из компоновщика (то, что выбрал пользователь)
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// 2. Создаем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
// 3. Выполняем компоновку. Это самый важный шаг.
// Система превращает настройки и схему в конкретный макет исполнения.
Макет = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки);
// 4. Теперь в макете можно найти итоговый запрос
// Обратите внимание: в макете может быть несколько наборов данных
Для Каждого Набор ИЗ Макет.НаборыДанных Цикл
Если ТипЗнч(Набор) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
Сообщить("Запрос для набора: " + Набор.Имя);
Сообщить(Набор.Запрос); // Это реальный SQL/текст запроса с учетом отборов
// Значения параметров для исполнения лежат здесь:
// Макет.ЗначенияПараметров
КонецЕсли;
КонецЦикла;
Этот способ позволяет увидеть, как именно СКД трансформировала ваш текст: добавила ли она условия отбора в параметры виртуальных таблиц или оставила их в секции ГДЕ, и какие поля реально выбираются. Похожий механизм используется при преобразовании динамического списка в отчет СКД для сохранения наложенных пользователем отборов. Для дальнейшего разбора запроса можно использовать инженерную консоль запросов — она умеет забирать из отладчика текст вместе с параметрами и временными таблицами, а также открывать запрос из готового отчета на СКД вместе с настройками набора данных.
Если вам нужно просто быстро посмотреть текст запроса с подставленными значениями параметров (как он уходит на SQL-сервер), и вы не хотите писать код:
В нижней части окна замера будет показан полный текст запроса. Если включен режим отображения запросов, вы увидите его уже с подставленными значениями параметров (например, вместо &П1 будет стоять конкретная дата или ссылка). Это самый быстрый способ "подглядеть", что происходит "под капотом", не прибегая к внешним обработкам.
Для отладки сложных запросов в СКД не стоит пытаться воссоздать их вручную. Используйте: