Как в СКД построить диаграмму «Топ-5 плюс все остальные»?

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

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

Решение 1: Использование временных таблиц и объединения запросов

Разберем классический и надежный способ реализации на уровне набора данных-запроса. Для этого нам необходимо выделить первые N записей во временную таблицу, а затем объединить их с остатком исходной таблицы, сгруппированным в одну строку.

Посмотрим на алгоритм реализации запроса по шагам:

  1. Выбираем первые 5 записей, отсортированных по убыванию показателя, и помещаем их во временную таблицу топ5. Важно помнить, что предложение УПОРЯДОЧИТЬ ПО корректно работает во временных таблицах платформы 1С:Предприятие именно в связке с конструкцией ПЕРВЫЕ N.
  2. В основном запросе выбираем строки из созданной временной таблицы топ5.
  3. С помощью оператора ОБЪЕДИНИТЬ ВСЕ добавляем строку с фиксированным наименованием "Прочие" (или "Все остальные"), рассчитав сумму по тем элементам исходной таблицы, которые не попали во временную таблицу (по левому соединению значение ключа из топ5 будет равно NULL).

Рассмотрим пример готового текста запроса для набора данных:


ВЫБРАТЬ ПЕРВЫЕ 5
    ВсеЧисла.Элемент КАК Элемент,
    ВсеЧисла.Количество КАК Количество
ПОМЕСТИТЬ топ5
ИЗ
    ВсеЧисла КАК ВсеЧисла
УПОРЯДОЧИТЬ ПО
    ВсеЧисла.Количество УБЫВ
;

ВЫБРАТЬ
    топ5.Элемент КАК Элемент,
    топ5.Количество КАК Количество
ИЗ
    топ5 КАК топ5

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    "Прочие",
    СУММА(Остальные.Количество)
ИЗ
    ВсеЧисла КАК Остальные
    ЛЕВОЕ СОЕДИНЕНИЕ топ5 КАК топ5
        ПО Остальные.Элемент = топ5.Элемент
ГДЕ
    топ5.Количество ЕСТЬ NULL
СГРУППИРОВАТЬ ПО
    "Прочие"

Решение 2: Вычисляемые поля и функции СКД

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

  1. В набор данных передаем полный список записей с сортировкой по убыванию ресурса.
  2. На вкладке «Вычисляемые поля» схемы компоновки добавляем новое поле ГруппаДляДиаграммы.
  3. В выражении поля задаем условие с проверкой порядкового номера строки:
    
    ВЫБОР 
        КОГДА НомерПоПорядку() <= 5 ТОГДА Элемент 
        ИНАЧЕ "Прочие" 
    КОНЕЦ
    
  4. В настройках структуры диаграммы СКД используем поле ГруппаДляДиаграммы в качестве точек диаграммы, а числовое поле выводим в ресурсы со стандартным агрегированием Сумма(Количество).

Почему результаты СКД могут отличаться от консоли запросов?

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

  1. Неправильная агрегатная функция на вкладке «Ресурсы»: если для ресурса по ошибке указано выражение Количество(Количество) вместо Сумма(Количество), СКД подсчитает количество строк в группировке, а не их сумму.
  2. Автозаполнение СКД: механизм автозаполнения может автоматически перестраивать текст запроса, исключая неиспользуемые поля или изменяя группировки при наложении пользовательских отборов.
  3. Ограничение «Количество записей» в настройках: параметр Количество записей на вкладке «Другие настройки» просто обрезает вывод после указанного числа строк и не производит суммирование отсеченных данных.

Как просмотреть реальный запрос СКД для отладки?

Чтобы выяснить причину расхождения данных и увидеть скомпонованный SQL-запрос, который платформа отправляет в СУБД, используем макет компоновки данных:


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

Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
    Если ТипЗнч(НаборДанных) = Тип("МакетКомпоновкиДанныхНаборДанныхЗапрос") Тогда
        ТекстРеальногоЗапроса = НаборДанных.Запрос;
    КонецЕсли;
КонецЦикла;

Также для детального анализа промежуточных таблиц и результирующего текста запроса удобно применять внешнюю обработку «Консоль системы компоновки данных».

← На главную