Как в запросе 1С добавить группировку по складу и рассчитать итог как максимальное значение?

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

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

Анализ исходной задачи

Разберем ситуацию на примере. Допустим, у нас есть данные по движениям товаров:

Если мы просто сгруппируем данные по складу и номенклатуре с функцией СУММА, то получим: Валенки — 300, Сапоги — 150. Но нашей целью является вывод итога по Складу 1 не как 450 (300 + 150), а как 300 (максимальное значение среди итогов по товарам).

Способ 1. Использование вложенных запросов и временных таблиц

Поскольку язык запросов 1С не позволяет напрямую использовать конструкцию вида МАКСИМУМ(СУММА(Количество)), нам необходимо разделить расчет на два этапа. Сначала мы просуммируем данные по номенклатуре, а затем выберем максимальное значение из этих сумм.

Проанализируем шаги реализации:

  1. Создаем временную таблицу, в которой группируем данные по Склад и Номенклатура, вычисляя сумму прихода и расхода.
  2. В основном запросе обращаемся к этой временной таблице и используем функцию МАКСИМУМ для получения итогов по складу.

Пример программного кода запроса:


ВЫБРАТЬ
    ТоварыОрганизаций.Склад КАК Склад,
    ТоварыОрганизаций.Номенклатура КАК Номенклатура,
    СУММА(ВЫБОР
            КОГДА ТоварыОрганизаций.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
                ТОГДА ТоварыОрганизаций.Количество
            ИНАЧЕ 0
        КОНЕЦ) КАК ПриходСумма
ПОМЕСТИТЬ ВТ_ИтогиПоНоменклатуре
ИЗ
    РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизаций
ГДЕ
    ТоварыОрганизаций.Период МЕЖДУ &ДатаНачала И &ДатаКонца
    И ТоварыОрганизаций.Активность
СГРУППИРОВАТЬ ПО
    ТоварыОрганизаций.Склад,
    ТоварыОрганизаций.Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_ИтогиПоНоменклатуре.Склад КАК Склад,
    МАКСИМУМ(ВТ_ИтогиПоНоменклатуре.ПриходСумма) КАК МаксимальныйПриход
ИЗ
    ВТ_ИтогиПоНоменклатуре КАК ВТ_ИтогиПоНоменклатуре
СГРУППИРОВАТЬ ПО
    ВТ_ИтогиПоНоменклатуре.Склад

Способ 2. Реализация через систему компоновки данных (СКД)

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

Посмотрим на алгоритм настройки вкладки Ресурсы:

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

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

Способ 3. Использование предложения ИТОГИ в языке запросов

Если отчет формируется программно без использования СКД, можно воспользоваться предложением ИТОГИ. Этот механизм позволяет задать разные агрегатные функции для разных уровней иерархии результата запроса.

Рассмотрим пример синтаксиса:


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

Важно: При использовании ИТОГИ результат запроса нужно обходить с помощью метода Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам). Помните, что такой запрос нельзя использовать в качестве источника данных для динамического списка.

Особенности производительности

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

← На главную