Синхронизация данных между конфигурациями 1С:Бухгалтерия (БП) и 1С:Зарплата и управление персоналом (ЗУП) — один из ключевых и в то же время уязвимых процессов в корпоративных информационных системах. В процессе обмена пользователи часто сталкиваются со следующей технической ошибкой:
{ОбщийМодуль.ОбменДаннымиXDTOСервер.Модуль(4614)}: Для уникального идентификатора <...> и узла <...> назначено несколько ссылок.
Эта неполадка полностью блокирует получение данных в принимающей базе. В рамках данной статьи мы подробно разберем, почему возникает эта коллизия, как устроен механизм сопоставления объектов в современных версиях платформ 1С, и пошагово проанализируем процесс ее устранения ручными и программными методами.
Современный обмен данными в 1С (начиная с редакций БП 3.0 и ЗУП 3.1) функционирует на базе технологии EnterpriseData (ED). В отличие от старых правил обмена, работавших через прямое конвертирование данных, формат ED использует промежуточную кодировку и концепцию публичных идентификаторов. За сопоставление объектов в базах-участниках обмена отвечает специальный регистр сведений — «Публичные идентификаторы синхронизируемых объектов».
Суть ошибки заключается в следующем: при загрузке пакета данных система считывает присланный из другой базы уникальный идентификатор (GUID) объекта (например, конкретного банка, контрагента, договора или физического лица). Затем система обращается к указанному регистру, чтобы найти, какому именно элементу в локальной базе соответствует данный GUID. Если в регистре для одного GUID и одного узла обмена система находит две или более разные ссылки, возникает логический конфликт. Платформа не может «решить», какой именно объект обновить, и аварийно завершает сеанс синхронизации.
Рассмотрим основные сценарии, которые приводят к возникновению этой проблемы:
Стоит отметить, почему стандартный совет проверить регистр сведений СоответствияОбъектовИнформационныхБаз часто не дает результатов. Дело в том, что этот регистр использовался в классических обменах по правилам конвертации. В современных конфигурациях сопоставление хранится именно в РегистрСведений.ПубличныеИдентификаторыСинхронизируемыхОбъектов.
Если ошибка носит единичный характер (в тексте ошибки указан один конкретный GUID), проще и быстрее всего устранить ее вручную через встроенные инструменты администрирования. Выполним этот процесс по шагам.
Шаг 1. Переход к функциям для технического специалиста
Для начала нам необходимо открыть список регистров. В главном меню программы (в правом верхнем углу) нажмите на значок меню, перейдите в раздел «Настройки» и выберите пункт «Функции для технического специалиста» (в старых версиях платформы данный пункт назывался «Все функции»). Если этот пункт недоступен, его необходимо включить в настройках параметров системы, предварительно убедившись, что у вашей учетной записи есть права администратора.
Шаг 2. Открытие нужного регистра сведений
В открывшемся дереве объектов найдите раздел «Регистры сведений» и откройте регистр «Публичные идентификаторы синхронизируемых объектов». Перед вами откроется список записей, связывающих уникальные идентификаторы внешних систем с внутренними ссылками текущей базы данных.
Шаг 3. Настройка поиска и отбора
В списке записей регистра воспользуйтесь строкой поиска или настройте отбор:
7700011f-04a9-11e8-a3ba-88d7f6c7e87b).Шаг 4. Анализ результатов поиска и удаление дублей
После применения фильтра вы увидите минимум две строки, содержащие одинаковый уникальный идентификатор. Внимательно проанализируйте колонку «Ссылка»:
После удаления лишней строки закройте регистр и повторно запустите процесс синхронизации данных. Ошибка должна исчезнуть.
В ситуациях, когда база данных подверглась массовой чистке дублей, ручное удаление записей через интерфейс становится слишком трудоемким процессом. В этом случае мы можем автоматизировать поиск и удаление поврежденных записей с помощью программного скрипта. Напишем и разберем код внешней обработки, которая находит все дублирующиеся связи в регистре сведений и устраняет их.
Проанализируем следующий программный код, который можно запустить в консоли кода или оформить в виде внешней обработки:
// Создаем запрос для поиска дублирующихся идентификаторов в разрезе узлов обмена
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПубличныеИдентификаторы.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| ПубличныеИдентификаторы.Идентификатор КАК Идентификатор,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ПубличныеИдентификаторы.Ссылка) КАК КоличествоСсылок
|ПОМЕСТИТЬ ВТ_ДублирующиеИдентификаторы
|ИЗ
| РегистрСведений.ПубличныеИдентификаторыСинхронизируемыхОбъектов КАК ПубличныеИдентификаторы
|ГРУППИРОВАТЬ ПО
| ПубличныеИдентификаторы.УзелИнформационнойБазы,
| ПубличныеИдентификаторы.Идентификатор
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ПубличныеИдентификаторы.Ссылка) > 1
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Рег.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| Рег.Идентификатор КАК Идентификатор,
| Рег.Ссылка КАК Ссылка
|ИЗ
| РегистрСведений.ПубличныеИдентификаторыСинхронизируемыхОбъектов КАК Рег
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ДублирующиеИдентификаторы КАК Дубли
| ПО Рег.УзелИнформационнойБазы = Дубли.УзелИнформационнойБазы
| И Рег.Идентификатор = Дубли.Идентификатор
|УПОРЯДОЧИТЬ ПО
| УзелИнформационнойБазы,
| Идентификатор";
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
ТекущийУзел = Неопределено;
ТекущийИдентификатор = "";
// Переменная для хранения ссылки, которую мы решим оставить
СсылкаДляСохранения = Неопределено;
Пока Выборка.Следующий() Цикл
// Проверяем смену группировки по проблемному идентификатору
Если ТекущийИдентификатор <> Выборка.Идентификатор Или ТекущийУзел <> Выборка.УзелИнформационнойБазы Тогда
ТекущийИдентификатор = Выборка.Идентификатор;
ТекущийУзел = Выборка.УзелИнформационнойБазы;
СсылкаДляСохранения = Выборка.Ссылка;
Продолжить; // Первую ссылку оставляем как эталонную
КонецЕсли;
// Все последующие ссылки для этого же идентификатора признаются дублями и подлежат удалению
НаборЗаписей = РегистрыСведений.ПубличныеИдентификаторыСинхронизируемыхОбъектов.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.УзелИнформационнойБазы.Установить(Выборка.УзелИнформационнойБазы);
НаборЗаписей.Отбор.Идентификатор.Установить(Выборка.Идентификатор);
НаборЗаписей.Отбор.Ссылка.Установить(Выборка.Ссылка);
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() > 0 Тогда
НаборЗаписей.Очистить();
Попытка
НаборЗаписей.Записать();
Сообщить("Успешно удалена дублирующая запись для идентификатора: " + Выборка.Идентификатор + " (Ссылка: " + Выборка.Ссылка + ")");
Исключение
Сообщить("Не удалось удалить запись для идентификатора: " + Выборка.Идентификатор + ". Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Иначе
Сообщить("Дублирующихся записей сопоставления в регистре не обнаружено.");
КонецЕсли;
Рассмотрим логику работы данного алгоритма. Сначала мы строим временную таблицу ВТ_ДублирующиеИдентификаторы, в которую отбираем только те сочетания узлов и внешних GUID, для которых зарегистрировано более одной уникальной ссылки в локальной базе. Затем мы соединяем полученную таблицу с исходным регистром, чтобы получить детальные записи.
В цикле обхода выборки мы анализируем данные. Первая ссылка для каждого уникального сочетания узла и GUID принимается за основную (она остается нетронутой), а все последующие записи удаляются с помощью создания точечного набора записей с установленным отбором по трем измерениям: УзелИнформационнойБазы, Идентификатор и Ссылка. Такой подход гарантирует безопасность и исключает полное удаление связи объекта с внешним источником.
Для того чтобы минимизировать вероятность повторного появления ошибок синхронизации, рекомендуем придерживаться нескольких простых правил при работе с информационными базами:
Подводя итог, можно сказать, что ошибка дублирования ссылок для одного уникального идентификатора легко устраняется как вручную, так и программно. Понимание архитектуры хранения связей обмена EnterpriseData в регистре Публичные идентификаторы синхронизируемых объектов позволяет администраторам 1С оперативно решать подобные проблемы и обеспечивать бесперебойную работу бизнес-процессов предприятия.