Как во внешней печатной форме УТ 10.3 вывести вес, количество мест и рассчитать по ним итоги?

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

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

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

Почему простое обращение к реквизитам табличной части вызывает ошибку?

Рассмотрим типичную ошибку начинающего разработчика. Пытаясь заполнить параметры макета напрямую из табличной части документа, программист пишет следующий код:


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

При выполнении этого кода система выдаст ошибку, сообщающую, что поле объекта Вес не обнаружено. Дело в том, что в типовой конфигурации УТ 10.3 вес не хранится физически в строках табличной части документов. Это сделано в целях нормализации базы данных: вес является характеристикой самой номенклатурной позиции (или ее упаковки), а не конкретной сделки.

Где физически хранится вес и как его получить?

Проанализируем структуру хранения данных в конфигурации «Управление торговлей 10.3». Вес привязан к конкретной единице измерения номенклатуры.

  1. У каждого элемента справочника Номенклатура есть подчиненный справочник ЕдиницыИзмерения.
  2. Именно в справочнике ЕдиницыИзмерения содержится числовой реквизит Вес. Это позволяет задавать разный вес для различных упаковок товара (например, вес штуки, вес коробки, вес паллеты).
  3. В табличной части Товары документа продажи есть реквизит ЕдиницаИзмерения, который ссылается на элемент этого подчиненного справочника.

Таким образом, чтобы получить вес единицы товара в строке, нам необходимо обратиться к нему через точку:

ВесЕдиницы = ТекущаяСтрока.ЕдиницаИзмерения.Вес;

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

ОбщийВесСтроки = ТекущаяСтрокаКоличество * ТекущаяСтрока.ЕдиницаИзмерения.Вес;

Разбираемся с логикой учета мест и упаковок

В «Управлении торговлей» реализована сложная, но гибкая система работы с транспортными местами. В одной строке документа могут фигурировать сразу две разные единицы измерения:

Если в документе заполнена колонка ЕдиницаМест, количество мест рассчитывается на основании коэффициентов соотношения этих единиц. Формула пересчета выглядит следующим образом:

Количество мест = (Количество * Коэффициент основной единицы) / Коэффициент единицы мест

В коде печатной формы этот расчет реализуется следующим образом:


КолМест = 0;
Если ЗначениеЗаполнено(ТекущаяСтрока.ЕдиницаМест) Тогда
    КоэффициентБазовый = ?(ЗначениеЗаполнено(ТекущаяСтрока.ЕдиницаИзмерения), ТекущаяСтрока.ЕдиницаИзмерения.Коэффициент, 1);
    КоэффициентМеста = ТекущаяСтрока.ЕдиницаМест.Коэффициент;
    
    Если КоэффициентМеста <> 0 Тогда
        КолМест = (ТекущаяСтрока.Количество * КоэффициентБазовый) / КоэффициентМеста;
    КонецЕсли;
КонецЕсли;

Как обойти ограничение метода Итог() для расчетных данных

Если мы попробуем написать код СсылкаНаОбъект.Товары.Итог("Вес"), платформа выдаст ошибку. Метод Итог() работает только с реально существующими в табличной части числовыми колонками. Поскольку вес и количество мест являются динамически вычисляемыми параметрами, у нас есть два пути решения этой проблемы.

Решение 1. Классический подсчет в цикле (наиболее производительный)

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

Решение 2. Использование промежуточной Таблицы Значений

Если логика вашей печатной формы требует многократной сортировки, группировки или вычисления различных итогов, можно выгрузить табличную часть в объект ТаблицаЗначений, программно добавить туда колонки «Вес» и «КоличествоМест», рассчитать их в цикле, а затем спокойно использовать стандартный метод ТЗ.Итог("Вес").

Пошаговая реализация в коде внешней печатной формы

Рассмотрим подробный пример реализации первого (наиболее надежного и быстрого) варианта непосредственно в модуле вашей внешней печатной формы. Этот код полностью готов к интеграции:


