При настройке обмена данными между современными конфигурациями, такими как 1С:ERP Управление предприятием и 1С:Управление производственным предприятием (УПП), разработчики часто сталкиваются с проблемой появления дублей. Казалось бы, правила настроены верно: указаны поля поиска, прописаны алгоритмы, но система упорно создает новый элемент справочника вместо того, чтобы найти существующий по коду. Особенно остро эта проблема проявляется в режиме онлайн-обмена.
В этой статье мы подробно разберем, почему штатные механизмы поиска могут давать сбой, как на это влияет специфика онлайн-обмена и какими программными методами можно гарантировать корректную идентификацию объектов. Рассмотрим ситуацию на примере синхронизации справочника Контрагенты, где поиск должен выполняться по специальному реквизиту КодУпп.
Прежде чем переходить к сложному программированию, проанализируем настройки Правил конвертации объектов (ПКО). Для того чтобы поиск по полям вообще инициировался, необходимо соблюдение нескольких условий в конфигурации Конвертация данных 2.1:
Код), обязательно должна стоять галочка в колонке "Поиск".Если хотя бы одно из этих условий не соблюдено, система либо ограничится поиском по УникальномуИдентификатору (GUID), либо проигнорирует ваши поля поиска, что неизбежно приведет к созданию дублей, если GUID в базах не совпадают.
Часто причина кроется не в программном коде, а в самих данных. Рассмотрим ситуацию: в ERP код контрагента может быть "123", а в УПП — "0000000123". Даже если визуально они похожи, для платформы 1С это разные строки. Проанализируем, как правильно подготовить данные при выгрузке.
Обязательно используем функцию СокрЛП() для обрезки невидимых пробелов. В обработчике "Перед выгрузкой" для ПКС Код (или того реквизита, который мапится в код приемника) следует написать:
Значение = СокрЛП(Источник.КодУпп);
Также важно учитывать длину кода в базе-приемнике. Если в УПП код имеет фиксированную длину с лидирующими нулями, их необходимо добавить программно, иначе стандартный метод поиска НайтиПоКоду или автоматический поиск КД не сработает.
Выясним важный нюанс: онлайн-обмен (через планы обмена и подсистему "Обмен данными") работает иначе, чем ручная загрузка через обработку "Универсальный обмен данными в формате XML".
В режиме онлайн-обмена используется обработка КонвертацияОбъектовИБ. У нее есть критическая особенность: если информация об объекте уже есть в регистре сведений "Соответствия объектов информационных баз", то система вообще не обращается к полям поиска и обработчикам поиска. Она просто берет ссылку из этого регистра. Если же соответствия нет, начинается поиск по ГУИД, и только потом — по полям поиска.
Важный совет: При тестировании правил в онлайн-обмене всегда очищайте записи в регистре "Соответствия объектов информационных баз" для тестируемого объекта в базе-приемнике, иначе вы не увидите работу ваших правок в обработчиках.
Если стандартный поиск не справляется (например, нужно искать по части строки или по сложному условию), мы прибегаем к написанию кода в обработчике "Поля поиска" в ПКО. Рассмотрим пример кода, который решает проблему поиска контрагента по коду, переданному в параметрах, с проверкой существования объекта.
Для начала убедимся, что мы правильно обращаемся к данным. В этом обработчике нам доступны две важные коллекции: СвойстваПоиска (содержит значения реквизитов с галочкой "Поиск") и ПараметрыОбъекта (содержит параметры с флагом "Передавать при поиске").
Проанализируем правильный алгоритм ручного поиска:
// Проверяем номер варианта поиска, чтобы не зацикливать алгоритм
Если НомерВариантаПоиска = 1 Тогда
// Пытаемся получить код для поиска из параметров
КодДляПоиска = "";
Если ПараметрыОбъекта <> Неопределено Тогда
КодДляПоиска = ПараметрыОбъекта.Получить("КодДляПоиска");
КонецЕсли;
Если ЗначениеЗаполнено(КодДляПоиска) Тогда
// Выполняем запрос к базе приемника
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Ссылка
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Код ПОДОБНО &Код";
// Добавляем % для поиска по подстроке, если это необходимо
Запрос.УстановитьПараметр("Код", "%" + СокрЛП(КодДляПоиска) + "%");
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Если Выборка.Следующий() Тогда
// Устанавливаем найденную ссылку
СсылкаНаОбъект = Выборка.Ссылка;
// Сообщаем системе, что поиск успешно завершен
ПрекратитьПоиск = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если вы пытаетесь отладить код через ЗаписьЖурналаРегистрации в обработчике "Поля поиска" и не видите записей, это может означать следующее:
Разберем краткий чек-лист для исправления проблем с поиском в КД 2.1:
СокрЛП и проверяйте соответствие форматов кодов (длина, префиксы).СвойстваПоиска или ПараметрыОбъекта (с включенным флагом передачи).Применяя эти методы, мы сможем добиться стабильной работы обмена данными и избежать утомительной очистки базы от дублирующихся записей.