Как вывести суммарный вес и объем в форме документа 1С 8.3 (Управляемые формы)

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

При разработке и кастомизации документов в решениях на платформе 1С:Предприятие 8.3 (например, в «1С:Управление торговлей 11», «1С:ERP» или «1С:Комплексная автоматизация») часто возникает задача динамического расчета логистических параметров. Пользователям крайне важно видеть общие весогабаритные характеристики отгружаемых или принимаемых товаров прямо в форме документа — в его подвале или на специальной панели.

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

Почему старые методы обычного приложения не работают в управляемых формах

Начинающие разработчики часто пытаются перенести логику из обычных форм (например, из конфигураций «УТ 10.3» или «УПП 1.3») в управляемые формы «1С 8.3». Типичный пример такой ошибки — использование события таблицы ОформлениеСтроки или попытка напрямую в цикле на клиенте обходить строки табличной части и обращаться через точку к свойствам ссылочных данных, например: Строка.Номенклатура.Вес.

В управляемом приложении такое обращение приводит к крайне неприятным последствиям:

Способ 1. Оптимальный метод с кэшированием данных в строках табличной части

Чтобы расчет происходил мгновенно и без лишней нагрузки на сервер, мы применим классический паттерн разработки в 1С: кэширование характеристик номенклатуры в строках табличной части. Мы будем получать вес и объем один раз при выборе номенклатуры в строке (на сервере), а все последующие расчеты при изменении количества выполнять мгновенно на клиенте.

Проанализируем пошагово, как это реализовать:

  1. Добавим в табличную часть Товары нашего документа четыре новых реквизита: ВесЕдиницы (Число 15,3), ОбъемЕдиницы (Число 15,3), Вес (Число 15,3 — здесь будет храниться общий вес строки) и Объем (Число 15,3 — общий объем строки).
  2. Вынесем эти реквизиты на форму в виде колонок табличной части. Для колонок общего веса и объема запретим редактирование, чтобы пользователь не мог изменить их вручную.
  3. Создадим на форме документа два реквизита формы: ИтогВес (Число 15,3) и ИтогОбъем (Число 15,3). Перетащим их в дерево элементов формы в область подвала (или создадим отдельную группу внизу формы) и установим им вид Поле надписи.

Теперь перейдем к написанию кода в модуле управляемой формы.

Шаг 1. Заполнение весогабаритных характеристик при выборе номенклатуры

При изменении номенклатуры в строке табличной части нам необходимо обратиться к базе данных на сервере, получить вес и объем одной единицы товара и записать их в строку. Создадим обработчик события ТоварыНоменклатураПриИзменении:


&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
    
    СтрокаТаблицы = Элементы.Товары.ТекущиеДанные;
    Если СтрокаТаблицы <> Неопределено Тогда
        // Вызываем серверную процедуру для заполнения данных единицы измерения
        ЗаполнитьВесИОбъемНоменклатурыНаСервере(СтрокаТаблицы);
        // Пересчитываем итоги по строке и по всему документу
        РассчитатьСтрокуИИтоги(СтрокаТаблицы);
    КонецЕсли;
    
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ЗаполнитьВесИОбъемНоменклатурыНаСервере(СтрокаТаблицы)
    
    // Получаем вес и объем непосредственно из справочника Номенклатура за один запрос к БД
    ДанныеНоменклатуры = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(СтрокаТаблицы.Номенклатура, "ВесЧислитель, ОбъемЧислитель");
    
    СтрокаТаблицы.ВесЕдиницы = ДанныеНоменклатуры.ВесЧислитель;
    СтрокаТаблицы.ОбъемЕдиницы = ДанныеНоменклатуры.ОбъемЧислитель;
    
КонецПроцедуры

Обратите внимание на использование директивы &НаСервереБезКонтекста. Это позволяет избежать передачи контекста всей формы на сервер, что существенно экономит сетевой трафик и ускоряет работу программы.

Шаг 2. Расчет веса и объема строки и подсчет общих итогов на клиенте

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


