При настройке обмена данными между конфигурациями, такими как ЗУП 3.1 и Документооборот 2.1, одной из наиболее острых проблем является дублирование информации. Особенно это актуально для справочника ФизическиеЛица и связанных с ними записей в регистрах сведений (например, паспортных данных). Рассмотрим подробно, как правильно настроить правила конвертации объектов (ПКО), чтобы система корректно идентифицировала объекты и обновляла существующие записи вместо создания новых.
Самый надежный способ избежать дублей — это синхронизация по Уникальному идентификатору. Если объекты в базе-источнике и базе-приемнике имеют одинаковый GUID, платформа 1С автоматически сопоставит их без дополнительных проверок. В настройках ПКО на закладке "Настройки поиска" необходимо установить флаг "Находить объект по внутреннему идентификатору источника".
Однако стоит помнить, что этот метод работает идеально только в том случае, если база-приемник изначально заполнялась путем загрузки из источника. Если данные в обеих базах вводились вручную, идентификаторы будут разными, и нам потребуется настроить поиск по полям (реквизитам).
Когда поиск по UID не дает результата, в игру вступают Поля поиска. Рассмотрим ситуацию, когда нам нужно найти физическое лицо по косвенным признакам: ИНН, СНИЛС или связке ФИО и даты рождения. Проанализируем, как реализовать гибкий алгоритм поиска в одноименном обработчике ПКО.
Просто отметить галочками поля поиска в интерфейсе КД 2.1 часто недостаточно, так как некоторые поля могут быть не заполнены. Разберем эффективный код, который можно разместить в обработчике Поля поиска:
Если СсылкаНаОбъект.Пустая() Тогда
// Если по УИД объект не найден, начинаем каскадный поиск
Если ЗначениеЗаполнено(СвойстваПоиска["ИНН"]) Тогда
СтрокаИменСвойствПоиска = "ИНН";
ИначеЕсли ЗначениеЗаполнено(СвойстваПоиска["СНИЛС"]) Тогда
СтрокаИменСвойствПоиска = "СНИЛС";
ИначеЕсли ЗначениеЗаполнено(СвойстваПоиска["Наименование"]) И ЗначениеЗаполнено(СвойстваПоиска["ДатаРождения"]) Тогда
СтрокаИменСвойствПоиска = "Наименование, ДатаРождения";
КонецЕсли;
КонецЕсли;
В данном примере мы проверяем наличие заполненных данных. Если ИНН заполнен, поиск будет идти строго по нему. Если нет — проверяем СНИЛС, и в самом крайнем случае используем связку Наименование (ФИО) и ДатаРождения. Это позволяет избежать ситуации, когда система пытается найти человека с пустым ИНН и находит первого попавшегося "пустого" контрагента.
Для более сложных сценариев обмена можно использовать встроенную переменную НомерВариантаПоиска. Это позволяет системе выполнить несколько попыток поиска за один цикл загрузки. Проанализируем следующий пример:
Если НомерВариантаПоиска = 1 Тогда
СтрокаИменСвойствПоиска = "ИНН, Физлицо";
ИначеЕсли НомерВариантаПоиска = 2 Тогда
СтрокаИменСвойствПоиска = "Наименование, ДатаРождения";
Иначе
// Вариант по умолчанию
СтрокаИменСвойствПоиска = "Наименование";
КонецЕсли;
Важно помнить: чем больше вариантов поиска, тем медленнее работает загрузка, так как к базе данных приемника выполняется несколько последовательных запросов. Старайтесь ограничиваться 2-3 наиболее надежными вариантами.
Перейдем к вопросу выгрузки паспортных данных. В конфигурациях на базе 1С 8.3 сведения о документах обычно хранятся в регистре сведений ДокументыФизическихЛиц. Проблема здесь заключается в том, что у регистра нет UID, и поиск возможен только по набору измерений.
Разберем основные правила для предотвращения дублей в регистрах:
Физлицо и ВидДокумента.ВыгрузитьПоПравилу, убедитесь, что вы передаете структуру поиска корректно.Иногда требуется выгрузить данные регистра "на лету" при выгрузке самого физического лица (в обработчике ПослеВыгрузки). Рассмотрим, как сформировать набор записей для выгрузки, чтобы в приемнике сработал механизм замещения:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| *
|ИЗ
| РегистрСведений.ДокументыФизическихЛиц КАК Документы
|ГДЕ
| Документы.Физлицо = &Физлицо";
Запрос.УстановитьПараметр("Физлицо", Источник.Ссылка);
Выборка = Запрос.Выполнить.Выбрать();
Пока Выборка.Следующий() Цикл
// Формируем структуру отбора для поиска в приемнике
Отбор = Новый ТаблицаЗначений;
Отбор.Колонки.Добавить("Имя");
Отбор.Колонки.Добавить("Значение");
Отбор.Колонки.Добавить("Использование");
НоваяСтрока = Отбор.Добавить();
НоваяСтрока.Имя = "Физлицо";
НоваяСтрока.Значение = Выборка.Физлицо;
НоваяСтрока.Использование = Истина;
НоваяСтрока = Отбор.Добавить();
НоваяСтрока.Имя = "ВидДокумента";
НоваяСтрока.Значение = Выборка.ВидДокумента;
НоваяСтрока.Использование = Истина;
// Формируем данные для записи
Строки = Новый ТаблицаЗначений;
// Добавляем все необходимые колонки ресурсов и реквизитов...
НаборЗаписей = Новый Структура("Отбор, Строки");
НаборЗаписей.Отбор = Отбор;
НаборЗаписей.Строки = Строки;
ВыгрузитьРегистр(НаборЗаписей, , , , "ДокументыФизическихЛиц");
КонецЦикла;
Обратите внимание: если вы используете обработку "Универсальный обмен данными в формате XML", метод ВыгрузитьРегистр может быть недоступен в некоторых контекстах. В таком случае рекомендуется использовать стандартное ПКО для регистра и передавать данные через входящие данные или просто настроить ПВД (Правила выгрузки данных) для этого регистра с соответствующим отбором.
Рассмотрим ситуацию, когда дубли уже появились в базе Документооборот. В этом случае никакая настройка правил обмена не поможет их "склеить" автоматически. Выясним последовательность действий для исправления ситуации:
ИНН или СНИЛС.Подведем итог: для качественного обмена без дублей необходимо комбинировать поиск по UID с интеллектуальным поиском в обработчике Поля поиска, всегда проверять заполненность ключевых реквизитов перед сопоставлением и корректно настраивать измерения в правилах для регистров сведений.