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

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

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

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

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

Самый быстрый вариант — метод Итог(), доступный у коллекции табличной части. Он возвращает сумму по указанному реквизиту без написания цикла. Более гибкие варианты — перебор строк в цикле с условиями и запрос к данным объекта. Каждый подход имеет свои ограничения: например, Итог() не умеет фильтровать строки, а запрос требует, чтобы объект был записан в базу.

Ниже разобраны все рабочие способы с примерами кода, типичные ошибки при обращении к табличным частям и способы проверить, что итог посчитан верно.

Метод Итог() — самый короткий способ

У любой табличной части объекта (документа, справочника, обработки) есть встроенный метод Итог(ИмяКолонки). В параметре передаётся строка с именем числового реквизита, по которому нужно получить сумму. Метод работает и на сервере, и на клиенте, и не требует записи объекта в базу.

// В модуле объекта или формы документа "РеализацияТоваровУслуг"

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

КоличествоВсего = Объект.Товары.Итог("Количество");

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

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

Сумма через цикл с условиями отбора

Когда суммировать нужно не все строки, а только часть, используется классический перебор коллекции табличной части. Внутри цикла проверяется условие, и значение добавляется к накопительной переменной.

СуммаОблагаемых = 0;

Для Каждого СтрокаТовары Из Объект.Товары Цикл

Если СтрокаТовары.СтавкаНДС <> Перечисления.СтавкиНДС.БезНДС Тогда

СуммаОблагаемых = СуммаОблагаемых + СтрокаТовары.Сумма;

КонецЕсли;

КонецЦикла;

Цикл даёт полный контроль: можно суммировать по нескольким условиям, считать сразу несколько итогов за один проход, учитывать вычисляемые значения (например, СтрокаТовары.Цена * СтрокаТовары.Количество, если колонки «Сумма» нет вовсе). Это универсальный способ, который работает везде — в модуле объекта, в форме, во внешней обработке.

Недостаток один: код длиннее и при большом числе условий становится громоздким. Для простого итога без фильтров предпочтительнее Итог() — он короче и читается легче.

Порядок действий при подсчёте циклом
  1. 1
    Объявите переменную-накопитель и присвойте ей 0
  2. 2
    Организуйте цикл Для Каждого по строкам табличной части
  3. 3
    Внутри цикла добавьте условие отбора, если оно нужно
  4. 4
    Прибавляйте значение реквизита строки к накопителю
  5. 5
    После цикла используйте результат и проверьте его на контрольном примере

Подсчёт суммы запросом

Запрос к табличной части имеет смысл, когда документ уже записан в базу и нужен итог по данным именно из базы, а не из редактируемой формы. Табличная часть хранится как отдельная таблица с именем вида Документ.РеализацияТоваровУслуг.Товары.

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

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

"ВЫБРАТЬ

| СУММА(Товары.Сумма) КАК СуммаИтог

|ИЗ

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

|ГДЕ

| Товары.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

СуммаДокумента = Выборка.СуммаИтог;

КонецЕсли;

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

Ограничение принципиальное: запрос видит только записанные данные. Если пользователь изменил строки в открытой форме и не сохранил документ, запрос вернёт устаревший итог. В этом случае работайте с данными формы через Итог() или цикл.

Сравнение способов

Метод Итог()

Подходит для простого итога по всем строкам в форме или модуле объекта. Не умеет фильтровать строки.

Цикл с накоплением

Универсален, позволяет любые условия и вычисляемые значения. Кода больше, но работает везде.

Запрос

Оптимален для записанных данных, группировок и анализа по многим документам. Не видит несохранённые изменения в форме.

Вывод итога в подвале таблицы на форме

Часто сумму по колонке нужно не вычислять в коде, а просто показать пользователю под таблицей. Для этого в управляемой форме у элемента «Таблица» включается подвал (свойство Подвал), а у колонки, по которой нужен итог, заполняются свойства ПутьКДаннымПодвала и ТекстПодвала либо настройка отображения итога в зависимости от версии платформы.

В типовых конфигурациях на управляемых формах итог по колонке «Сумма» обычно уже выведен в подвал. Если его нет, разработчик добавляет реквизит формы и в обработчиках ПриИзменении строк табличной части пересчитывает его через Объект.Товары.Итог("Сумма"), привязывая реквизит к полю внизу формы.

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

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

Особенности для обычных форм и тонкого клиента

В обычных формах (режим обычного приложения) у табличного поля есть встроенная возможность показать итог в подвале колонки через палитру свойств — достаточно установить флаг отображения итога у нужной колонки, и платформа посчитает сумму автоматически. Код писать не нужно.

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

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

После реализации подсчёта сверьте итог с ручным расчётом на тестовом документе из трёх–пяти строк с простыми числами. Это сразу выявляет ошибки в имени колонки, неверный контекст обращения или пропущенные строки.

Типичные ошибки
01
Опечатка в имени колонки в методе Итог() — платформа выдаёт ошибку о несуществующем реквизите или возвращает не тот итог
02
Обращение к табличной части из модуля формы без префикса Объект — код не видит данные
03
Использование запроса к незаписанному документу — итог не учитывает свежие правки пользователя
04
Попытка суммировать нечисловой реквизит — ошибка выполнения
05
Отсутствие пересчёта итога после удаления строки — на форме показывается устаревшая сумма
Контрольные точки

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

Сумма на контрольном документе
Норма

Совпадает с ручным сложением значений колонки

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

Расходится — проверьте имя реквизита и условия отбора

Итог после удаления строки
Норма

Пересчитывается автоматически

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

Остаётся прежним — не обработано событие ПослеУдаления

Пустая табличная часть
Норма

Итог равен 0, ошибок нет

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

Ошибка или значение Неопределено — добавьте проверку результата запроса

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

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

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

Что вернёт Итог(), если табличная часть пустая?

Метод вернёт 0 — это безопасно, отдельная проверка на пустоту не требуется. А вот запрос с функцией СУММА по пустой выборке вернёт NULL, поэтому результат запроса стоит оборачивать проверкой или использовать ЕСТЬNULL в тексте запроса.

Можно ли посчитать сумму сразу по нескольким колонкам?

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

Почему Итог("Сумма") возвращает не то значение, что видно в документе?

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

Как вывести сумму колонки в печатную форму документа?

В модуле менеджера печати или при формировании табличного документа получите итог через Итог() по табличной части объекта и присвойте его параметру области макета: ОбластьИтог.Параметры.СуммаИтог = Объект.Товары.Итог("Сумма").