Функция ПечатьДокумента() Экспорт

    ТабличныйДокумент = Новый ТабличныйДокумент;
    ТабличныйДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_РеализацияТоваровУслуг";
    
    // Получаем макет нашей внешней обработки
    МакетОбработки = ПолучитьМакет("Макет");
    
    // Получаем области макета
    ОбластьШапка  = МакетОбработки.ПолучитьОбласть("Шапка");
    ОбластьСтрока = МакетОбработки.ПолучитьОбласть("Строка");
    ОбластьПодвал = МакетОбработки.ПолучитьОбласть("Подвал");
    
    // Заполняем шапку печатной формы
    ОбластьШапка.Параметры.Заполнить(СсылкаНаОбъект);
    ТабличныйДокумент.Вывести(ОбластьШапка);
    
    // Инициализируем переменные для подсчета итогов
    ИтоговыйВес = 0;
    ИтоговоеКоличествоМест = 0;
    
    // Начинаем обход строк табличной части "Товары"
    Для Каждого ТекущаяСтрока Из СсылкаНаОбъект.Товары Цикл
        
        // Очищаем параметры области строки перед заполнением
        ОбластьСтроки.Параметры.Очистить();
        
        // Переносим базовые реквизиты строки (Код, Номенклатура, Количество, Цена, Сумма и т.д.)
        ЗаполнитьЗначенияСвойств(ОбластьСтроки.Параметры, ТекущаяСтрока);
        
        // --- БЛОК РАСЧЕТА ВЕСА ---
        ВесСтроки = 0;
        Если ЗначениеЗаполнено(ТекущаяСтрока.ЕдиницаИзмерения) Тогда
            // Вес единицы измерения умножаем на количество в строке
            ВесСтроки = ТекущаяСтрока.Количество * ТекущаяСтрока.ЕдиницаИзмерения.Вес;
        КонецЕсли;
        
        ОбластьСтроки.Параметры.Вес = ВесСтроки;
        ИтоговыйВес = ИтоговыйВес + ВесСтроки;
        
        // --- БЛОК РАСЧЕТА КОЛИЧЕСТВА МЕСТ ---
        КоличествоМестСтроки = 0;
        Если ЗначениеЗаполнено(ТекущаяСтрока.ЕдиницаМест) Тогда
            
            КоэфОсновной = ?(ЗначениеЗаполнено(ТекущаяСтрока.ЕдиницаИзмерения), ТекущаяСтрока.ЕдиницаИзмерения.Коэффициент, 1);
            КоэфМеста = ТекущаяСтрока.ЕдиницаМест.Коэффициент;
            
            Если КоэфМеста <> 0 Тогда
                КоличествоМестСтроки = (ТекущаяСтрока.Количество * КоэфОсновной) / КоэфМеста;
            КонецЕсли;
            
        КонецЕсли;
        
        ОбластьСтроки.Параметры.КоличествоМест = КоличествоМестСтроки;
        ИтоговоеКоличествоМест = ИтоговоеКоличествоМест + КоличествоМестСтроки;
        
        // Выводим заполненную строку в документ
        ТабличныйДокумент.Вывести(ОбластьСтроки);
        
    КонецЦикла;
    
    // Заполняем параметры подвала накопленными итогами
    ОбластьПодвал.Параметры.ВсегоВес = ИтоговыйВес;
    ОбластьПодвал.Параметры.ВсегоМест = ИтоговоеКоличествоМест;
    
    // Выводим подвал в документ
    ТабличныйДокумент.Вывести(ОбластьПодвал);
    
    Возврат ТабличныйДокумент;

КонецФункции

Особенности кастомизированных конфигураций

При работе с нетиповыми или доработанными конфигурациями «Управление торговлей» необходимо учитывать ряд важных нюансов:

  1. Хранение веса напрямую в Номенклатуре: Иногда программисты при доработке базы упрощают схему данных и добавляют реквизит Вес (или ВесЧислом) непосредственно в справочник Номенклатура. В этом случае код расчета веса изменится и будет выглядеть так:

    ВесСтроки = ТекущаяСтрока.Количество * ТекущаяСтрока.Номенклатура.ВесЧислом;

    Перед началом разработки обязательно загляните в конфигуратор и проверьте, где именно хранится реквизит веса в вашей информационной базе.
  2. Единицы измерения веса: В карточке единицы измерения вес может быть указан в разных величинах (например, в граммах или килограммах). Если у вас в системе часть товаров взвешивается в граммах, а в печатной форме всегда требуются килограммы (или тонны), не забывайте делать соответствующий пересчет в коде (например, делить полученный результат на 1000).
  3. Проверка на нулевые коэффициенты: Обязательно делайте программную проверку деления на ноль. Если пользователь случайно запишет в базу единицу измерения с нулевым коэффициентом, отсутствие проверки вызовет критический сбой системы при попытке сформировать печатную форму.

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

← На главную