К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как просуммировать поля в запросе 1С

Как просуммировать поля в запросе 1С: функция СУММА, ГРУППИРОВКА ПО, ИТОГИ, суммирование в СКД и в коде. Примеры, типичные ошибки и проверка результата.

Суммирование полей — одна из самых частых операций при работе с запросами в 1С. Она встречается в отчётах по продажам, расчёте остатков на складе, сводках по зарплате и в любых агрегированных выборках. Платформа 1С предлагает несколько способов получить сумму: агрегатная функция СУММА в тексте запроса, предложение ИТОГИ, группировки в СКД и программное суммирование при обходе результата.

Выбор способа зависит от задачи. Если нужна одна итоговая цифра по всей выборке — достаточно функции СУММА без группировки. Если суммы нужны в разрезе контрагентов, складов или периодов — добавляется ГРУППИРОВКА ПО или ИТОГИ ПО. Если данные дальше идут в отчёт на СКД, суммирование лучше поручить самой компоновке, а не тексту запроса.

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

Сумма одного поля по всей выборке: функция СУММА

Самый простой случай — получить одну сумму по всей таблице или по отфильтрованному набору строк. Для этого в списке полей выборки указывается агрегатная функция СУММА с именем числового поля в скобках. Пример для табличной части документа реализации:

ВЫБРАТЬ

СУММА(РеализацияТовары.Сумма) КАК СуммаВсего

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары

ГДЕ

РеализацияТовары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода

Здесь запрос вернёт одну строку с одной колонкой СуммаВсего. Псевдоним через КАК важен: без него обращаться к полю результата придётся по сгенерированному имени, что неудобно и небезопасно при доработках.

Если в выборке, кроме СУММА, есть обычные поля (например, Организация или Склад), запрос не выполнится с ошибкой «Поле не входит в группу». Платформа требует: либо все поля агрегатные, либо неагрегатные поля явно перечислены в ГРУППИРОВКА ПО. Это частая причина ошибок у начинающих разработчиков.

Суммы по группам: ГРУППИРОВКА ПО

Когда суммы нужны в разрезе аналитики — по контрагентам, номенклатуре, складам — используется предложение ГРУППИРОВКА ПО. В нём перечисляются все неагрегатные поля выборки:

ВЫБРАТЬ

Продажи.Контрагент КАК Контрагент,

СУММА(Продажи.СуммаОборот) КАК СуммаПродаж

ИЗ

РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ) КАК Продажи

СГРУППИРОВАТЬ ПО

Продажи.Контрагент

Группировать можно по нескольким полям — тогда сумма считается по каждой уникальной комбинации. Например, ГРУППИРОВКА ПО Контрагент, Склад даст сумму продаж каждого контрагента по каждому складу отдельно.

Полезное дополнение — предложение ИМЕЮЩИЕ, аналог HAVING в SQL. Оно фильтрует уже сгруппированные строки по значению агрегата: например, оставить только контрагентов с суммой продаж больше заданной. Обычный ГДЕ здесь не сработает, потому что он применяется до группировки.

СГРУППИРОВАТЬ ПО

Продажи.Контрагент

ИМЕЮЩИЕ

СУММА(Продажи.СуммаОборот) > &МинСумма

Иерархические итоги: предложение ИТОГИ

Предложение ИТОГИ работает иначе, чем ГРУППИРОВКА ПО: детальные строки сохраняются, а итоговые добавляются как отдельные записи. Это удобно для отчётов вида «документы с подытогами по контрагентам и общим итогом».

ВЫБРАТЬ

Реализация.Контрагент КАК Контрагент,

Реализация.Ссылка КАК Документ,

Реализация.СуммаДокумента КАК Сумма

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ИТОГИ

СУММА(Сумма)

ПО

Контрагент

Результат такого запроса обходят через ВыборкаИзГруппировки с типом обхода «По группировкам»: сначала идёт итоговая запись по контрагенту, затем вложенная выборка детальных строк. Поле Контрагент в итоговой записи заполнено, в общем итоге — NULL.

