Как исключить создание конкретного контрагента по условию в 1С:Конвертация данных 2.1?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При переносе данных между базами 1С с помощью конфигурации «1С:Конвертация данных 2.1» (КД 2.1) разработчики часто сталкиваются со специфическими задачами фильтрации. Одна из классических проблем: требуется сделать так, чтобы определенный контрагент (например, предопределенный, служебный или ошибочно созданный в источнике) ни при каких условиях не переносился и не создавался в базе-приемнике. При этом глобальный флаг «Не создавать новый объект в приемнике, если он не найден» в ПКО (Правила конвертации объектов) использовать нельзя, так как все остальные контрагенты должны создаваться в штатном режиме.

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


В чем заключается скрытая опасность простого отказа от выгрузки?

Рассмотрим стандартную логику работы XML-выгрузки. Допустим, мы пишем условие отказа в ПКО Контрагенты. Если мы просто укажем Отказ = Истина, система действительно не запишет подробные реквизиты контрагента (наименование, ИНН, КПП) в файл выгрузки. Однако, если этот контрагент выбран в каком-либо документе (например, в накладной «Реализация товаров и услуг»), который переносится в этом же сеансе, произойдет следующее:

  1. При обработке документа правила выгрузки увидят ссылку на нашего «запрещенного» контрагента.
  2. В XML-файл запишется узел ссылки (УИД объекта источника) для того, чтобы в приемнике документ мог связаться с контрагентом.
  3. При загрузке в базу-приемник XML-парсер считает документ и попытается найти контрагента по УИД.
  4. Поскольку контрагент в базе-приемнике отсутствует, а глобальный флаг запрета создания в ПКО снят, система автоматически создаст пустой элемент справочника. В базе появится «битый» контрагент с пустым наименованием и ИНН, но с заполненным УИД.

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


Способ №1: Программное управление флагом «Не создавать, если не найден» (Рекомендуемый способ)

Этот способ является наиболее изящным и правильным с точки зрения архитектуры КД 2.1. Вместо того чтобы полностью блокировать выгрузку, мы можем программно указать платформе: «Именно этого контрагента создавать в приемнике нельзя, если поиск не дал результатов».

Для этого мы воспользуемся обработчиком события «Перед выгрузкой» в ПКО Контрагенты. В этом обработчике нам доступен специальный параметр НеСоздаватьЕслиНеНайден.

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


// Обработчик события "Перед выгрузкой" ПКО Контрагенты
// Проверяем объект по ключевому реквизиту (например, Наименованию или ИНН)

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

Как это работает: При выгрузке контрагента в XML-файл добавится специальный служебный атрибут НеСоздаватьЕслиНеНайден="true". При загрузке файла в базу-приемник модуль обмена попытается найти контрагента по полям поиска. Если объект не будет найден, система просто пропустит его создание. В документах, ссылающихся на него, поле контрагента останется пустым (или будет содержать пустую ссылку), но новые элементы-пустышки создаваться не будут.


Способ №2: Подмена объекта на стороне источника

Если бизнес-логика вашего переноса подразумевает, что вместо «запрещенного» контрагента документы должны проводиться по какому-то другому, реально существующему контрагенту (например, «Розничный покупатель» или «Служебный контрагент»), то лучшим решением будет динамическая подмена объекта непосредственно в момент выгрузки.

Этот код мы также пишем в обработчике «Перед выгрузкой» ПКО Контрагенты:


// Обработчик события "Перед выгрузкой" ПКО Контрагенты

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

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


Способ №3: Отмена записи объекта на стороне приемника

Иногда решение о том, нужно ли создавать объект, невозможно принять на стороне источника (например, если логика завязана на данные, которые присутствуют только в базе-приемнике). В этом случае мы можем заблокировать создание объекта непосредственно при загрузке.

Для этого перейдем в ПКО Контрагенты и откроем обработчик события «После загрузки». Обратите внимание: использовать нужно именно «После загрузки», а не «Перед загрузкой», так как нам важно знать статус поиска объекта.

Проанализируем пример кода:


// Обработчик события "После загрузки" ПКО Контрагенты
// Параметр "ОбъектНайден" указывает, существовал ли объект в базе до загрузки

Если Не ОбъектНайден И Объект.Наименование = "Нежелательный Контрагент" Тогда
    
    // Устанавливаем Отказ в Истина, чтобы предотвратить запись нового объекта в базу
    Отказ = Истина;
    Сообщить("Создание нового контрагента " + Объект.Наименование + " заблокировано на стороне приемника.");
    
КонецЕсли;

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


Резюме и рекомендации

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

← На главную