Синхронизация данных между конфигурациями «1С:Управление торговлей 11» (УТ) и «1С:Бухгалтерия предприятия 3.0» (БП) — это стандартный процесс для большинства торговых компаний. Однако в процессе эксплуатации пользователи часто сталкиваются с неприятной проблемой: в базах начинают плодиться дубли контрагентов, организаций или их банковских счетов. Обычное удаление дублирующихся элементов стандартными средствами не всегда решает проблему окончательно — при следующем сеансе обмена они могут появиться снова.
В этой статье мы подробно разберем причины возникновения этой проблемы, изучим внутренние механизмы сопоставления объектов в платформе «1С:Предприятие 8.3» и пошагово пройдем процесс исправления и предотвращения дублирования данных.
Современный обмен между УТ 11 и БП 3 построен на использовании универсального формата обмена EnterpriseData. При первой отправке данных система пытается автоматически сопоставить объекты в двух базах по определенным полям поиска (правилам сопоставления). Если автоматическое сопоставление не находит однозначного соответствия, создается новый объект, что и приводит к появлению дублей. Рассмотрим, почему это происходит наиболее часто:
ИНН + КПП для юридических лиц или по ИНН для физических лиц и индивидуальных предпринимателей. Если в одной базе КПП заполнен, а в другой нет (или заполнен с ошибкой), система посчитает этих контрагентов разными и создаст дублирующий элемент. Если ИНН отсутствует в обеих базах, сопоставление идет по наименованию. Любое несовпадение (лишний пробел, разница в кавычках или регистре букв) гарантированно приведет к задвоению.БанковскиеСчетаКонтактов (или аналогичные подчиненные справочники) жестко привязан к владельцу — контрагенту или организации. Если задвоился сам контрагент, то все его банковские счета будут созданы повторно для нового дубля контрагента. Даже если владельцы сопоставлены корректно, банковские счета сопоставляются по связке БИК банка и НомерСчета. Ошибка хотя бы в одной цифре приведет к созданию нового счета.Для того чтобы объекты «узнавали» друг друга при повторных обменах, платформа хранит связи между их уникальными идентификаторами в специальных регистрах сведений. В зависимости от версии конфигураций и используемой технологии обмена это могут быть разные регистры:
РегистрСведений.СоответствияОбъектовИнформационныхБаз — использовался в классических обменах на основе правил конвертации данных (КД 2.0). Он до сих пор активен во многих обменах, например, между ЗУП 3.1 и БП 3.0.РегистрСведений.ПубличныеИдентификаторыСинхронизируемыхОбъектов — современный регистр, который используется в обменах по формату EnterpriseData (включая связку УТ 11.4 и БП 3.0).Рассмотрим подробнее регистр ПубличныеИдентификаторыСинхронизируемыхОбъектов. В нем хранятся записи, связывающие ссылку на объект в текущей базе с уникальным идентификатором этого же объекта в базе-источнике через узел обмена. Если в этом регистре для одного объекта создано несколько некорректных записей или присутствуют «битые» ссылки, обмен будет постоянно сбоить или создавать дубли.
Для быстрого перехода к этому регистру в любой из баз мы можем воспользоваться меню «Перейти по ссылке» (сочетание клавиш Shift + F11) и вставить следующий адрес:
e1cib/list/РегистрСведений.ПубличныеИдентификаторыСинхронизируемыхОбъектов
Проанализируем ситуацию: если мы просто удалим дублирующий элемент справочника с помощью стандартной обработки, запись в регистре сведений может остаться и указывать на несуществующий объект (отображается как <Объект не найден...>). При следующем обмене это может вызвать ошибку:
«Для уникального идентификатора и узла назначен более чем один объект...» или обмен просто создаст дубль заново.
Для того чтобы корректно и навсегда устранить задвоение объектов, выполним последовательно следующие шаги. Настоятельно рекомендуем делать это в периоды отсутствия активной работы пользователей и обязательно создать резервные копии обеих баз перед началом процедур. При работе с несколькими базами для автоматического создания их архивных копий перед проведением технических процедур применяется программа для автоматического архивирования и обслуживания 1С.
Прежде чем запускать слияние дублей, нам необходимо разорвать неверные связи обмена. Перейдем в базу, где обнаружены дубли (например, в БП 3.0), и откроем регистр сведений ПубличныеИдентификаторыСинхронизируемыхОбъектов через «Переход по ссылке».
В списке записей настроим отбор по колонке «Объект» или визуально найдем записи, которые ведут на дублирующийся (неправильный) элемент справочника Контрагенты или БанковскиеСчета. Также обратим внимание на записи с битыми ссылками (<Объект не найден>). Выделим эти записи и удалим их из регистра.
Теперь, когда неверные связи в регистре удалены, мы можем безопасно объединить дубли в самой информационной базе. Для этого воспользуемся типовым инструментом:
Контрагенты (или Банковские счета).Чтобы изменения успешно передались во вторую информационную базу (УТ 11) и связали там правильный объект, нам нужно принудительно зарегистрировать измененные карточки к отправке:
Контрагенты.Запустим процесс обмена данными. После завершения цикла выгрузки-загрузки в обеих базах ссылки синхронизируются. Поскольку старая неверная связь в регистре публичных идентификаторов была удалена, а измененный объект был принудительно зарегистрирован к отправке, система создаст правильную единую запись сопоставления.
Для того чтобы не бороться с последствиями, мы можем контролировать процесс сопоставления непосредственно во время выполнения обмена. Для этого используется режим интерактивной синхронизации.
Рассмотрим, как запустить этот режим по шагам:
Контрагенты. Откроется форма сопоставления.Если дублей скопилось слишком много, ручная очистка регистра может занять много времени. Рассмотрим пример кода на встроенном языке 1С, который позволяет программно найти и удалить записи в регистре ПубличныеИдентификаторыСинхронизируемыхОбъектов, ссылающиеся на помеченные на удаление или «битые» ссылки объектов справочника контрагентов.
Проанализируем следующий алгоритм:
// Создаем запрос для поиска записей регистра с "битыми" или удаляемыми объектами
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПубличныеИдентификаторы.Идентификатор КАК Идентификатор,
| ПубличныеИдентификаторы.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| ПубличныеИдентификаторы.Ссылка КАК Ссылка
|ИЗ
| РегистрСведений.ПубличныеИдентификаторыСинхронизируемыхОбъектов КАК ПубличныеИдентификаторы
|ГДЕ
| (ПубличныеИдентификаторы.Ссылка.ПометкаУдаления = ИСТИНА
| ИЛИ ПубличныеИдентификаторы.Ссылка.Ссылка ЕСТЬ NULL)
| И ПубличныеИдентификаторы.Ссылка ССЫЛКА Справочник.Контрагенты";
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Записываем набор записей с отбором для удаления конкретной строки
НаборЗаписей = РегистрыСведений.ПубличныеИдентификаторыСинхронизируемыхОбъектов.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Идентификатор.Установить(ВыборкаДетальныеЗаписи.Идентификатор);
НаборЗаписей.Отбор.УзелИнформационнойБазы.Установить(ВыборкаДетальныеЗаписи.УзелИнформационнойБазы);
// Пробуем записать пустой набор, что эквивалентно удалению записи
Попытка
НаборЗаписей.Записать();
Сообщить("Успешно удалено сопоставление для ссылки: " + ВыборкаДетальныеЗаписи.Ссылка);
Исключение
Сообщить("Ошибка удаления записи регистра: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Этот код выбирает из базы сопоставления для тех контрагентов, которые либо помечены на удаление, либо уже физически удалены из базы (значение NULL при проверке реквизитов ссылки). После выполнения такой обработки можно смело запускать стандартный поиск и удаление дублей — конфликтов при последующей синхронизации не возникнет. Для этой задачи также можно использовать инструмент аудита базы с нечетким поиском дублей и безопасной заменой ссылок.
Для того чтобы навсегда минимизировать вероятность появления дублей при обмене УТ 11 и БП 3, рекомендуем придерживаться нескольких простых правил организации совместной работы в базах: