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

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

Как получить итоги из запроса 1С

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

Итоги в запросе 1С — это агрегированные значения (суммы, количества, средние), рассчитанные по группам строк или по всей выборке целиком. Они нужны практически в каждом отчёте: обороты по контрагенту, остатки по складу, сумма продаж за период. Платформа «1С:Предприятие» даёт два основных механизма: секцию ИТОГИ ПО в тексте запроса и агрегатные функции в секции ВЫБРАТЬ с группировкой.

Ошибки при работе с итогами приводят к типичным проблемам: суммы «задваиваются», итоговые строки попадают в детальные данные, либо разработчик обходит выборку циклом и суммирует вручную там, где запрос мог бы посчитать всё сам. Ниже разобраны оба подхода, обход выборки с группировками, итоги по периодам и контроль корректности результата.

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

Два способа получить итоги: группировка и секция ИТОГИ ПО

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

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

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

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

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

СГРУППИРОВАТЬ ПО + агрегаты

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

ИТОГИ ПО

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

Ручное суммирование в цикле

Гибко, но медленно и рискованно: легко получить дубли при соединениях. Оправдано только для сложных неаддитивных расчётов.

Агрегатные функции и группировка

Агрегатные функции языка запросов: СУММА, КОЛИЧЕСТВО, СРЕДНЕЕ, МАКСИМУМ, МИНИМУМ. Все поля в списке выборки, не обёрнутые в агрегатную функцию, обязаны быть перечислены в СГРУППИРОВАТЬ ПО — иначе конструктор выдаст ошибку ещё на этапе проверки запроса.

Пример — сумма и количество документов по каждому контрагенту:

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

Запрос.Текст =

"ВЫБРАТЬ

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

| СУММА(Продажи.Сумма) КАК СуммаПродаж,

| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Продажи.Ссылка) КАК ЧислоДокументов

|ИЗ

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

|ГДЕ

| Продажи.Проведен

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

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

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

Выборка = Результат.Выбрать();

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

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

КонецЦикла;

Обратите внимание на КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...): без ключевого слова РАЗЛИЧНЫЕ при соединении таблиц количество документов умножится на число строк соединения. Это одна из самых частых причин «задвоенных» итогов.

Типичные ошибки
01
Суммирование поля после соединения с табличной частью: одна шапка соединяется с несколькими строками, и СУММА задваивается. Решение — группировать до соединения или использовать вложенный запрос.
02
КОЛИЧЕСТВО без РАЗЛИЧНЫЕ при подсчёте документов — считает строки, а не документы.
03
Итоги по виртуальной таблице ОстаткиИОбороты без отбора по периоду — считаются данные за всё время, результат не сходится с отчётом.
04
Поле в ВЫБРАТЬ без агрегата и без группировки — ошибка построения запроса.

Секция ИТОГИ ПО и иерархическая выборка

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

Запрос.Текст =

"ВЫБРАТЬ

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

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

| Продажи.Сумма КАК Сумма

|ИЗ

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

|ИТОГИ

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

|ПО

| Контрагент";

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

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

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

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

ИтогПоКонтрагенту = ВыборкаГрупп.Сумма;

Детали = ВыборкаГрупп.Выбрать();

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

// Детальная строка: номенклатура и сумма

КонецЦикла;

КонецЦикла;

Общие итоги и несколько уровней группировки

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

Итоги по периодам и регистрам

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

"ВЫБРАТЬ

| Обороты.Период КАК Месяц,

| Обороты.Номенклатура КАК Номенклатура,

| Обороты.КоличествоОборот КАК Продано

|ИЗ

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

|ИТОГИ СУММА(Продано) ПО Месяц ПЕРИОДАМИ(МЕСЯЦ, &Начало, &Конец)";

Конструкция ПЕРИОДАМИ после поля группировки заставляет запрос выдать итоговые записи даже за те периоды, в которых не было движений. Это удобно для графиков и сводных таблиц: не придётся программно дополнять пропущенные месяцы нулями.

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

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

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

Второй контроль — сверка иерархии: сумма детальных записей группы должна сходиться с итоговой записью. Если в запросе есть соединения и сумма деталей больше итога — ищите дубли от соединения «один ко многим».

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

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

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

Итог запроса против типового отчёта за тот же период
Норма

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

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

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

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

Значения равны

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

Детали больше итога — дубли от соединения таблиц

Поля итогов в выборке
Норма

Числа или NULL, обработанный ЕСТЬNULL

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

Необработанный NULL ломает дальнейшие расчёты

Итоги без запроса: СКД и сводные таблицы

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

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

Если один и тот же запрос используется и для детальных данных, и для итогов, выгоднее выполнить его один раз с ИТОГИ ПО и обойти иерархически, чем выполнять два отдельных запроса. Но если детали не нужны — не тащите их из базы: плоская группировка всегда легче для СУБД.
ПЗ
Практическое замечание

FAQ

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

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

Почему СУММА в запросе даёт завышенное значение?

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

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

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

Что делать, если итоговое поле возвращает NULL?

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

Как получить итоги за каждый месяц, включая пустые?

Используйте виртуальную таблицу Обороты с периодичностью Месяц и в секции ИТОГИ укажите группировку по периоду с дополнением ПЕРИОДАМИ(МЕСЯЦ, &Начало, &Конец). Запрос выдаст итоговые записи и за месяцы без движений — с нулевыми или NULL-значениями ресурсов.

Можно ли получить итоги без написания запроса?

Да. В отчётах на СКД итоги по ресурсам рассчитываются автоматически на каждом уровне группировки. В таблице значений есть метод Итог("ИмяКолонки"). В консоли отчётов и стандартных отчётах конфигурации итоги выводятся настройками без программирования.

Итог

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

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