&НаКлиенте
Процедура ТоварыКоличествоПриИзменении(Элемент)
    
    СтрокаТаблицы = Элементы.Товары.ТекущиеДанные;
    Если СтрокаТаблицы <> Неопределено Тогда
        РассчитатьСтрокуИИтоги(СтрокаТаблицы);
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьСтрокуИИтоги(СтрокаТаблицы)
    
    // Рассчитываем вес и объем для текущей строки
    СтрокаТаблицы.Вес = СтрокаТаблицы.Количество * СтрокаТаблицы.ВесЕдиницы;
    СтрокаТаблицы.Объем = СтрокаТаблицы.Количество * СтрокаТаблицы.ОбъемЕдиницы;
    
    // Пересчитываем общие итоги по всей табличной части на клиенте (быстрый цикл)
    ВсегоВес = 0;
    ВсегоОбъем = 0;
    
    Для Каждого ТекСтрока Из Объект.Товары Цикл
        ВсегоВес = ВсегоВес + ТекСтрока.Вес;
        ВсегоОбъем = ВсегоОбъем + ТекСтрока.Объем;
    КонецЦикла;
    
    // Записываем результат в реквизиты формы для отображения на экране
    ИтогВес = ВсегоВес;
    ИтогОбъем = ВсегоОбъем;
    
КонецПроцедуры

Шаг 3. Первоначальный расчет при открытии документа

Важно помнить, что когда пользователь открывает уже созданный и сохраненный документ, реквизиты формы ИтогВес и ИтогОбъем изначально будут равны нулю, так как они не хранятся в базе данных, а существуют только в контексте формы. Нам необходимо рассчитать их при инициализации. Лучше всего сделать это в обработчике события формы ПриЧтенииНаСервере:


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    
    // Рассчитываем итоги при открытии существующего документа
    ИтогВес = Объект.Товары.Итог("Вес");
    ИтогОбъем = Объект.Товары.Итог("Объем");
    
КонецПроцедуры

Метод Итог() является встроенным методом табличных частей и таблиц значений в 1С. Он работает на уровне платформы чрезвычайно быстро, суммируя числовые значения по указанной колонке.

Способ 2. Автоматический вывод итогов в подвал таблицы (Без написания кода)

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

Давайте разберем по шагам, как настроить этот функционал через свойства элементов в конфигураторе:

  1. Откройте форму документа в конфигураторе. В дереве элементов выделите таблицу формы (обычно она называется Товары).
  2. В панели свойств этой таблицы найдите свойство Подвал (Footer) и установите для него флажок в значение Истина. Это активирует отображение дополнительной строки итогов под самой таблицей.
  3. Разверните элементы таблицы формы и найдите колонку, отображающую общий вес строки (например, элемент ТоварыВес).
  4. В свойствах этого элемента найдите группу свойств «Оформление» и найдите свойство ПутьКДаннымПодвала (FooterPath).
  5. Укажите в качестве пути к данным следующее выражение: Объект.Товары.ИтогВес (или выберите через диалоговое окно автовычисляемый итог: Объект.Товары.Итог("Вес")).
  6. Повторите аналогичную операцию для колонки объема (ТоварыОбъем), указав в свойстве ПутьКДаннымПодвала путь: Объект.Товары.ИтогОбъем.

При использовании этого способа платформа 1С будет самостоятельно и автоматически суммировать значения в колонках и выводить их в подвал при любом изменении строк таблицы на клиенте. Вам больше не потребуется писать код для обхода строк в цикле и вручную заполнять реквизиты формы.

Настройка условного оформления для подсветки строк с незаполненным весом

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

Разберем, как настроить автоподсветку без написания программного кода через конфигуратор:

  1. В редакторе формы документа перейдите на вкладку Условное оформление (находится на нижней панели окна редактора формы или в свойствах самой формы).
  2. Нажмите кнопку Добавить для создания нового элемента условного оформления.
  3. На вкладке Оформление выберите параметр Цвет фона (например, нежно-розовый цвет с RGB-кодом 255, 200, 200) или Цвет текста. Нажмите ОК.
  4. Перейдите на вкладку Условие. Добавьте новое условие сравнения:
    • Поле: Объект.Товары.ВесЕдиницы
    • Вид сравнения: Равно
    • Значение: 0
  5. Перейдите на вкладку Оформляемые поля. Если вы хотите, чтобы подсвечивалась только конкретная ячейка с весом, добавьте в список поле ТоварыВесЕдиницы (и ТоварыВес при необходимости). Если нужно подсветить всю строку целиком, оставьте список оформляемых полей пустым.
  6. Нажмите ОК для сохранения настроек.

Платформа 1С берет на себя всю работу по отрисовке интерфейса. Как только в табличную часть будет добавлен товар с нулевым весом, ячейка мгновенно окрасится в заданный цвет прямо на клиенте.

Решение возможных ошибок при реализации алгоритма

Проанализируем частые ошибки, с которыми сталкиваются разработчики при написании кода:

Используя предложенные методики кэширования данных в строках и декларативного условного оформления, вы получите быстрое, надежное и отказоустойчивое решение, которое будет соответствовать всем стандартам разработки фирмы «1С».

← На главную