Как передать реквизит документа для поиска контрагента по альтернативному ИНН в 1С:Конвертация данных 2

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

При настройке правил обмена в «1С:Конвертация данных 2» (КД 2) часто возникает классическая задача: необходимо сопоставить объект справочника в базе-приемнике не по его собственным ключевым полям, а по реквизиту документа-владельца. Рассмотрим конкретный пример: из базы-источника выгружается документ, в котором есть стандартный реквизит Контрагент и дополнительный реквизит ИННБух (введенный пользователями для особых взаиморасчетов). Задача состоит в том, чтобы при поиске контрагента в базе-приемнике использовать значение ИННБух из документа, если оно заполнено, и стандартный ИНН контрагента в противном случае.

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

Разберем детально три различных способа реализации этой задачи, начиная от самого простого и заканчивая профессиональным и наиболее гибким методом.

Способ 1. Временная подмена значения ИНН при выгрузке (Простой метод)

Этот метод основан на прямой подмене значения выгружаемого ИНН контрагента в XML-файле. Мы берем значение ИННБух из документа и передаем его «под видом» обычного ИНН контрагента в ПКО «Контрагенты». База-приемник при чтении файла автоматически выполнит поиск по этому значению, так как ИНН отмечен как поле поиска.

Проанализируем пошагово, как это настроить в КД 2:

  1. Откроем Правило Конвертации Свойств (ПКС) для реквизита Контрагент в ПКО нашего документа.
  2. Перейдем в обработчик события «Перед выгрузкой» этого ПКС и напишем код для инициализации структуры исходящих данных:

Если ЗначениеЗаполнено(Источник.ИННБух) Тогда
    ИсходящиеДанные = Новый Структура("ИНН", Источник.ИННБух);
КонецЕсли;

Этот код создает структуру ИсходящиеДанные, которая будет автоматически передана в ПКО «Контрагенты» и станет там доступна через переменную ВходящиеДанные.

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

Если ВходящиеДанные <> Неопределено И ВходящиеДанные.Свойство("ИНН") Тогда
    Значение = ВходящиеДанные.ИНН;
КонецЕсли;

Как работает эта схема: Если в документе реквизит ИННБух заполнен, программа помещает его в специальный контейнер передачи данных. При выгрузке контрагента ПКС считывает это значение и подменяет стандартный ИНН контрагента на ИННБух. В результате в файл выгрузки запишется контрагент, у которого в поле ИНН будет находиться значение ИННБух. Приемник найдет контрагента по этому значению.

Важное предупреждение: У этого способа есть серьезный недостаток. Если контрагент с таким ИНН не будет найден в базе-приемнике, КД 2 создаст нового контрагента и запишет ему в поле ИНН значение ИННБух. Если это нежелательно и вам необходимо сохранить оригинальный ИНН контрагента при создании, используйте Способ 2.

Способ 2. Использование параметров объекта и переопределение «Полей поиска» (Рекомендуемый метод)

Этот способ является более гибким и профессиональным. Он позволяет передать альтернативный ИНН как дополнительный параметр, выполнить по нему поиск в приемнике, но при этом сохранить оригинальный ИНН контрагента в файле выгрузки на случай, если объект придется создавать с нуля.

Разберем этот алгоритм по шагам:

  1. В ПКО «Контрагенты» перейдем на вкладку «Параметры» и добавим новый параметр с именем ИННДляПоиска (тип — Строка).
  2. В ПКО документа в ПКС для реквизита Контрагент в обработчике события «Перед выгрузкой» передадим значение во входящие данные:

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

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

Как работает эта схема: В файл выгрузки записывается контрагент со своим реальным ИНН, но к нему «прикрепляется» параметр ИННДляПоиска, содержащий ИННБух. При загрузке в приемнике перед поиском отрабатывает наш скрипт. Он проверяет наличие параметра, и если он заполнен, временно подставляет его в структуру СвойстваПоиска вместо оригинального ИНН. Поиск происходит по ИННБух. Если объект не найден, платформа создаст нового контрагента, но запишет в него его настоящий ИНН, который пришел в стандартных свойствах файла.

Способ 3. Поиск через запрос в обработчике «Поля поиска» (Максимальная гибкость)

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

Рассмотрим реализацию такой логики в обработчике «Поля поиска» ПКО «Контрагенты»:


// По умолчанию инициализируем флаг поиска
ПрекратитьПоиск = Ложь;

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

// Если по альтернативному ИНН ничего не найдено, КД 2 автоматически продолжит стандартный поиск 
// по полям поиска, определенным в ПКС (например, по обычному ИНН контрагента),
// так как переменная ПрекратитьПоиск осталась равной Ложь.

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

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

Правильное использование переменных ИсходящиеДанные, ВходящиеДанные и параметров объектов в сочетании с обработчиком Поля поиска позволяет разработчику 1С реализовать практически любую, даже самую неординарную логику синхронизации бизнес-данных между различными конфигурациями.

← На главную