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