Как посчитать и вывести итоговый вес позиций табличной части документа в 1С:Управление торговлей 10?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке и доработке документов в конфигурации «1С:Управление торговлей» ред. 10.3 (на обычных формах) часто возникает задача вывести суммарный вес всех товаров, добавленных в документ. В этой статье разберем, как правильно реализовать данный расчет, избежать неэффективных циклов и обращений к базе данных, а также правильно обновить значение в элементах формы.

Выявление проблемы прямого перебора табличной части

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

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

Способ 1. Добавление реквизита строки и использование метода Итог()

Проанализируем наиболее простое и эффективное решение с точки зрения быстродействия при редактировании документа. Для этого добавим реквизит Вес (числовой тип) в табличную часть Товары конфигуратора.

Разберем по шагам порядок действий:

  1. В конфигураторе для табличной части Товары создаем реквизит Вес (число, длина 15, точность 3).
  2. При изменении номенклатуры, количества или единицы измерения рассчитываем вес текущей строки.
  3. Для расчета общего итогового веса используем встроенный метод табличной части Товары.Итог("Вес").

Рассмотрим пример кода в модуле формы документа:


// Расчет веса в строке табличной части при изменении значений
СтрокаТабличнойЧасти = ЭлементыФормы.Товары.ТекущиеДанные;
Если СтрокаТабличнойЧасти <> Неопределено Тогда
    СтрокаТабличнойЧасти.Вес = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.ЕдиницаИзмерения.Вес;
КонецЕсли;

// Обновление итоговой надписи подвала формы
ИтоговыйВес = Товары.Итог("Вес");
ЭлементыФормы.ИтВес.Значение = ОбщегоНазначения.ФорматСумм(ИтоговыйВес) + " кг.";

Способ 2. Расчет через один запрос по табличной части без изменения структуры базы

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

Посмотрим на пример реализации расчета запросом:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	СУММА(Т.Количество * ВЫБОР
    |			КОГДА Т.Номенклатура.Весовой
    |				ТОГДА 1
    |			ИНАЧЕ ЕСТЬNULL(Т.ЕдиницаИзмерения.Вес, 0)
    |		КОНЕЦ) КАК ВесВсего
    |ИЗ
    |	&ТЧТовары КАК Т";

Запрос.УстановитьПараметр("ТЧТовары", ЭтотОбъект.Товары.Выгрузить());
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Если Выборка.Следующий() Тогда
    ВсегоВес = Выборка.ВесВсего;
    ЭлементыФормы.ИтВес.Значение = Формат(ВсегоВес, "ЧДЦ=3") + " кг.";
КонецЕсли;

Способ 3. Вывод итога в подвал табличной части

Альтернативным вариантом отображения является вывод итогового веса непосредственно в подвал колонки табличного поля без создания отдельной надписи на форме:

  1. Для элемента формы ЭлементыФормы.Товары устанавливаем свойство ОтображатьПодвал = Истина.
  2. В процедуре пересчета итогов задаем значение подвала колонки:

ИтоговыйВес = Товары.Итог("Вес");
ЭлементыФормы.Товары.Колонки.Вес.ТекстПодвала = Формат(ИтоговыйВес, "ЧДЦ=3");

Необходимые события формы для актуализации итогов

Чтобы итоговый вес всегда оставался актуальным при любых действиях пользователя, процедуру пересчета итогов необходимо вызывать в следующих событиях формы документа:

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

← На главную