Как правильно заполнить и пересчитать табличную часть документа Реализация товаров и услуг в 1С:Бухгалтерия 3.0?

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

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

Выясним причину такого поведения платформы и разберем правильные архитектурные подходы к автозаполнению и пересчету табличных частей типовых документов в конфигурации «1С:Бухгалтерия предприятия 3.0».

Почему простое копирование строк не заполняет зависимые реквизиты

В управляемом интерфейсе 1С при программном добавлении строк в коллекцию формы события элементов формы (такие как ТоварыНоменклатураПриИзменении) намеренно не вызываются платформой. Попытка открыть форму через ПолучитьФорму, перенести туда данные через КопироватьДанныеФормы и вручную вызывать клиентские обработчики приводит к усложнению кода, переносу множества зависимых процедур во внешнюю обработку и нестабильной работе интерфейса.

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

Способ 1. Серверное создание документа и заполнение через типовые общие модули

Для внешних обработок с видом «Создание связанных объектов» стандартом разработки 1С является выполнение операции на стороне сервера с типом команды ВызовСерверногоМетода. В этом случае мы создаем документ в серверном контексте, заполняем его реквизиты, применяем специализированные методы конфигурации и записываем объект.

Разберем по шагам реализацию этого механизма в модуле объекта внешней обработки:

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

Посмотрим на пример кода серверной процедуры:


Процедура ВыполнитьКоманду(ИдентификаторКоманды, МассивОбъектов, СозданныеОбъекты) Экспорт

    Для Каждого СсылкаОснование Из МассивОбъектов Цикл
        
        НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
        НовыйДокумент.Дата = ТекущаяДатаСеанса();
        НовыйДокумент.Организация = СсылкаОснование.Организация;
        НовыйДокумент.Склад = СсылкаОснование.Склад;
        НовыйДокумент.ДокументОснование = СсылкаОснование;
        
        // Переносим номенклатурный состав
        Для Каждого СтрПродукция Из СсылкаОснование.Продукция Цикл
            НоваяСтрока = НовыйДокумент.Товары.Добавить();
            НоваяСтрока.Номенклатура = СтрПродукция.Номенклатура;
            НоваяСтрока.Количество = СтрПродукция.Количество;
            НоваяСтрока.Коэффициент = 1;
            
            // Заполнение счетов учета номенклатуры и доходов/расходов по правилам БП 3.0
            СчетаУчетаВДокументах.ЗаполнитьСчетаУчетаВСтрокеТабЧасти(НовыйДокумент, НоваяСтрока, "Товары");
            
            // Расчет сумм и НДС при наличии цен
            ОбработкаТабличныхЧастейКлиентСервер.РассчитатьСуммуТабЧасти(НоваяСтрока, НовыйДокумент);
            ОбработкаТабличныхЧастейКлиентСервер.РассчитатьСуммуНДСТабЧасти(НоваяСтрока, НовыйДокумент);
        КонецЦикла;
        
        // Пакетное заполнение счетов учета для всей табличной части (альтернативный вызов)
        СчетаУчетаВДокументах.ЗаполнитьСчетаУчетаВТабличнойЧасти(НовыйДокумент, "Товары");
        
        НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
        СозданныеОбъекты.Добавить(НовыйДокумент.Ссылка);
        
    КонецЦикла;

КонецПроцедуры

Способ 2. Интерактивное открытие формы с передачей структуры заполнения

Если логика бизнес-процесса требует не сразу сохранять документ в базу, а открыть готовую, но незаписанную форму для ручной проверки и редактирования пользователем, используется метод ОткрытьФорму с параметром ЗначенияЗаполнения.

Проанализируем ситуацию: платформа 1С при передаче структуры в параметре ЗначенияЗаполнения автоматически запускает обработчик ОбработкаЗаполнения в модуле объекта и инициализирует форму по всем правилам конфигурации. Для этого не нужно использовать устаревший метод ПолучитьФорму.

Разберем пример реализации на клиенте:


&НаКлиенте
Процедура СоздатьРеализациюИнтерактивно(СсылкаОснование)

    ДанныеЗаполнения = СформироватьДанныеЗаполненияНаСервере(СсылкаОснование);
    
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("ЗначенияЗаполнения", ДанныеЗаполнения);
    
    ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыОткрытия);

КонецПроцедуры

&НаСервере
Функция СформироватьДанныеЗаполненияНаСервере(СсылкаОснование)

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

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

Способ 3. Переопределение логики ввода на основании в расширении конфигурации

Если есть возможность использовать механизм расширений, наиболее чистым решением будет добавление логики связки документов непосредственно в типовую процедуру ОбработкаЗаполнения модуля объекта документа РеализацияТоваровУслуг.

В этом случае типовой документ сам научится заполняться на основании ОтчетПроизводстваЗаСмену, команда создания станет доступна в стандартном подменю «Создать на основании», а все счета учета и суммы будут рассчитаны штатными процедурами конфигурации.

Пример кода метода в модуле объекта через аннотацию &Вместо или &После:


&После("ОбработкаЗаполнения")
Процедура Расш_ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)

    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ОтчетПроизводстваЗаСмену") Тогда
        
        Организация = ДанныеЗаполнения.Организация;
        Склад = ДанныеЗаполнения.Склад;
        ДокументОснование = ДанныеЗаполнения;
        
        Для Каждого Стр Из ДанныеЗаполнения.Продукция Цикл
            НоваяСтрока = Товары.Добавить();
            НоваяСтрока.Номенклатура = Стр.Номенклатура;
            НоваяСтрока.Количество = Стр.Количество;
            НоваяСтрока.Коэффициент = 1;
        КонецЦикла;
        
        // Вызов штатного заполнения счетов БП 3.0
        СчетаУчетаВДокументах.ЗаполнитьСчетаУчетаВТабличнойЧасти(ЭтотОбъект, "Товары");
        
    КонецЕсли;

КонецПроцедуры

Сводные рекомендации

  1. Избегайте ручного переноса клиентских процедур формы (ТоварыНоменклатураПриИзменении) во внешние обработки.
  2. Всегда производите манипуляции с данными на сервере, используя типовые методы модуля СчетаУчетаВДокументах для автоматического определения счетов БУ (41, 43, 90.01, 90.02) по регистру сведений «Счета учета номенклатуры».
  3. Для расчета сумм и НДС применяйте экспортные методы общего модуля ОбработкаТабличныхЧастейКлиентСервер.
← На главную