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