Как исправить ошибку «Использование вложенных агрегатных функций не допустимо» и рассчитать итоги в СКД?

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

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

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

Причины возникновения ошибки и некорректного поведения итогов

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

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

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

Рассмотрим проверенные способы решения этой задачи, начиная от базовой доработки запроса и заканчивая возможностями выражений СКД.

Способ 1. Перенос предварительной группировки в запрос

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

  1. Выделим расчет количества уникальных записей в отдельный подзапрос или временную таблицу, сгруппировав данные по требуемым аналитическим разрезам.
  2. В тексте запроса применим конструкцию КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...). Поле перестанет быть агрегатом на уровне СКД и станет простым числовым полем набора данных.
  3. На вкладке Ресурсы схемы компоновки данных добавим полученное поле и укажем для него стандартное выражение Сумма(ИмяПоля).

Посмотрим на пример структуры запроса:


ВЫБРАТЬ
    Начисления.Подразделение КАК Подразделение,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Начисления.Сотрудник) КАК КоличествоСотрудников
ПОМЕСТИТЬ ВТ_КоличествоПоПодразделениям
ИЗ
    РегистрНакопления.ВзаиморасчетыСРаботниками КАК Начисления
СГРУППИРОВАТЬ ПО
    Начисления.Подразделение
;

ВЫБРАТЬ
    ВТ.Подразделение КАК Подразделение,
    ВТ.КоличествоСотрудников КАК КоличествоСотрудников,
    ВТ.КоличествоСотрудников * &НормаВыработкиНаЧеловека КАК НормаВыработки
ИЗ
    ВТ_КоличествоПоПодразделениям КАК ВТ

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

Способ 2. Использование функции «ВычислитьВыражениеСГруппировкойМассив»

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


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

Рассмотрим подробнее принцип работы этой функции:

  1. Внутренняя функция ВычислитьВыражениеСГруппировкойМассив обходит все записи указанной группировки (второй параметр) и вычисляет для каждой из них выражение из первого параметра.
  2. Результатом работы функции становится массив чисел, каждое из которых представляет собой расчет по конкретной строке группировки.
  3. Внешняя функция Сумма последовательно складывает полученные элементы массива, формируя правильный арифметический итог для вышестоящей группировки или общего итога.

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

Способ 3. Разделение формул расчета по группировкам на вкладке «Ресурсы»

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

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

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

← На главную