Разработка и Конфигурация · 12 мин
Как просуммировать поля в запросе 1С
Как просуммировать поля в запросе 1С: функция СУММА, ГРУППИРОВКА ПО, ИТОГИ, суммирование в СКД и в коде. Примеры, типичные ошибки и проверка результата.
Суммирование полей — одна из самых частых операций при работе с запросами в 1С. Она встречается в отчётах по продажам, расчёте остатков на складе, сводках по зарплате и в любых агрегированных выборках. Платформа 1С предлагает несколько способов получить сумму: агрегатная функция СУММА в тексте запроса, предложение ИТОГИ, группировки в СКД и программное суммирование при обходе результата.
Выбор способа зависит от задачи. Если нужна одна итоговая цифра по всей выборке — достаточно функции СУММА без группировки. Если суммы нужны в разрезе контрагентов, складов или периодов — добавляется ГРУППИРОВКА ПО или ИТОГИ ПО. Если данные дальше идут в отчёт на СКД, суммирование лучше поручить самой компоновке, а не тексту запроса.
Ниже разобраны все основные варианты с примерами кода, условиями применения, ограничениями и типичными ошибками, которые приводят к неверным суммам или ошибкам выполнения запроса.
Сумма одного поля по всей выборке: функция СУММА
Самый простой случай — получить одну сумму по всей таблице или по отфильтрованному набору строк. Для этого в списке полей выборки указывается агрегатная функция СУММА с именем числового поля в скобках. Пример для табличной части документа реализации:
ВЫБРАТЬ
СУММА(РеализацияТовары.Сумма) КАК СуммаВсего
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТовары
ГДЕ
РеализацияТовары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
Здесь запрос вернёт одну строку с одной колонкой СуммаВсего. Псевдоним через КАК важен: без него обращаться к полю результата придётся по сгенерированному имени, что неудобно и небезопасно при доработках.
Если в выборке, кроме СУММА, есть обычные поля (например, Организация или Склад), запрос не выполнится с ошибкой «Поле не входит в группу». Платформа требует: либо все поля агрегатные, либо неагрегатные поля явно перечислены в ГРУППИРОВКА ПО. Это частая причина ошибок у начинающих разработчиков.
Суммы по группам: ГРУППИРОВКА ПО
Когда суммы нужны в разрезе аналитики — по контрагентам, номенклатуре, складам — используется предложение ГРУППИРОВКА ПО. В нём перечисляются все неагрегатные поля выборки:
ВЫБРАТЬ
Продажи.Контрагент КАК Контрагент,
СУММА(Продажи.СуммаОборот) КАК СуммаПродаж
ИЗ
РегистрНакопления.Продажи.Обороты(&Начало, &Конец, , ) КАК Продажи
СГРУППИРОВАТЬ ПО
Продажи.Контрагент
Группировать можно по нескольким полям — тогда сумма считается по каждой уникальной комбинации. Например, ГРУППИРОВКА ПО Контрагент, Склад даст сумму продаж каждого контрагента по каждому складу отдельно.
Полезное дополнение — предложение ИМЕЮЩИЕ, аналог HAVING в SQL. Оно фильтрует уже сгруппированные строки по значению агрегата: например, оставить только контрагентов с суммой продаж больше заданной. Обычный ГДЕ здесь не сработает, потому что он применяется до группировки.
СГРУППИРОВАТЬ ПО
Продажи.Контрагент
ИМЕЮЩИЕ
СУММА(Продажи.СуммаОборот) > &МинСумма
Иерархические итоги: предложение ИТОГИ
Предложение ИТОГИ работает иначе, чем ГРУППИРОВКА ПО: детальные строки сохраняются, а итоговые добавляются как отдельные записи. Это удобно для отчётов вида «документы с подытогами по контрагентам и общим итогом».
ВЫБРАТЬ
Реализация.Контрагент КАК Контрагент,
Реализация.Ссылка КАК Документ,
Реализация.СуммаДокумента КАК Сумма
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ИТОГИ
СУММА(Сумма)
ПО
Контрагент
Результат такого запроса обходят через ВыборкаИзГруппировки с типом обхода «По группировкам»: сначала идёт итоговая запись по контрагенту, затем вложенная выборка детальных строк. Поле Контрагент в итоговой записи заполнено, в общем итоге — NULL.
Если нужен только общий итог без разрезов, пишется ИТОГИ СУММА(Сумма) ПО ОБЩИЕ. Обратите внимание: при обходе результата с итогами легко ошибиться и просуммировать детальные строки вместе с итоговыми, получив удвоенные значения. Всегда явно задавайте тип обхода выборки.
Сравнение вариантов суммирования
Только итоговые строки по каждой группе. Подходит для сводных таблиц и дальнейшей обработки в коде. Детальные данные теряются.
Детальные строки плюс подытоги по уровням. Подходит для отчётов с группировками. Требует правильного обхода выборки.
Суммы считаются настройками отчёта, запрос выдаёт детальные данные. Подходит для отчётов, где пользователь сам меняет группировки.
Накопление в переменной при обходе выборки. Подходит для сложных условий, которые не выразить в запросе, но медленнее и громоздче.
Суммирование в СКД и в программном коде
Суммы в системе компоновки данных
В отчётах на СКД суммировать поля в тексте запроса часто не нужно. Достаточно выбрать детальные данные и на закладке «Ресурсы» указать ресурс с выражением Сумма(СуммаПродаж). Компоновка сама посчитает суммы по любым группировкам, которые пользователь добавит в настройках отчёта.
Преимущество подхода — гибкость: один и тот же запрос даёт суммы по контрагентам, периодам, складам без изменения кода. Если же просуммировать данные уже в запросе, дальнейшая группировка в СКД будет невозможна или даст ошибочные результаты при детализации.
Суммирование при обходе выборки
Когда логика сложнее, чем позволяет язык запросов (например, суммировать только строки, удовлетворяющие вычисляемому условию), сумму накапливают в переменной при обходе результата:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Сумма ИЗ Документ.РеализацияТоваровУслуг";
Выборка = Запрос.Выполнить().Выбрать();
ИтогоСумма = 0;
Пока Выборка.Следующий() Цикл
ИтогоСумма = ИтогоСумма + Выборка.Сумма;
КонецЦикла;
Такой способ оправдан только при нестандартных условиях. Для обычных сумм он медленнее и требует больше кода, чем СУММА в запросе: платформа выполняет агрегацию на уровне СУБД, а программный обход гоняет каждую строку через встроенный язык.
- 1Откройте конструктор запроса и выберите нужную таблицу в левой панели
- 2Перенесите суммируемое числовое поле в список полей
- 3На закладке «Группировка» перенесите поле в «Суммируемые поля» и выберите функцию Сумма
- 4Поля-измерения перенесите в «Поля группировки»
- 5Нажмите ОК и проверьте текст запроса: должны появиться СУММА и СГРУППИРОВАТЬ ПО
- 6Выполните запрос в консоли запросов и сверьте сумму с известным контрольным значением
Как проверить, что сумма посчитана правильно
Главный приём проверки — сопоставление с независимым источником. Для отчёта по продажам контрольной точкой служит стандартный отчёт конфигурации за тот же период с теми же отборами. Для остатков — оборотно-сальдовая ведомость или отчёт по складу. Если суммы расходятся, сначала сверяют отборы: период, организацию, признак проведённости документов.
Вторая проверка — детализация. Замените СУММА на выборку детальных строк и просуммируйте вручную небольшой фрагмент. Так быстро обнаруживаются задвоения из-за соединений: если к документу присоединить таблицу, где на один документ приходится несколько строк, сумма умножится на количество совпадений.
Третья проверка — граничные случаи: пустая выборка, строки с NULL, документы с нулевой суммой. Убедитесь, что запрос возвращает ожидаемое поведение в каждом из них, а не NULL там, где бизнес-логика ждёт ноль.
Как проверить результат
Значения совпадают при одинаковых отборах и периоде
Расхождение — проверьте отборы, виртуальные таблицы и соединения
Строк столько, сколько уникальных групп (или детальных записей при ИТОГИ)
Строк больше ожидаемого — вероятно задвоение через левое соединение
Сумма равна NULL или 0 (при ЕСТЬNULL), код это обрабатывает
Ошибка при обращении к полю или NULL попадает в расчёты
Итоговые записи обрабатываются отдельно от детальных
Итоги суммируются вместе с деталями — значения удваиваются
Типичные ошибки и ограничения
Самая частая ошибка — забыть перечислить неагрегатное поле в ГРУППИРОВКА ПО. Запрос падает с ошибкой ещё на этапе проверки, поэтому проблема выявляется быстро, но начинающих сбивает формулировка сообщения. Правило простое: каждое поле выборки либо внутри агрегатной функции, либо в списке группировки.
Вторая ошибка — суммирование после левого соединения без учёта кратности. Если к продажам присоединить, например, дополнительные реквизиты или таблицу с несколькими строками на документ, сумма продаж задвоится или затроится. Решение — сначала сгруппировать присоединяемую таблицу до одной строки на ключ, и только потом соединять.
Третья группа проблем связана с типами данных. СУММА работает только с числовыми полями; попытка просуммировать строковое поле даст ошибку. Если сумма хранится в составном поле (число и строка), приведите значения к числу через ВЫРАЗИТЬ или отфильтруйте нечисловые варианты.
Отдельно стоит помнить про производительность. Группировка по полю большой таблицы без отборов заставляет СУБД обработать все записи. Всегда накладывайте отбор по периоду и организации, а для регистров накопления используйте виртуальные таблицы Обороты и ОстаткиИОбороты — они считают агрегаты по уже свёрнутым данным и работают на порядки быстрее.
Когда какой способ выбрать
Одна итоговая цифра по отбору — СУММА без группировки. Сводная таблица по аналитике — СУММА с ГРУППИРОВКА ПО. Отчёт с детальными строками и подытогами — ИТОГИ ПО. Отчёт, где пользователь сам настраивает группировки, — ресурсы СКД с функцией Сумма над детальным запросом. Программное накопление в цикле — только для условий, которые невозможно выразить в языке запросов.
Если сомневаетесь между ГРУППИРОВКА ПО и ИТОГИ, задайте себе вопрос: нужны ли в результате сами детальные строки. Нужны — ИТОГИ. Нужны только суммы — группировка, она проще в обходе и предсказуемее.
Как выбрать способ
Что важно запомнить
Базовый инструмент суммирования — функция СУММА с ГРУППИРОВКА ПО для разрезов и ИТОГИ для подытогов с деталями. Все неагрегатные поля обязаны быть в группировке. Проверяйте результат сверкой со стандартным отчётом и остерегайтесь задвоений при соединениях.
Часто задаваемые вопросы
Почему запрос с СУММА выдаёт ошибку «Поле не входит в группу»?
В выборке есть обычное поле, которое не перечислено в ГРУППИРОВКА ПО. Либо добавьте это поле в группировку, либо уберите его из выборки, либо оберните в агрегатную функцию (МАКСИМУМ, МИНИМУМ), если нужно только одно представительское значение на группу.
Как получить ноль вместо NULL при пустой выборке?
Оберните аргумент функции в ЕСТЬNULL: СУММА(ЕСТЬNULL(Таб.Сумма, 0)). Учтите, что если выборка вообще не содержит строк, запрос без группировки вернёт одну строку с NULL — обработайте этот случай в коде через проверку на NULL или ЕСТЬNULL уже над результатом СУММА.
Чем отличается ГРУППИРОВКА ПО от ИТОГИ ПО?
ГРУППИРОВКА ПО сворачивает строки: в результате остаются только итоговые записи по каждой группе. ИТОГИ ПО сохраняет детальные строки и добавляет к ним итоговые записи по указанным измерениям, поэтому результат нужно обходить с учётом типа записи — детальная или итоговая.
Почему сумма после левого соединения стала больше реальной?
Присоединяемая таблица содержит несколько строк на одну строку основной таблицы, и сумма основной умножается на их количество. Сначала сгруппируйте присоединяемую таблицу до одной строки на ключ соединения во вложенном запросе, затем выполняйте соединение.
Можно ли суммировать по условию прямо в запросе?
Да, через конструкцию ВЫБОР внутри СУММА: СУММА(ВЫБОР КОГДА Таб.ВидОперации = &Продажа ТОГДА Таб.Сумма ИНАЧЕ 0 КОНЕЦ). Так в одном запросе получают несколько сумм по разным условиям — например, отдельно продажи и возвраты.
Что быстрее: сумма в запросе или накопление в цикле?
Практически всегда быстрее сумма в запросе: агрегация выполняется на стороне СУБД над индексированными данными, а программный обход перебирает каждую строку во встроенном языке. Цикл оправдан только для логики, которую невозможно выразить средствами языка запросов.