Как синхронизировать две базы 1С:Управление торговлей 11, если справочники не совпадают и данные дублируются?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При работе с несколькими базами 1С:Управление торговлей 11 (например, при наличии рабочей базы продаж и консолидирующей базы управленческого учета) часто возникает проблема рассинхронизации справочников. Если пользователи создают номенклатуру, контрагентов или валюты параллельно в обеих системах, то при регулярном переносе документов данные начинают «плыть». Появляются многочисленные дубли, ломается аналитика, а ручные исправления превращают поддержку систем в бесконечный рутинный процесс.

В этой статье мы подробно разберем, как решить проблему рассинхронизации справочников раз и навсегда. Мы рассмотрим четыре практических сценария решения: от штатного интерактивного сопоставления до технического подключения существующей базы к РИБ и программного выравнивания уникальных идентификаторов (UUID/УИД) объектов.

Решение 1. Штатное интерактивное сопоставление через регистр «Соответствия объектов информационных баз»

В современных конфигурациях 1С на базе Библиотеки стандартных подсистем (БСП), включая Управление торговлей 11, реализован мощный механизм сопоставления данных. Вся информация о связях между объектами в разных базах хранится в регистре сведений СоответствияОбъектовИнформационныхБаз. Это позволяет связывать объекты с совершенно разными уникальными идентификаторами (GUID), предотвращая появление дублей.

Разберем по шагам, как настроить интерактивный обмен без программирования:

  1. Запуск настройки синхронизации: Перейдем в меню «НСИ и администрирование» — «Синхронизация данных». Создадим новое подключение через универсальный формат EnterpriseData или правила обмена.
  2. Первый запуск обмена: При первом выполнении обмена система автоматически предложит проанализировать данные. Вместо автоматической загрузки, которая гарантированно создаст дубли, выберем пункт «Выполнить сопоставление и загрузку».
  3. Настройка правил сопоставления: В открывшемся окне для каждого справочника (например, Номенклатура, Валюты) настроим поля поиска. По умолчанию 1С ищет объекты по внутреннему идентификатору (УИД). Нам необходимо отключить этот признак для первого обмена и установить сопоставление по реквизитам:
    • Для номенклатуры — по Артикулу, Штрихкоду или сочетанию Наименование + Производитель.
    • Для валют — по Коду (цифровому коду валюты).
    • Для контрагентов — по ИНН и КПП.
  4. Ручное сопоставление несовпавших данных: Объекты, которые система не смогла связать автоматически (например, из-за опечаток в наименовании), сопоставим вручную в интерфейсе табличной части.
  5. Сохранение связей: После завершения сопоставления нажмем кнопку «Записать и продолжить». Система автоматически создаст записи в регистре СоответствияОбъектовИнформационныхБаз. При всех последующих обменах документы будут корректно находить сопоставленные элементы, даже если их УИД в базах различаются.

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


МенеджерЗаписи = РегистрыСведений.СоответствияОбъектовИнформационныхБаз.СоздатьМенеджерЗаписи();
МенеджерЗаписи.УзелИнформационнойБазы = УзелОбмена; // Ссылка на узел плана обмена
МенеджерЗаписи.СобственнаяСсылка = СсылкаВЛокальнойБазе;
МенеджерЗаписи.УникальныйИдентификаторИсточника = СсылкаВЛокальнойБазе.УникальныйИдентификатор();
МенеджерЗаписи.УникальныйИдентификаторПриемника = Новый УникальныйИдентификатор(GUID_В_Центральной_Базе);
МенеджерЗаписи.ТипИсточника = "СправочникСсылка.Номенклатура";
МенеджерЗаписи.ТипПриемника = "СправочникСсылка.Номенклатура";
МенеджерЗаписи.Записать();

Решение 2. Подключение существующей базы к РИБ без потери накопленных данных

Распределенная информационная база (РИБ) — это самый надежный способ поддерживать идентичность справочников «из коробки». В РИБ все изменения справочников, созданные в центральной базе, гарантированно и без искажений переносятся в подчиненные узлы.

