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

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

Как вывести итог в запросе 1С

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

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

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

Ниже разобраны синтаксис секции ИТОГИ, агрегатные функции, итоги по иерархии, обход результата с группировками, типичные ошибки и способы проверить, что итоги посчитаны правильно.

Агрегатные функции и группировка: простой итог без деталей

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

ВЫБРАТЬ

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

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

ИЗ

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

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

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

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

Для общего итога по всей выборке без разрезов группировка не нужна вовсе: достаточно написать ВЫБРАТЬ СУММА(Таблица.Сумма) ИЗ .... Запрос вернёт одну строку с итоговым значением. Если таблица пуста, СУММА вернёт NULL, а не ноль — учитывайте это при дальнейшем использовании результата.

Секция ИТОГИ: детальные строки плюс подытоги

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

ВЫБРАТЬ

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

Продажи.Номенклатура КАК Номенклатура,

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

ИЗ

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

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

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

Продажи.Номенклатура

ИТОГИ

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

ПО

Контрагент

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

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

bsl
ИТОГИ
	СУММА(Сумма),
	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Номенклатура)
ПО
	Контрагент,
	ОБЩИЕ

Обход результата запроса с итогами в коде

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

РезультатЗапроса = Запрос.Выполнить();

ВыборкаПоКонтрагентам = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

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

// Итоговая строка по контрагенту

Сообщить("Контрагент: " + ВыборкаПоКонтрагентам.Контрагент

+ ", итого: " + ВыборкаПоКонтрагентам.Сумма);

ВыборкаДетали = ВыборкаПоКонтрагентам.Выбрать();

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

// Детальные записи внутри группы

КонецЦикла;

КонецЦикла;

У строки общего итога (при указании ОБЩИЕ) поле группировки равно NULL. Это удобный признак для проверки: Если Выборка.Контрагент = NULL Тогда ... — значит, это общий итог. Вложенный вызов Выбрать() без параметров внутри итоговой строки возвращает детальные записи этой группы.

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

Типичные ошибки
01
Обход результата линейной выборкой: итоговые строки попадают в цикл, суммы удваиваются
02
Сравнение итоговой суммы с нулём вместо проверки на NULL — общий итог по пустой выборке теряется
03
Поле в списке выборки не входит ни в группировку, ни в агрегат — запрос не выполняется
04
Итоги по числовому полю, которое само рассчитано как СУММА, без повторного указания СУММА в секции ИТОГИ — синтаксическая ошибка

Итоги по иерархии справочников

Когда итог нужен не только по элементам, но и по папкам иерархического справочника (например, сумма продаж по группам номенклатуры), после поля группировки добавляется ключевое слово ИЕРАРХИЯ: ИТОГИ СУММА(Сумма) ПО Номенклатура ИЕРАРХИЯ. Запрос построит итоговые строки для каждого родителя.

ВЫБРАТЬ

Продажи.Номенклатура КАК Номенклатура,

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

ИЗ

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

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

Продажи.Номенклатура

ИТОГИ

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

ПО

Номенклатура ИЕРАРХИЯ

Обход такого результата выполняется с типом «ПоГруппировкамСИерархией». Учтите ограничение: итоги по иерархии заметно увеличивают объём результата и время выполнения, особенно на глубоких справочниках. Если иерархия нужна только для отображения, а не для расчётов, часто дешевле построить её в СКД, где группировка по иерархии настраивается без изменения текста запроса.

Итоги в СКД и в отчётах без программирования

В системе компоновки данных итоги чаще всего не требуют секции ИТОГИ в запросе вообще. Достаточно определить ресурсы (поля с агрегатными функциями на закладке «Ресурсы») и настройки группировок — СКД сама рассчитает подытоги и общий итог. Это предпочтительный путь для отчётов: пользователь сможет менять состав группировок в настройках, и итоги пересчитаются автоматически.

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

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

Сравнение вариантов

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

Нужна только сводка без деталей; самый быстрый вариант, минимальный объём результата

Секция ИТОГИ

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

Ресурсы СКД

Отчёт с настраиваемыми группировками; итоги пересчитываются при смене настроек без изменения запроса

Суммирование в цикле

Только для логики, не выразимой агрегатами; медленно и чревато ошибками округления

Проверка правильности итогов

После написания запроса проверьте итоги на контрольном примере с известным результатом. Возьмите период, где сумму можно сверить со стандартным отчётом конфигурации (например, оборотно-сальдовой ведомостью по регистру), и сравните общий итог. Расхождение обычно означает лишние соединения, задваивающие строки, или неверный отбор.

Отдельно проверьте граничные случаи: пустой период (итог должен быть NULL или ноль, но не ошибка), отбор, отсекающий все записи, и группировку, где у части групп детальных записей нет. Убедитесь, что в коде, потребляющем итог, NULL обрабатывается через ЕСТЬNULL или проверку.

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

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

Общий итог запроса против стандартного отчёта
Норма

Суммы совпадают до копейки

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

Расхождение — ищите дубли строк из-за соединений или неверный отбор

Сумма подытогов против общего итога
Норма

Сумма итогов по группам равна общему итогу

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

Не сходится — часть записей выпала из группировки (NULL в поле группы)

Поведение на пустой выборке
Норма

Итог NULL или 0, код не падает

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

Ошибка приведения типов или деление на NULL дальше по коду

Частые вопросы

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

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

Как вывести только общий итог без групп?

Два варианта: запрос вида ВЫБРАТЬ СУММА(Поле) ИЗ Таблица без группировки, который вернёт одну строку, или секция ИТОГИ СУММА(Поле) ПО ОБЩИЕ, если детальные записи тоже нужны. Первый вариант предпочтительнее, когда нужна только цифра.

Почему СУММА вернула NULL вместо нуля?

Агрегат СУММА по пустому набору записей или по набору, где все значения NULL, возвращает NULL. Чтобы получить ноль, используйте ЕСТЬNULL(СУММА(Поле), 0) в тексте запроса или проверку на NULL в коде перед использованием значения.

Как посчитать итог по нескольким полям одновременно?

Перечислите агрегаты через запятую: ИТОГИ СУММА(Сумма), СУММА(Количество), КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Документ) ПО Контрагент. Каждое итоговое выражение рассчитывается независимо для каждой группы и для общего итога.

Можно ли вывести итоги в запросе динамического списка?

Напрямую в колонках динамического списка итоги не выводятся. Обычно итог считают отдельным запросом с агрегатами и показывают в поле на форме, либо заменяют список отчётом на СКД, где итоги поддерживаются штатно.

Итог

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

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