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