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