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