Как вывести итоговый вес товаров в подвале документа Реализация товаров и услуг в 1С:УТ 11.4

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

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

Анализ задачи и выбор стратегии реализации

Для вывода веса нам необходимо решить три подзадачи: где хранить данные, как их рассчитывать и как отображать. Проанализируем ситуацию: вес каждой номенклатурной позиции может храниться либо в самой карточке Номенклатура (реквизиты ВесЧислитель и ВесЗнаменатель), либо в справочнике УпаковкиЕдиницыИзмерения, если в документе используются упаковки.

Существует два основных подхода к реализации:

  1. Изменение основной конфигурации: Добавление реквизита в объект или форму и написание кода в модулях.
  2. Использование расширения: Более предпочтительный метод, позволяющий оставить основную конфигурацию на поддержке и упростить будущие обновления.

Шаг 1: Подготовка данных и реквизитов формы

Прежде всего, нам нужно поле в подвале, куда будет выводиться итоговое значение. Если мы не хотим менять структуру базы данных (добавлять реквизит в сам документ РеализацияТоваровУслуг), мы можем создать Реквизит формы.

Разберем алгоритм действий в расширении:

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

Шаг 2: Алгоритм расчета веса в строке

Чтобы итоговый вес был верным, нужно правильно рассчитать вес каждой строки. Важно учитывать, что товар может отгружаться как в базовых единицах (штуках, кг), так и в упаковках (коробках, паллетах). Выясним причину, почему нельзя просто умножать количество на вес из карточки товара: если выбрана упаковка, ее индивидуальный вес может отличаться от простого произведения веса единицы на количество в упаковке.

Рассмотрим пример кода для расчета веса одной строки на сервере:


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

Шаг 3: Обновление итогов в подвале

Проанализируем ситуацию, когда должен происходить пересчет. Итоги должны обновляться при открытии документа и при любом изменении состава или количества товаров. Для этого нам нужно создать процедуру РассчитатьИтоговыйВесНаФорме и вызвать ее из соответствующих обработчиков событий.

Посмотрим на пример реализации процедуры пересчета всех строк:


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

Важный момент: Чтобы избежать «клиент-серверных прыжков» внутри цикла, рекомендуется один раз при получении данных (например, в ПриЧтенииНаСервере или при изменении номенклатуры) заполнять скрытую колонку ВесИтогПоСтроке в табличной части Товары. Тогда на клиенте расчет будет мгновенным.

Шаг 4: Интеграция с типовыми механизмами (Best Practice)

Программисты 1С часто рекомендуют использовать штатные механизмы. В УТ 11 существует общий модуль НоменклатураКлиентСервер, в котором могут быть функции для работы с весовыми характеристиками. Разберем по шагам, как подключить обработчики в расширении через аннотацию &После.

Нам необходимо расширить процедуру, которая отвечает за пересчет итогов документа:


&После("РассчитатьИтоговыеПоказателиДокумента")
Процедура Расш_РассчитатьИтоговыеПоказателиДокумента(Форма, ДокументОбъект = Неопределено)
    // Вызываем серверную функцию для расчета веса
    // Форма.ИтоговыйВесОбщий = Расш_СерверныйМодуль.РассчитатьВес(Форма.Объект);
КонецПроцедуры

Оптимизация производительности при работе с запросами

Как упоминалось в сообщениях форума, использование запроса — это более быстрый и правильный путь, особенно если в документе сотни строк. Вместо перебора объектов в цикле, мы можем отправить всю таблицу Товары в запрос на сервер.

Рассмотрим пример запроса:


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

Запрос.УстановитьПараметр("ТаблицаТовары", Объект.Товары.Выгрузить());
Результат = Запрос.Выполнить().Выбрать();
Если Результат.Следующий() Тогда
    ИтоговыйВесОбщий = Результат.ВесИтого;
КонецЕсли;

Этот подход гарантирует точность данных, так как учитывает актуальные веса из справочников, даже если они изменились с момента последнего редактирования строки.

Нюансы с весовым товаром

При реализации расчета обязательно выясним: является ли товар сам по себе весовым. В 1С:УТ, если единица измерения товара — «кг», то реквизит Количество уже по сути является весом. В программном коде необходимо добавить проверку: если Стр.Номенклатура.ЕдиницаИзмерения = ЕдиницаИзмеренияВеса, то дополнительно умножать на коэффициент веса не нужно, иначе произойдет «зацикливание» (умножение килограммов на вес одного килограмма).

Вывод в печатные формы

Если ваша задача заключается не только в отображении веса в интерфейсе, но и в выводе его в печатные формы (ТОРГ-12, УПД), то менять форму документа вовсе не обязательно. В этом случае достаточно создать внешнюю печатную форму или расширить макет типовой, где расчет будет производиться в момент формирования табличного документа. Однако наличие веса в подвале самой формы значительно повышает удобство работы менеджера «в моменте» формирования заказа.

Подведем итог: Для реализации вывода веса в подвале документа «Реализация товаров и услуг» лучше всего использовать Расширение конфигурации, добавить Реквизит формы для отображения итога и использовать Запрос для получения данных о весе из справочников Номенклатура или Упаковки. Это обеспечит высокую производительность и сохранит чистоту основной конфигурации.

← На главную