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

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

Как в 1С посчитать сумму в таблице

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

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

Для пользователя чаще всего достаточно встроенных итогов формы или группировок отчёта. Разработчику и внедренцу нужны программные методы: функция Итог() таблицы значений, агрегатная функция СУММА() в языке запросов, свёртка и сводные таблицы. Ниже разобраны все рабочие варианты с примерами кода и ограничениями.

Материал ориентирован на типовые конфигурации на платформе 1С:Предприятие 8.3 (Управление торговлей, ERP, Бухгалтерия, Зарплата и управление персоналом), но описанные приёмы работают и в самописных решениях.

Как посчитать сумму по табличной части документа

Табличная часть документа (например, «Товары» в реализации) — это коллекция строк, у которой есть встроенный метод Итог(). Он суммирует значения числовой колонки по всем строкам и возвращает число.

СуммаДокумента = Объект.Товары.Итог("Сумма");

СуммаНДС = Объект.Товары.Итог("СуммаНДС");

Метод работает и на клиенте, и на сервере, не требует обращения к базе данных — считается по данным в памяти. Если колонка содержит незаполненные значения, они трактуются как ноль, ошибки не возникает.

В типовых конфигурациях итог по табличной части часто уже выведен на форму автоматически: внизу таблицы отображается строка «Итого». Если её нет, проверьте свойство «Подвал» у таблицы формы и включите отображение итогов для нужной колонки в настройках формы.

Сумма в таблице значений: Итог() и Свернуть()

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

ТЗ = Новый ТаблицаЗначений;

// ... заполнение таблицы ...

ОбщаяСумма = ТЗ.Итог("Сумма");

Если нужна не одна сумма, а суммы в разрезе групп (по контрагентам, складам, номенклатуре), используется метод Свернуть(). Он группирует строки по указанным колонкам и суммирует числовые:

ТЗ.Свернуть("Контрагент", "Сумма, Количество");

// теперь в ТЗ одна строка на каждого контрагента

// с суммой и количеством по нему

Учтите: Свернуть() изменяет саму таблицу, исходная детализация теряется. Если построчные данные ещё понадобятся, сначала сделайте копию через ТЗ.Скопировать() и сворачивайте копию.

Типичные ошибки
01
Вызов Свернуть() для основной таблицы — детальные строки удаляются безвозвратно, последующий код работает с уже агрегированными данными
02
Попытка суммировать строковую колонку — Итог() вернёт 0 или ошибку, если тип колонки не числовой
03
Суммирование колонки со значениями NULL из запроса — результат может отличаться от ожидаемого, нужно ЕстьNULL() в запросе

Сумма в запросе: функция СУММА()

Когда данные лежат в базе, а не в памяти, сумму эффективнее считать запросом — это быстрее, чем выгружать строки и складывать их циклом. В языке запросов 1С есть агрегатная функция СУММА():

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

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

"ВЫБРАТЬ

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

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

|ИЗ

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

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

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

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

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

bsl
Запрос.Текст = "ВЫБРАТЬ СУММА(ЕстьNULL(Товары.Сумма, 0)) КАК Итого ИЗ Документ.РеализацияТоваровУслуг.Товары КАК Товары ГДЕ Товары.Ссылка = &Ссылка";

Как посчитать сумму без программирования

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

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

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

Нужна сумма по строкам открытого документаИспользуйте Объект.ТабличнаяЧасть.Итог("Сумма") или подвал формы
Данные в таблице значений в обработкеИтог() для общей суммы, Свернуть() для сумм по группам
Данные в базе, объём большойЗапрос с СУММА() — быстрее выгрузки и цикла
Нужна одноразовая проверка без кодаУниверсальный отчёт или группировка в типовом отчёте

Сумма с условием: отбор строк перед расчётом

Часто нужна не общая сумма, а сумма по части строк: по конкретному складу, ставке НДС, признаку оплаты. Универсального метода «Итог с условием» в таблице значений нет, поэтому применяют три подхода.

Первый — скопировать строки по отбору и посчитать итог по копии:

Отбор = Новый Структура("Склад", СкладОтгрузки);

ТЗОтбор = ТЗ.Скопировать(Отбор);

СуммаПоСкладу = ТЗОтбор.Итог("Сумма");

Второй — цикл с накоплением. Он гибче: позволяет комбинировать несколько условий и считать сразу несколько сумм за один проход:

СуммаНал = 0; СуммаБезнал = 0;

Для Каждого Строка Из ТЗ Цикл

Если Строка.ФормаОплаты = "Наличные" Тогда

СуммаНал = СуммаНал + Строка.Сумма;

Иначе

СуммаБезнал = СуммаБезнал + Строка.Сумма;

КонецЕсли;

КонецЦикла;

Третий — условие прямо в запросе через ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ 0 КОНЕЦ внутри СУММА(). Это оптимально для больших объёмов, так как расчёт выполняется на уровне СУБД.

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

Проверка результата и типичные проблемы

После расчёта сумму стоит проверить, особенно если результат идёт в документ или отчёт. Самый простой контроль — сравнить программный итог с итогом, который показывает форма документа, либо с суммой по отчёту за тот же период.

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

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

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

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

Совпадение с формой документа
Норма

Итог() равен сумме в подвале таблицы

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

Расхождение — проверить отборы и скрытые строки

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

Число строк соответствует ожидаемому набору данных

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

Строк больше — возможны дубли после объединения таблиц

Тип колонки
Норма

Колонка числовая, Итог() возвращает число

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

Итог равен 0 при заполненных строках — колонка строковая

NULL в данных запроса
Норма

Применено ЕстьNULL, сумма стабильна

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

Сумма пропадает или занижена при пустых значениях

Производительность: когда цикл заменить запросом

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

Правило простое: если данные ещё не выгружены из базы — агрегируйте в запросе. Если уже лежат в таблице значений — используйте Итог() и Свернуть(), а не ручные циклы. Цикл оставляйте для случаев со сложной логикой условий, которую невозможно выразить группировкой.

FAQ: частые вопросы о суммировании в 1С

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

Динамический список не имеет метода Итог(). Варианты: включить итоги в подвале таблицы формы через настройку, либо выполнить тот же запрос, что у списка, с СУММА() и показать результат отдельным полем.

Почему Итог() возвращает 0, хотя колонка заполнена?

Чаще всего колонка имеет строковый тип или неопределённый состав типа. Проверьте тип колонки таблицы значений; при необходимости создайте колонку с описанием типа «Число» и заполните её преобразованными значениями.

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

В модуле формы обойдите коллекцию Элементы.Таблица.ВыделенныеСтроки, получите данные каждой строки через ДанныеСтроки() и сложите значения нужной колонки в переменную.

Чем СУММА() в запросе лучше цикла по выборке?

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

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

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

Можно ли суммировать таблицу значений без потери детальных строк?

Да. Метод Итог() не изменяет таблицу. Для группировок сделайте копию через Скопировать() и примените Свернуть() к копии — исходная таблица останется нетронутой.

Итог

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

Для табличной части и таблицы значений используйте Итог(), для группировок — Свернуть() на копии таблицы, для данных в базе — запрос с СУММА() и ЕстьNULL(). Перед доверием результату сверьте его с итогом формы или отчёта и проверьте состав строк на дубли и отборы.