При разработке отчетов на Системе компоновки данных (СКД) часто возникает задача разделения количественных показателей по определенному признаку, например, по полу. Несмотря на кажущуюся простоту, начинающие разработчики часто сталкиваются с тем, что отчет выводит либо пустые значения, либо некорректные итоги. В этой статье мы подробно разберем, как правильно реализовать подсчет мальчиков и девочек (или любых других категорий) в отчете, проанализируем типичные ошибки и приведем примеры правильного кода.
Рассмотрим ситуацию, когда разработчик пытается создать вычисляемое поле для разделения пола. Часто в выражении вычисляемого поля пишут конструкцию следующего вида:
ВЫБОР КОГДА ЗНАЧЕНИЕ(Перечисление.ПолФизическогоЛица.Мужской) ТОГДА 1 ИНАЧЕ 0 КОНЕЦ
Выясним причину, почему это не работает: логическая функция ВЫБОР ожидает условие, которое вернет результат "Истина" или "Ложь". В данном примере система видит просто литерал перечисления, который не является логическим выражением. СКД пытается преобразовать его к типу Булево, получает "Ложь" и всегда уходит в ветку ИНАЧЕ 0. В итоге во всех строках отчета по этому полю проставляются нули.
Чтобы выражение работало корректно, необходимо сравнивать поле из вашего набора данных со значением перечисления. Правильный вариант написания выражения в вычисляемом поле или ресурсе выглядит так:
ВЫБОР КОГДА Пол = ЗНАЧЕНИЕ(Перечисление.ПолФизическогоЛица.Мужской) ТОГДА 1 ИНАЧЕ 0 КОНЕЦ
Здесь Пол — это имя поля, которое вы выбрали в запросе (например, Анкета.ФизическоеЛицо.Пол).
После того как мы создали вычисляемые поля (например, ПолМ и ПолЖ), их нужно добавить на вкладку Ресурсы, чтобы СКД могла рассчитать итоги по группировкам. Здесь кроется вторая частая ошибка — выбор неправильной агрегатной функции.
Рассмотрим разницу:
Количество(ПолМ), система просто посчитает количество записей в этой колонке. Поскольку функция ВЫБОР у нас всегда возвращает либо 1, либо 0, то в каждой строке есть значение. Система посчитает и нули, и единицы, выдав в итоге общее количество строк, что будет неверно.Сумма(ПолМ). В этом случае система сложит все единицы и проигнорирует нули, что и даст нам искомое количество студентов конкретного пола.Проанализируем ситуацию, когда данные в отчет собираются из нескольких источников с помощью оператора ОБЪЕДИНИТЬ ВСЕ (UNION ALL). Это часто встречается в типовых отчетах, например, в конфигурации "1С:Колледж".
Если в одном из запросов объединения вы выбираете поле Пол, а в других на этом же месте стоит NULL, это приведет к "разваливанию" строк в отчете. СКД не сможет схлопнуть данные по специальности или группе в одну строку, так как значения в поле Пол будут разными (где-то заполнено, а где-то NULL).
Рекомендуемый алгоритм действий в запросе:
Пол (или ссылка на физическое лицо, из которого можно получить пол) присутствует во всех частях объединения.СГРУППИРОВАТЬ ПО, убедитесь, что поле Пол включено в список группировочных полей, иначе возникнет ошибка синтаксиса.Пример структуры запроса с подготовкой полей для подсчета пола:
ВЫБРАТЬ
Анкета.Специальность КАК Специальность,
Анкета.ФизическоеЛицо.Пол КАК Пол,
1 КАК КоличествоСтудентов
ИЗ
Документ.АнкетаАбитуриента КАК Анкета
Часто пользователи жалуются, что отчет выводит данные "лесенкой" или дублирует строки: в одной строке заполнено количество мальчиков, а в другой (для той же специальности) — количество девочек. Это происходит из-за того, что поле Пол добавлено в Группировки в настройках отчета.
Пошаговое решение проблемы визуального отображения:
Специальности).Пол.ПолМ и ПолЖ.Таким образом, СКД сгруппирует все записи по специальности, а внутри группы просуммирует наши единицы и нули, выдав итоговый результат в одной красивой строке.
Иногда один и тот же студент может попасть в выборку несколько раз (например, если он подал документы на несколько направлений). В этом случае обычное суммирование единиц даст завышенный результат. Чтобы этого избежать, воспользуемся более сложным выражением в ресурсах:
Количество(Различные ВЫБОР КОГДА Пол = ЗНАЧЕНИЕ(Перечисление.ПолФизическогоЛица.Мужской) ТОГДА Ссылка ИНАЧЕ NULL КОНЕЦ)
В данном примере система сначала отберет только те записи, где пол мужской, вернет их уникальные идентификаторы (Ссылка), а затем функция Количество(Различные ...) посчитает только уникальных людей. Это гарантирует максимальную точность отчета.
В некоторых конфигурациях поле Пол может быть не перечислением, а ссылкой на справочник. Перед написанием кода обязательно проверьте тип значения в Палитре свойств. Если это справочник, то обращение ЗНАЧЕНИЕ(Перечисление...) работать не будет, и вам придется сравнивать либо по коду, либо через предопределенные элементы справочника, если они созданы разработчиками.
Также не забывайте про функцию ЕСТЬNULL. Если данные приходят из левых соединений, вместо значения может прийти NULL, что сломает арифметические операции. Всегда оборачивайте числовые поля: ЕСТЬNULL(Поле, 0).