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