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