При построении отчетов в 1С часто возникает задача, когда стандартное суммирование итогов не подходит. Например, нам нужно получить сумму оборотов по каждой номенклатуре внутри склада, но на уровне самого склада мы хотим видеть не общую сумму всех товаров, а только максимальное значение из полученных итогов по номенклатуре. Рассмотрим подробнее, какими способами можно решить эту задачу, начиная от простого изменения запроса и заканчивая использованием системы компоновки данных (СКД).
Разберем ситуацию на примере. Допустим, у нас есть данные по движениям товаров:
Если мы просто сгруппируем данные по складу и номенклатуре с функцией СУММА, то получим: Валенки — 300, Сапоги — 150. Но нашей целью является вывод итога по Складу 1 не как 450 (300 + 150), а как 300 (максимальное значение среди итогов по товарам).
Поскольку язык запросов 1С не позволяет напрямую использовать конструкцию вида МАКСИМУМ(СУММА(Количество)), нам необходимо разделить расчет на два этапа. Сначала мы просуммируем данные по номенклатуре, а затем выберем максимальное значение из этих сумм.
Проанализируем шаги реализации:
Склад и Номенклатура, вычисляя сумму прихода и расхода.МАКСИМУМ для получения итогов по складу.Пример программного кода запроса:
ВЫБРАТЬ
ТоварыОрганизаций.Склад КАК Склад,
ТоварыОрганизаций.Номенклатура КАК Номенклатура,
СУММА(ВЫБОР
КОГДА ТоварыОрганизаций.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
ТОГДА ТоварыОрганизаций.Количество
ИНАЧЕ 0
КОНЕЦ) КАК ПриходСумма
ПОМЕСТИТЬ ВТ_ИтогиПоНоменклатуре
ИЗ
РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизаций
ГДЕ
ТоварыОрганизаций.Период МЕЖДУ &ДатаНачала И &ДатаКонца
И ТоварыОрганизаций.Активность
СГРУППИРОВАТЬ ПО
ТоварыОрганизаций.Склад,
ТоварыОрганизаций.Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_ИтогиПоНоменклатуре.Склад КАК Склад,
МАКСИМУМ(ВТ_ИтогиПоНоменклатуре.ПриходСумма) КАК МаксимальныйПриход
ИЗ
ВТ_ИтогиПоНоменклатуре КАК ВТ_ИтогиПоНоменклатуре
СГРУППИРОВАТЬ ПО
ВТ_ИтогиПоНоменклатуре.Склад
Если вы разрабатываете отчет на СКД, это самый гибкий и правильный метод. В СКД можно настроить расчет ресурсов так, чтобы на разных уровнях группировки применялись разные формулы. Выясним, как это сделать в конфигураторе.
Посмотрим на алгоритм настройки вкладки Ресурсы:
Приход в список ресурсов.Сумма(Приход).Максимум(ВычислитьВыражениеСГруппировкойМассив("Сумма(Приход)", "Номенклатура")).Склад.Этот метод позволяет платформе сначала вычислить суммы по всей номенклатуре, собрать их в массив и затем найти среди них максимальное число специально для строки склада.
Если отчет формируется программно без использования СКД, можно воспользоваться предложением ИТОГИ. Этот механизм позволяет задать разные агрегатные функции для разных уровней иерархии результата запроса.
Рассмотрим пример синтаксиса:
ВЫБРАТЬ
ТоварыОрганизаций.Склад КАК Склад,
ТоварыОрганизаций.Номенклатура КАК Номенклатура,
ТоварыОрганизаций.Количество КАК Количество
ИЗ
РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизаций
ИТОГИ
СУММА(Количество) ПО Номенклатура,
МАКСИМУМ(Количество) ПО Склад
Важно: При использовании ИТОГИ результат запроса нужно обходить с помощью метода Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам). Помните, что такой запрос нельзя использовать в качестве источника данных для динамического списка.
При работе с большими объемами данных в регистре ТоварыОрганизаций следует учитывать, что использование соединений (особенно левых соединений для поиска максимума) может замедлить работу отчета. Использование временных таблиц с индексацией по полю Склад обычно работает быстрее и стабильнее. Если задача позволяет, всегда отдавайте предпочтение СКД, так как ее механизмы оптимизированы для построения сложных иерархических отчетов с нетиповыми итогами.