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