Как программно получить исполняемый текст запроса из системы компоновки данных (СКД)

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки сложных отчетов на базе Системы компоновки данных (СКД) часто возникает необходимость перехватить итоговый текст запроса. Это требуется для отладки, выполнения запроса в сторонних обработках или передачи данных в другие формы. Особенность СКД заключается в том, что исходный текст запроса, написанный в схеме, содержит "мягкие" параметры (в фигурных скобках {}), которые платформа динамически модифицирует в зависимости от настроек пользователя. В этой статье мы подробно разберем, как получить «чистый» исполняемый код запроса, который система отправляет на сервер СУБД.

Зачем нужен исполняемый текст запроса

Когда мы пишем запрос в конструкторе СКД, мы часто используем расширения языка запросов для компоновки. Например, конструкция {ГДЕ Ссылка.*} позволяет системе автоматически добавлять отбор, если пользователь его установил. Однако, если нам нужно выполнить этот же запрос вручную через объект Запрос, нам необходим текст, где все эти условия уже либо удалены (если они не заполнены), либо преобразованы в жесткие условия ГДЕ с конкретными параметрами. Простое копирование текста из схемы здесь не поможет. Для интерактивного получения готового запроса без написания вспомогательного кода можно использовать инженерную консоль с возможностью извлечения текста запроса из отчетов СКД.

Пошаговый алгоритм получения макета компоновки

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


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // 1. Получаем текущие настройки пользователя (отборы, параметры)
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // 2. Инициализируем объект для хранения данных расшифровки
    ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
    
    // 3. Создаем компоновщик макета
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    
    // 4. Генерация макета компоновки. Именно на этом этапе формируется итоговый текст запроса.
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    // Теперь в объекте МакетКомпоновки содержится итоговая информация
КонецПроцедуры

Где искать текст запроса в макете

После того как метод Выполнить() завершил свою работу, объект МакетКомпоновки (типа МакетКомпоновкиДанных) содержит коллекцию НаборыДанных. Каждый элемент этой коллекции соответствует набору данных из вашей схемы. Если у вас один основной набор данных (запрос), его текст можно получить следующим образом:

Вариант 1: Обращение по имени

Если вы знаете имя набора данных (например, НаборДанных1), используйте прямой доступ:

ТекстИтоговогоЗапроса = МакетКомпоновки.НаборыДанных.НаборДанных1.Запрос;

Вариант 2: Обход коллекции

Если наборов несколько или вы пишете универсальный механизм, лучше перебрать их в цикле:


Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
    Если ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
        ТекстЗапроса = НаборДанных.Запрос;
        // Здесь можно вывести текст в сообщение или записать в журнал
        Сообщить("Итоговый запрос для " + НаборДанных.Имя + ": " + ТекстЗапроса);
    КонецЕсли;
КонецЦикла;

Почему НаборыДанных могут быть пустыми?

Рассмотрим ситуацию, когда МакетКомпоновки.НаборыДанных.Количество() возвращает 0. Это часто сбивает разработчиков с толку. Основная причина — внутренняя оптимизация СКД. Если в выбранных настройках (вкладка «Выбранные поля») не указано ни одного поля из данного набора данных, и поля этого набора не задействованы в отборах, группировках или условном оформлении, СКД просто исключает этот набор из генерации макета. Система считает, что данные из этого источника не нужны для построения текущего отчета, и не тратит ресурсы на формирование запроса.

Чтобы гарантированно получить текст, убедитесь, что в объекте Настройки, который вы передаете в КомпоновщикМакета.Выполнить(), выбрано хотя бы одно поле из интересующего вас набора.

Работа с параметрами запроса

Получить только текст запроса недостаточно для его ручного выполнения. СКД генерирует собственные имена параметров, особенно для отборов. Эти параметры хранятся в коллекции МакетКомпоновки.ЗначенияПараметров. Разберем, как извлечь значения, чтобы подставить их в объект Запрос:


НовыйЗапрос = Новый Запрос(ТекстИтоговогоЗапроса);

// Переносим параметры из макета СКД в обычный запрос
Для Каждого ПараметрМакета Из МакетКомпоновки.ЗначенияПараметров Цикл
    НовыйЗапрос.УстановитьПараметр(ПараметрМакета.Имя, ПараметрМакета.Значение);
КонецЦикла;

Результат = НовыйЗапрос.Выполнить();

Важно помнить, что имена параметров в макете могут отличаться от тех, что вы задавали в СхемаКомпоновкиДанных. Например, если вы используете стандартный период, СКД может разложить его на &П1 и &П2 или добавить префиксы для уникальности.

Особенности отладки в современных конфигурациях (ЗУП 3.1, ERP 2.5)

Часто программисты сталкиваются с тем, что точка останова в процедуре ПриКомпоновкеРезультата не срабатывает. Это происходит из-за того, что в современных конфигурациях на управляемых формах отчеты по умолчанию формируются в фоновом задании на сервере.

Чтобы "поймать" этот момент отладчиком, выполните следующие действия:

  1. Проверьте, включена ли отладка на сервере (флаг -debug в параметрах запуска службы сервера 1С).
  2. В Конфигураторе зайдите в меню Отладка -> Подключение -> Автоматическое подключение и установите флаг Фоновые задания.
  3. Альтернативный способ: запустите сеанс "1С:Предприятие" с параметром РежимОтладки в строке запуска. Это заставит систему выполнять формирование отчета в основном потоке, минуя фоновые задания.

Сложные случаи: связи наборов данных

Проанализируем ситуацию, когда в схеме используется несколько наборов данных, связанных через вкладку "Связи наборов данных". В этом случае вы не найдете одного общего текста запроса. Система компоновки работает как "мини-СУБД": она выполнит запрос первого набора, получит результат, а затем будет итерационно выполнять запросы второго набора, подставляя данные из первого в качестве параметров. В МакетКомпоновки.НаборыДанных вы увидите отдельные фрагменты запросов, но логика их объединения скрыта глубоко в ПроцессореКомпоновкиДанных.

Практические советы по использованию

Таким образом, использование коллекции МакетКомпоновки.НаборыДанных является самым надежным и быстрым способом получить доступ к реальному SQL-коду, который формируется системой 1С:Предприятие "под капотом" механизма компоновки.

← На главную