Как узнать текст итогового запроса СКД с учетом отборов и механизмов представлений в ЗУП

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

При работе с Системой компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда запрос, написанный в конструкторе схемы, существенно отличается от того, что реально выполняется платформой. Особенно остро эта проблема стоит в конфигурации 1С:Зарплата и управление персоналом 3.1, где активно используются так называемые «представления» и программная модификация текста запроса перед выводом. В этой статье мы подробно разберем, как «выловить» итоговый запрос, который учитывает все пользовательские настройки, отборы и программные манипуляции.

Понимаем разницу между Схемой и Макетом компоновки

Прежде всего, проанализируем важный теоретический момент. Основная ошибка новичков — попытка найти итоговый запрос в объекте СхемаКомпоновкиДанных. Однако схема — это лишь декларативное описание того, «что мы хотим получить». Итоговый же текст, который будет отправлен в СУБД, формируется только в объекте МакетКомпоновкиДанных.

Рассмотрим процесс трансформации данных в СКД:

  1. Схема компоновки: содержит исходный шаблон запроса.
  2. Настройки компоновки: содержат выбранные пользователем поля, отборы и параметры.
  3. Компоновщик макета: соединяет схему и настройки, генерируя итоговый макет.
  4. Макет компоновки: содержит готовый текст запроса (или нескольких запросов для временных таблиц), оптимизированный под конкретные условия.

Метод 1. Программный перехват в процедуре ПриКомпоновкеРезультата

Если нам нужно увидеть запрос в контексте работающего отчета, наиболее эффективным способом будет использование точки останова в модуле объекта отчета. Разберем по шагам, как это сделать.

Найдем в модуле объекта отчета процедуру ПриКомпоновкеРезультата. В конфигурациях на базе БСП (включая ЗУП) именно здесь происходит основная «магия». Проанализируем типичный фрагмент кода:


Процедура ПриКомпоновкеРезультата(РезультатОформления, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Здесь вызываются общие модули, которые могут подменять схему
    ЗарплатаКадрыОтчеты.ПриКомпоновкеРезультата(ЭтотОбъект, РезультатОформления, ДанныеРасшифровки, СтандартнаяОбработка);
    
    // Чтобы увидеть итоговый запрос, нам нужно вручную скомпоновать макет
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
    
    // В переменной МакетКомпоновки теперь содержится итоговый запрос
    Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
        Если ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
            ТекстИтоговогоЗапроса = НаборДанных.Запрос; // Вот он!
        КонецЕсли;
    КонецЦикла;

КонецПроцедуры

Важный нюанс: Ставьте точку останова ПОСЛЕ вызова общих модулей модификации (например, после ЗарплатаКадрыОтчеты.ПриКомпоновкеРезультата). Именно в этот момент «пустые» запросы-заглушки ЗУПа превращаются в реальный код, работающий с виртуальными таблицами представлений.

Метод 2. Использование специализированных консолей СКД

Стандартные консоли запросов часто не справляются с отчетами ЗУП, так как не умеют инициализировать специфические параметры или программные обработчики. Рассмотрим использование продвинутых инструментов, таких как «Инструменты разработчика» (автор Tormozit).

Эти инструменты позволяют «подключиться» к уже открытому в пользовательском сеансе отчету. Выясним, почему это удобно:

Если вы используете стороннюю консоль, ищите кнопку «Получить макет компоновки» или «Показать итоговый запрос». Если консоль выдает ошибку в ЗУП, скорее всего, она пытается инициализировать схему в отрыве от программного контекста (общих модулей), который заполняет параметры периодов или описания представлений.

Метод 3. Анализ механизмов представлений в ЗУП 3.1

В ЗУП 3.1 текст запроса в СКД часто выглядит крайне лаконично, например: ВЫБРАТЬ * ИЗ Представления_ФИОФизическихЛиц. Это не настоящая таблица, а маркер для программной подстановки.

Разберем, как это работает: СКД при генерации макета вызывает обработчик, который заменяет этот маркер на огромный вложенный запрос с соединениями к регистрам сведений. Чтобы увидеть результат этой замены, недостаточно просто посмотреть СхемаКомпоновкиДанных.НаборыДанных. Нужно обязательно выполнить метод Выполнить() объекта КомпоновщикМакетаКомпоновкиДанных, как было показано в первом методе. Только в Макете маркеры представлений превратятся в реальный SQL-подобный код.

Метод 4. Отладка на уровне СУБД (SQL Profiler и Технологический журнал)

Иногда возникают ситуации, когда запрос в 1С выглядит правильно, но выполняется медленно или возвращает странные результаты из-за особенностей оптимизатора СУБД. Проанализируем, как увидеть «чистый» SQL.

Технологический журнал (ТЖ): Настройте сбор события DBMSSQL (для MS SQL Server) или DBPOSTGRS (для PostgreSQL). Фильтрация по текущему сеансу позволит вам увидеть текст запроса в том виде, в котором его получила база данных. Это крайний, но самый точный метод контроля.

Почему запрос работает «странно» после добавления отборов?

Выясним причину частого вопроса: «Запрос правильный, но при добавлении отбора данные исчезают». Это связано с тем, как СКД модифицирует соединения (JOIN). Рассмотрим ситуацию:

Чтобы избежать этого, проверьте настройки Ролей полей в СКД. Использование флага Обязательное или правильная настройка условий в секции ГДЕ (с учетом возможных NULL) поможет сохранить ожидаемую структуру запроса при любых пользовательских отборах.

Используя предложенные методы программной отладки и специализированные инструменты, вы всегда сможете точно определить, какой именно запрос выполняет ваша система, и оперативно исправить ошибки в логике компоновки данных.

← На главную