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