Как исправить неверные итоги по функции Количество(Различные) в СКД 1С?

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

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

Рассмотрим пример: в отчете выводятся пациенты медицинской клиники и оказанные им услуги. Бизнес-задача — получить общее количество уникальных пациентов, посетивших клинику в заданном периоде. Если просто добавить ресурс с методом подсчета КоличествоРазличные, результат в общих итогах может оказаться совершенно непредсказуемым. Выясним причину этой ошибки и разберем по шагам правильные архитектурные решения.

Почему возникает ошибка при применении функции к числовому полю

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

Если мы применим эту функцию к числовому ресурсу, например, к полю КоличествоУслуг, СКД будет искать уникальные цифры. Посмотрим на пример: предположим, у нас есть три строки заказа в отчете, где количество оказанных услуг равно 5, 5 и 10. В этом случае СКД вернет в итогах результат «2», так как уникальных цифр во всем массиве строк всего две (пятерка и десятка). Это в корне искажает бизнес-смысл отчета.

Чтобы система считала уникальные объекты (идентификаторы), а не совпавшие числовые показатели, метод должен применяться исключительно к ссылочным полям. Разберем по шагам правильную настройку: вместо числового поля используем ссылки на справочники или документы. Правильное выражение на вкладке ресурсов будет выглядеть так:

  1. Для подсчета пациентов: Количество(Различные Пациент)
  2. Для подсчета документов: Количество(Различные Заказ)

Где правильнее считать: в Запросе или в Ресурсах СКД?

Рассмотрим архитектурно правильный подход к разработке на платформе 1С. Частая ошибка начинающих разработчиков — пытаться подсчитать уникальные значения напрямую в тексте SQL-запроса, используя оператор РАЗЛИЧНЫЕ или группируя данные там, а затем просто выводить готовое число в СКД.

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

Чтобы избежать этой проблемы, вытягиваем в набор данных запроса саму ссылку (например, поле Пациент), а агрегатную функцию настраиваем исключительно на вкладке «Ресурсы» в схеме компоновки данных. При таком подходе платформа самостоятельно и математически верно пересчитает уникальные значения для каждого уровня иерархии индивидуально.

Дублирование строк при связях «один ко многим»

Разберем по шагам проблему, которая часто возникает при соединении таблиц в запросе СКД. Например, при левом соединении шапки документа Заказ с его табличной частью Услуги. В результате такого соединения один заказ размножается на столько строк, сколько номенклатурных позиций (услуг) в нем содержится.

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

Подводные камни с пустыми ссылками и значениями NULL

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

Важно помнить архитектурную особенность: агрегатные функции в СКД игнорируют значения NULL. Посмотрим на пример того, как пустые ссылки преобразовать в NULL на лету, чтобы они не искажали итоги. В поле выражения на вкладке «Ресурсы» необходимо написать следующую конструкцию:


Количество(Различные Выбор 
    Когда Пациент = Значение(Справочник.Пациенты.ПустаяСсылка) Тогда NULL 
    Иначе Пациент 
Конец)

Рассмотрим подробнее эту формулу: встроенная функция Выбор проверяет поле на равенство пустой ссылке справочника. Если условие выполняется, возвращается значение NULL, которое движок компоновки полностью игнорирует при подсчете количества. Таким образом, в итоги попадут только реально существующие элементы.

Продвинутые вычисления с помощью массивов в СКД

Проанализируем ситуацию, когда бизнес-логика отчета требует нетипового и сложного расчета. Например, нам нужно подсчитать уникальных пациентов только по определенным видам заказов внутри общих итогов группировки. В таких случаях стандартной функции в ресурсах может оказаться недостаточно.

В СКД можно использовать мощные встроенные функции работы с массивами. Разберем сложный расчет с помощью функции ВычислитьВыражениеСГруппировкойМассив. Посмотрим на пример кода, который необходимо вставить в выражение ресурса:

Количество(Различные ВычислитьВыражениеСГруппировкойМассив("Пациент", "Заказ"))

Разберем по шагам, как работает это выражение. Данная формула указывает процессору компоновки данных сначала собрать массив всех ссылок на пациентов в разрезе каждого отдельного заказа на текущем уровне группировки. Только после того как массив сформирован, внешняя функция Количество(Различные ...) вычисляет количество уникальных элементов в уже собранном массиве. Это чрезвычайно гибкий инструмент для построения сложных аналитических дашбордов и отчетов, где требуется собирать итоги по непересекающимся множествам данных.

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

← На главную