Как правильно просуммировать поля в запросе 1С и настроить группировку данных

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

Работа с запросами в системе 1С:Предприятие 8 — это базовый навык разработчика, однако задачи агрегации данных часто вызывают вопросы у начинающих специалистов. Одной из типичных ситуаций является необходимость получить «схлопнутую» таблицу с итогами, не используя при этом иерархическую структуру, которую предоставляет предложение ИТОГИ ПО. Разберем детально, как правильно суммировать поля, группировать данные и избегать распространенных ошибок компиляции запроса.

Понимание разницы между СГРУППИРОВАТЬ ПО и ИТОГИ ПО

Прежде чем переходить к практике, проанализируем, почему стандартные «Итоги» не всегда подходят для решения задачи. Предложение ИТОГИ ПО в языке запросов 1С предназначено для формирования иерархического результата. Это полезно для отчетов, где нужно видеть детальные записи и «шапки» с суммами над ними. Однако, если наша цель — получить плоскую таблицу, где каждая строка представляет собой уникальную комбинацию измерений с их общими суммами, нам необходимо использовать секцию СГРУППИРОВАТЬ ПО.

Рассмотрим ситуацию: если мы оставим ИТОГИ ПО, система вернет дерево значений. Если же мы применим СГРУППИРОВАТЬ ПО, мы получим компактный результат без лишних уровней вложенности. Это критически важно для дальнейшей обработки данных в коде или выгрузки в таблицу значений.

Золотое правило группировки данных

Основная сложность, с которой сталкиваются разработчики, заключается в синтаксисе секции ВЫБРАТЬ при включенной группировке. Давайте запомним фундаментальное правило: каждое поле, которое мы указываем в списке выбора, должно находиться в одном из двух состояний:

  1. Оно перечислено в секции СГРУППИРОВАТЬ ПО (является «измерением» группировки).
  2. Оно обернуто в агрегатную функцию (СУММА, МАКСИМУМ, МИНИМУМ, КОЛИЧЕСТВО или СРЕДНЕЕ).

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


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

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

Разбор ошибки «Операция не разрешена в предложении СГРУППИРОВАТЬ»

Проанализируем типичную ошибку, когда разработчик пытается написать СГРУППИРОВАТЬ ПО СУММА(Поле1). Это логическая ловушка. Мы группируем ПО значениям полей, а не ПО результатам функций. В секции СГРУППИРОВАТЬ ПО должны указываться только имена полей или выражения без агрегатных функций. Функции суммирования живут исключительно в секции ВЫБРАТЬ.

Если вы используете Конструктор запроса, порядок действий должен быть следующим:

  1. Перейдите на вкладку «Группировка».
  2. В левом списке вы увидите все поля, выбранные в запросе.
  3. Перенесите поля-измерения (по которым нужно группировать, например, Номенклатура, Склад) в правое верхнее окно.
  4. Поля-ресурсы (которые нужно суммировать, например, Количество, Сумма) перенесите в правое нижнее окно «Суммируемые поля». Конструктор сам подставит функцию СУММА в текст запроса.

Почему получается «1 в каждой строке» вместо общей суммы?

Это одна из самых коварных проблем. Вы вроде бы настроили СУММА, но в результате видите много строк, и в каждой сумма равна единице или значению одной конкретной проводки. Выясним причину этого поведения. Группировка работает по уникальному набору всех полей, перечисленных в СГРУППИРОВАТЬ ПО.

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

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

Использование МАКСИМУМ для нечисловых данных

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

Например, мы группируем продажи по Номенклатуре, но хотим видеть ЕдиницуИзмерения. Если мы добавим ЕдиницуИзмерения в группировку, и у одной номенклатуры вдруг окажутся разные единицы в разных записях, строки разделятся. Если же мы напишем МАКСИМУМ(ЕдиницаИзмерения), запрос останется стабильным и вернет одну строку.


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

Работа с NULL и пустыми значениями

При суммировании данных из разных таблиц (через ЛЕВОЕ СОЕДИНЕНИЕ) часто возникают значения NULL. Помните, что СУММА(NULL) не вызывает ошибку, но математические операции внутри функции могут привести к неожиданным результатам. Рекомендуем использовать функцию ЕСТЬNULL внутри агрегатов, если вы производите расчеты между полями:


ВЫБРАТЬ
    СУММА(ЕСТЬNULL(Таблица.Поле1, 0) + ЕСТЬNULL(Таблица.Поле2, 0)) КАК ОбщийИтог
...

Подведем итог нашему анализу. Чтобы успешно просуммировать поля в запросе 1С, нужно четко разделять поля на те, по которым мы группируем, и те, которые мы агрегируем. Убирайте все лишние разрезы (поля), если они дробят результат, и всегда проверяйте секцию СГРУППИРОВАТЬ ПО на наличие ошибочно вставленных функций.

← На главную