Однако стандартный механизм создания РИБ требует генерации начального образа, что полностью затирает базу-приемник. Если в подчиненной базе уже ведется независимый учет и там накоплены документы, затирать ее нельзя. Рассмотрим технический трюк, который позволяет «привязать» уже существующую рабочую базу в качестве подчиненного узла РИБ:

  1. Синхронизация конфигураций: Конфигурации центральной базы (ЦБ) и подчиненной базы (ПБ) должны стать абсолютно идентичными. Выгрузим файл конфигурации (.cf) из ЦБ и загрузим его в ПБ через «Конфигуратор» — «Поддержка» — «Обновить конфигурацию» (или просто «Загрузить конфигурацию из файла»).
  2. Создание узлов в центральной базе: В ЦБ в плане обмена (например, «По Организации» или «Полный») создадим два узла:
    • Узел, соответствующий самой центральной базе (это предопределенный узел, назначим ему код «ЦБ»).
    • Узел для подчиненной базы (назначим код «ПБ»).
  3. «Обман» подчиненной базы: В подчиненной базе нам необходимо программно установить признак того, что у нее есть главный узел. Для этого запустим в ПБ внешнюю обработку со следующим кодом:
    
    УзелГлавный = ПланыОбмена.НайтиПоКоду("ЦБ");
    Если ЗначениеЗаполнено(УзелГлавный) Тогда
        ПланыОбмена.УстановитьГлавныйУзел(УзелГлавный);
        Сообщить("База успешно переведена в режим подчиненного узла РИБ!");
    Иначе
        Сообщить("Узел с кодом ЦБ не найден в планах обмена подчиненной базы!");
    КонецЕсли;
    
  4. Слияние справочников и очистка регистрации: Сразу после установки главного узла базы станут связаны. Однако в них все еще находятся дубли справочников. Нам необходимо запустить встроенную обработку «Поиск и замена дублей» в подчиненной базе, чтобы объединить локальные элементы с элементами, которые прилетели из центрального узла. Перед первым обменом обязательно очистим регистрацию изменений в подчиненной базе, чтобы локальные документы не хлынули лавиной в центральную базу без предварительного контроля.

Решение 3. Использование формата EnterpriseData и расширений для кастомизации поиска

Если жесткие ограничения РИБ (например, запрет на изменение конфигурации в подчиненной базе) нам не подходят, лучшим выбором будет использование универсального формата обмена EnterpriseData. В отличие от старых правил обмена Конвертации данных 2.0, где алгоритмы поиска жестко прописаны внутри правил, в EnterpriseData (на базе Конвертации данных 3.0) логика сопоставления гибко отделена от самой структуры данных.

Проанализируем, как переопределить логику поиска элементов без изменения типовой конфигурации:

Мы можем создать небольшое Расширение конфигурации, в котором переопределим алгоритм сопоставления в общем модуле менеджера обмена. Например, переопределим обработку сопоставления номенклатуры, заставив систему искать объекты исключительно по связке реквизитов Артикул и Производитель, полностью игнорируя проверку по внутреннему УИД при первом поиске.

Для этого в расширении переопределим процедуру сопоставления в модуле МенеджерОбменаЧерезУниверсальныйФормат:


&После("ПриСопоставленииДанных")
Процедура Расш_ПриСопоставленииДанных(ДанныеИмпорта, ПолученныеДанные, СвойстваОчистки, Шла Запись)
    Если ДанныеИмпорта.ТипИмпорта = "СправочникСсылка.Номенклатура" Тогда
        // Наш кастомный алгоритм поиска по артикулу
        АртикулИмпорта = ДанныеИмпорта.Артикул;
        НайденнаяСсылка = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", АртикулИмпорта);
        Если ЗначениеЗаполнено(НайденнаяСсылка) Тогда
            ДанныеИмпорта.СопоставленнаяСсылка = НайденнаяСсылка;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

Решение 4. Физическое выравнивание Уникальных Идентификаторов (GUID)

Если обмен между базами планируется односторонний и долгосрочный, наиболее фундаментальным и изящным решением является приведение УИД (UUID) всех ключевых справочников в подчиненной базе к "общему знаменателю" центральной базы. Когда уникальные идентификаторы объектов в обеих базах станут абсолютно одинаковыми, любые стандартные обмены (даже простые обработки выгрузки/загрузки XML) начнут сопоставлять данные автоматически.

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

  1. Считаем GUID эталонного объекта из центральной базы (например, через COM-соединение, файл выгрузки или Web-сервис).
  2. В подчиненной базе создаем абсолютно новый элемент справочника с требуемым эталонным GUID.
  3. Заполняем реквизиты нового объекта данными из старого локального объекта.
  4. Используем метод платформы НайтиИЗаменитьДубли(), чтобы перенаправлять все ссылки в документах, регистрах и движениях со старого локального элемента на новый эталонный элемент.
  5. Удаляем старый элемент-дубль.

Рассмотрим пример кода, реализующий этот алгоритм для справочника Номенклатура:


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

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

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

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

Выбор конкретного метода зависит от масштаба вашей инфраструктуры и регулярности обменов:

← На главную