Если нужен только общий итог без разрезов, пишется ИТОГИ СУММА(Сумма) ПО ОБЩИЕ. Обратите внимание: при обходе результата с итогами легко ошибиться и просуммировать детальные строки вместе с итоговыми, получив удвоенные значения. Всегда явно задавайте тип обхода выборки.

Сравнение вариантов суммирования

СУММА + ГРУППИРОВКА ПО

Только итоговые строки по каждой группе. Подходит для сводных таблиц и дальнейшей обработки в коде. Детальные данные теряются.

СУММА + ИТОГИ ПО

Детальные строки плюс подытоги по уровням. Подходит для отчётов с группировками. Требует правильного обхода выборки.

Суммирование в СКД

Суммы считаются настройками отчёта, запрос выдаёт детальные данные. Подходит для отчётов, где пользователь сам меняет группировки.

Программное суммирование

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

Суммирование в СКД и в программном коде

Суммы в системе компоновки данных

В отчётах на СКД суммировать поля в тексте запроса часто не нужно. Достаточно выбрать детальные данные и на закладке «Ресурсы» указать ресурс с выражением Сумма(СуммаПродаж). Компоновка сама посчитает суммы по любым группировкам, которые пользователь добавит в настройках отчёта.

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

Суммирование при обходе выборки

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

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Сумма ИЗ Документ.РеализацияТоваровУслуг";

Выборка = Запрос.Выполнить().Выбрать();

ИтогоСумма = 0;

Пока Выборка.Следующий() Цикл

ИтогоСумма = ИтогоСумма + Выборка.Сумма;

КонецЦикла;

Такой способ оправдан только при нестандартных условиях. Для обычных сумм он медленнее и требует больше кода, чем СУММА в запросе: платформа выполняет агрегацию на уровне СУБД, а программный обход гоняет каждую строку через встроенный язык.

Как добавить сумму в запрос через конструктор
  1. 1
    Откройте конструктор запроса и выберите нужную таблицу в левой панели
  2. 2
    Перенесите суммируемое числовое поле в список полей
  3. 3
    На закладке «Группировка» перенесите поле в «Суммируемые поля» и выберите функцию Сумма
  4. 4
    Поля-измерения перенесите в «Поля группировки»
  5. 5
    Нажмите ОК и проверьте текст запроса: должны появиться СУММА и СГРУППИРОВАТЬ ПО
  6. 6
    Выполните запрос в консоли запросов и сверьте сумму с известным контрольным значением

Как проверить, что сумма посчитана правильно

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

Вторая проверка — детализация. Замените СУММА на выборку детальных строк и просуммируйте вручную небольшой фрагмент. Так быстро обнаруживаются задвоения из-за соединений: если к документу присоединить таблицу, где на один документ приходится несколько строк, сумма умножится на количество совпадений.

Третья проверка — граничные случаи: пустая выборка, строки с NULL, документы с нулевой суммой. Убедитесь, что запрос возвращает ожидаемое поведение в каждом из них, а не NULL там, где бизнес-логика ждёт ноль.

Контрольные точки

Как проверить результат

Сумма по запросу против стандартного отчёта
Норма

Значения совпадают при одинаковых отборах и периоде

Тревожный признак

Расхождение — проверьте отборы, виртуальные таблицы и соединения

Количество строк результата
Норма

Строк столько, сколько уникальных групп (или детальных записей при ИТОГИ)

Тревожный признак

Строк больше ожидаемого — вероятно задвоение через левое соединение

Пустая выборка
Норма

Сумма равна NULL или 0 (при ЕСТЬNULL), код это обрабатывает

Тревожный признак

Ошибка при обращении к полю или NULL попадает в расчёты

Обход результата с ИТОГИ
Норма

Итоговые записи обрабатываются отдельно от детальных

Тревожный признак

Итоги суммируются вместе с деталями — значения удваиваются

Типичные ошибки и ограничения

Самая частая ошибка — забыть перечислить неагрегатное поле в ГРУППИРОВКА ПО. Запрос падает с ошибкой ещё на этапе проверки, поэтому проблема выявляется быстро, но начинающих сбивает формулировка сообщения. Правило простое: каждое поле выборки либо внутри агрегатной функции, либо в списке группировки.

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

