Как автоматически перезаполнить Таможенную декларацию при изменении Поступления товаров и услуг?

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

В процессе работы в программах 1С:ERP, Комплексная автоматизация или Управление торговлей часто возникает ситуация, когда на основании документа ПоступлениеТоваровУслуг (или ПриобретениеТоваровУслуг) создается ТаможеннаяДекларацияИмпорт. Однако, если после создания декларации пользователь вносит изменения в исходное поступление (меняет количество, номенклатуру или цены), данные в ГТД становятся неактуальными. Разберем подробно, как реализовать механизм автоматического обновления связанной декларации.

Выбор места для реализации логики

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

Для обеспечения надежности системы рассмотрим использование модуля объекта. Нам необходимо подписаться на событие ПриЗаписи или создать подписку на событие для документа-основания. Это гарантирует, что при любом способе записи «Поступления» код поиска и обновления ГТД будет выполнен.

Поиск связанных документов

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

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	ГТДТовары.Ссылка КАК Ссылка
    |ИЗ
    |	Документ.ТаможеннаяДекларацияИмпорт.Товары КАК ГТДТовары
    |ГДЕ
    |	ГТДТовары.ДокументПоступления = &ДокументОснование
    |	И ГТДТовары.Ссылка.Проведен";

Запрос.УстановитьПараметр("ДокументОснование", СсылкаНаПоступление);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Обратите внимание на использование ключевого слова РАЗЛИЧНЫЕ. Поскольку одно и то же поступление может упоминаться в нескольких строках таблицы товаров ГТД, нам нужно получить уникальный список ссылок на документы.

Алгоритм перезаполнения данных

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

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

Проанализируем пример реализации цикла обновления:


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

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

Особенности структуры документа ГТД

Выясним причину, по которой нельзя просто скопировать строки из таблицы Товары одного документа в другой. В документе ТаможеннаяДекларацияИмпорт структура сложнее, чем в обычном поступлении:

Поэтому ручное присваивание значений полям, как предлагалось в сообщении №8 на форуме (ТекСтрока.Номенклатура = Выборка.Номенклатура), является ошибочным путем. Оно не учитывает связи между табличными частями Разделы и Товары. Программисту следует вызывать методы РассчитатьИРаспределитьСборы() или аналогичные функции, заложенные разработчиками конфигурации.

Важные замечания по производительности и транзакциям

Рассмотрим ситуацию, когда в документе «Поступление» 500 строк, и у нас есть 5 зависимых ГТД. Перезаполнение и проведение каждого такого документа — ресурсоемкая операция. Выполняя этот код внутри транзакции записи основного документа, мы рискуем получить блокировки таблиц.

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

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

Заключение

Мы проанализировали задачу синхронизации поступления и ГТД. Основной вывод: вместо написания сложного кода по копированию каждой колонки, старайтесь максимально использовать штатные процедуры заполнения (ЗаполнитьПоОснованию). Это сохранит логическую целостность документа, корректно заполнит счета учета, аналитику и правильно распределит таможенные платежи по разделам декларации.

← На главную