Почему в запросах СКД появляется условие ИМЕЮЩИЕ КОЛИЧЕСТВО и как это исправить

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

При работе с Системой компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда итоговый запрос, генерируемый системой, существенно отличается от того, что был написан в схеме компоновки. Одной из самых загадочных метаморфоз является внезапное появление секции ИМЕЮЩИЕ (HAVING) с агрегатными функциями вроде КОЛИЧЕСТВО(...) и странными параметрами типа &П5. Рассмотрим подробно, почему это происходит и как найти "виновника" в настройках отчета.

Механизм трансформации запроса в Компоновщике макета

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


КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(),,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

В этот момент СКД не просто подставляет параметры в ваш текст запроса. Она перестраивает его структуру, основываясь на ролях полей и настройках отбора. Если система видит, что отбор накладывается на поле, которое определено как ресурс или имеет определенную роль в наборе данных, она может принять решение перенести условие из секции ГДЕ в секцию ИМЕЮЩИЕ. Это делается для того, чтобы отфильтровать уже сгруппированные данные, а не исходные записи.

Откуда берутся параметры П1, П2, П5

Параметры с именами &П1, &П2, &П5 и так далее называются системными генерируемыми параметрами. Разберем причины их появления:

Роль полей и автоматическая агрегация

Одной из ключевых причин появления КОЛИЧЕСТВО(История.Период) = &П5 является настройка ролей на закладке "Наборы данных". Выясним, как это работает. Если поле, по которому установлен отбор, помечено в СКД как рассчитываемое через агрегатную функцию, или если оно логически связано с количеством записей в подчиненной таблице, система заменяет прямое обращение к полю на функцию КОЛИЧЕСТВО по ключевому полю (в нашем случае — по полю Период таблицы История).

Особенно часто это проявляется при использовании отборов вида "Равно 0" для числовых показателей. Для СКД условие "значение равно нулю" часто интерпретируется как "отсутствие записей в этой группе", что логически эквивалентно КОЛИЧЕСТВО(...) = 0 в секции ИМЕЮЩИЕ.

Пошаговый алгоритм диагностики проблемы

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

  1. Анализ всех активных отборов: Откройте настройки отчета и посмотрите список примененных фильтров. Обратите внимание на те, которые наложены на числовые поля, ресурсы или поля, которые не входят в текущую группировку.
  2. Метод исключения: Попробуйте поочередно отключать (снимать галочку использования) каждый реквизит в отборе. После каждого отключения проверяйте итоговый текст запроса в отладчике через МакетКомпоновки.НаборыДанных[0].Запрос.
  3. Проверка ролей полей: Перейдите в Схему компоновки данных на закладку "Набор данных". Проверьте колонку "Роль". Если у поля стоит роль "Измерение" или заполнено "Выражение" для агрегации, это прямой кандидат на попадание в HAVING.
  4. Использование консоли СКД: Это самый эффективный способ. Загрузите вашу схему и настройки в консоль системы компоновки данных. Там можно увидеть не только итоговый запрос, но и детальную информацию о том, как распределились роли полей и какие временные таблицы были созданы.

Пример исправления

Рассмотрим конкретный пример. Предположим, у нас есть поле КоличествоПоложительныхРезультатов. В настройках установлен отбор:

КоличествоПоложительныхРезультатов Равно 0

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

ИМЕЮЩИЕ КОЛИЧЕСТВО(История.Период) = &П5

Где в параметр &П5 передается значение 0.

Решение: Чтобы убрать это поведение, можно либо пересмотреть логику получения этого поля (сделать его физическим полем в запросе, а не ресурсом СКД), либо изменить условие отбора на более простое, если это допустимо бизнес-логикой. В некоторых случаях помогает явное указание роли "Обязательное" для поля или отключение автозаполнения полей в наборе данных с последующей ручной настройкой.

Резюме

Появление "магических" строк кода в СКД — это результат работы встроенного оптимизатора и генератора запросов. Не стоит пугаться параметров типа &П5. Теперь мы знаем, что это лишь способ системы обеспечить целостность данных при сложных группировках и отборах по агрегатным величинам. Помните, что поиск причины всегда стоит начинать с анализа настроек отбора и ролей полей в наборе данных.

← На главную