Третья группа проблем связана с типами данных. СУММА работает только с числовыми полями; попытка просуммировать строковое поле даст ошибку. Если сумма хранится в составном поле (число и строка), приведите значения к числу через ВЫРАЗИТЬ или отфильтруйте нечисловые варианты.

Отдельно стоит помнить про производительность. Группировка по полю большой таблицы без отборов заставляет СУБД обработать все записи. Всегда накладывайте отбор по периоду и организации, а для регистров накопления используйте виртуальные таблицы Обороты и ОстаткиИОбороты — они считают агрегаты по уже свёрнутым данным и работают на порядки быстрее.

Типичные ошибки
01
Поле в выборке не добавлено в ГРУППИРОВКА ПО — запрос не выполняется с ошибкой группировки
02
Суммирование после соединения с множественными строками — суммы задваиваются или утраиваются
03
Использование ГДЕ вместо ИМЕЮЩИЕ для фильтрации по сумме — условие применяется до группировки и не работает
04
Обход результата с ИТОГИ без учёта типа записи — итоговые строки суммируются повторно
05
Игнорирование NULL — результат NULL вместо 0 ломает последующие вычисления в коде
06
Группировка по полной таблице без отборов — запрос выполняется минутами вместо секунд

Когда какой способ выбрать

Одна итоговая цифра по отбору — СУММА без группировки. Сводная таблица по аналитике — СУММА с ГРУППИРОВКА ПО. Отчёт с детальными строками и подытогами — ИТОГИ ПО. Отчёт, где пользователь сам настраивает группировки, — ресурсы СКД с функцией Сумма над детальным запросом. Программное накопление в цикле — только для условий, которые невозможно выразить в языке запросов.

Если сомневаетесь между ГРУППИРОВКА ПО и ИТОГИ, задайте себе вопрос: нужны ли в результате сами детальные строки. Нужны — ИТОГИ. Нужны только суммы — группировка, она проще в обходе и предсказуемее.

Маршрут решения

Как выбрать способ

Нужна одна сумма по отфильтрованным строкамИспользуйте СУММА(Поле) без группировки
Нужны суммы по контрагентам, складам или периодамДобавьте СГРУППИРОВАТЬ ПО с перечислением полей разреза
Нужны детальные строки вместе с подытогамиИспользуйте ИТОГИ СУММА(Поле) ПО Измерение
Отчёт строится на СКД с настраиваемыми группировкамиОставьте запрос детальным и задайте ресурс Сумма в настройках СКД
Условие суммирования вычисляется сложной логикойНакапливайте сумму в переменной при обходе выборки
Итог

Что важно запомнить

Базовый инструмент суммирования — функция СУММА с ГРУППИРОВКА ПО для разрезов и ИТОГИ для подытогов с деталями. Все неагрегатные поля обязаны быть в группировке. Проверяйте результат сверкой со стандартным отчётом и остерегайтесь задвоений при соединениях.

Часто задаваемые вопросы

Почему запрос с СУММА выдаёт ошибку «Поле не входит в группу»?

В выборке есть обычное поле, которое не перечислено в ГРУППИРОВКА ПО. Либо добавьте это поле в группировку, либо уберите его из выборки, либо оберните в агрегатную функцию (МАКСИМУМ, МИНИМУМ), если нужно только одно представительское значение на группу.

Как получить ноль вместо NULL при пустой выборке?

Оберните аргумент функции в ЕСТЬNULL: СУММА(ЕСТЬNULL(Таб.Сумма, 0)). Учтите, что если выборка вообще не содержит строк, запрос без группировки вернёт одну строку с NULL — обработайте этот случай в коде через проверку на NULL или ЕСТЬNULL уже над результатом СУММА.

Чем отличается ГРУППИРОВКА ПО от ИТОГИ ПО?

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

Почему сумма после левого соединения стала больше реальной?

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

Можно ли суммировать по условию прямо в запросе?

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

Что быстрее: сумма в запросе или накопление в цикле?

Практически всегда быстрее сумма в запросе: агрегация выполняется на стороне СУБД над индексированными данными, а программный обход перебирает каждую строку во встроенном языке. Цикл оправдан только для логики, которую невозможно выразить средствами языка запросов.