Как просуммировать детальные записи в СКД при избыточной детализации

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

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

Постановка проблемы и анализ ситуации

Проанализируем ситуацию на примере практического кейса. Представим отчет, который должен выводить данные по продажам в разрезе следующих группировок: Филиал, Канал, Номенклатура и Характеристика. Однако в самом запросе схемы компоновки данных присутствует поле Склад. Из-за наличия этого поля в выборке детальные записи начинают дробиться по складам. В итоге, когда мы пытаемся вывести общую сумму по номенклатуре или филиалу, СКД начинает складывать показатели по каждой складской позиции, что приводит к искажению итогов.

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

---

Решение 1. Использование функции ВычислитьВыражениеСГруппировкойМассив

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

Разберем по шагам, как настроить расчет ресурса:

  1. Перейдите на вкладку «Ресурсы» в схеме компоновки данных.
  2. Добавьте ваше числовое поле (например, СуммаОборот) в список ресурсов.
  3. В колонке «Выражение» напишите следующую формулу:

Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СуммаОборот)", "Номенклатура, Характеристика"))

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

---

Решение 2. Разделение запросов через связи наборов данных

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

Для объединения этих данных перейдем на вкладку «Связи наборов данных». Укажем в качестве источника связи НаборДанных2, а в качестве приемника — НаборДанных1. Свяжем их по ключевым полям:

  1. Филиал
  2. Канал
  3. Номенклатура

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

---

Решение 3. Тонкая настройка расчета ресурсов по группировкам

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

Рассмотрим, как ограничить расчет ресурса конкретными уровнями:

  1. На вкладке «Ресурсы» выберите нужное поле.
  2. В колонке «Рассчитывать по...» по умолчанию стоит пустое значение (что означает «рассчитывать везде»).
  3. Кликните на эту ячейку и выберите только те группировки, на которых расчет этой суммы имеет смысл (например, укажите только Филиал, Канал и Номенклатура).
  4. Для детальных записей или группировки по складу оставьте расчет отключенным либо задайте выражение равным 0.

Этот способ незаменим, когда на нижнем уровне (детальные записи) сумма не имеет физического смысла, но на уровне группировок нам необходимо показать корректный консолидированный итог.

---

Решение 4. Анализ ролей полей и флага «Обязательное»

Часто проблема избыточного дублирования и разбиения детальных записей кроется в настройках ролей полей схемы компоновки данных. Если поле Склад выбрано из виртуальной таблицы (например, остатков или оборотов), СКД по умолчанию может назначить ему роль с включенным свойством «Обязательное».

Проанализируем ситуацию: если у поля стоит флаг «Обязательное», СКД будет принудительно добавлять это поле во все генерируемые SQL-запросы к базе данных, даже если пользователь отключил отображение склада в настройках отчета. Из-за этого детальные строки не могут «схлопнуться», и суммы продолжают двоиться.

Решить это можно следующим образом:

  1. Перейдите на вкладку «Наборы данных».
  2. Найдите поле Склад в таблице полей.
  3. Кликните по ячейке в колонке «Роль».
  4. В открывшемся окне свойств роли снимите флаг «Обязательное».

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

---

Решение 5. Использование уникальных идентификаторов строк

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

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

Наличие такого уникального поля в детальных записях гарантирует, что СКД распознает каждую строку как отдельную сущность, выведет их обособленно и при этом корректно подведет итоги на уровнях родительских группировок.

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

← На главную