При обмене данными между двумя, казалось бы, идентичными конфигурациями 1С через формат XML часто возникает неприятная ситуация: документы и записи регистров переносятся, но вместо ссылок на справочники (например, на «Основной склад» или «Статью ДДС») в базе-приемнике мы видим надпись «Объект не найден». При этом сами предопределенные элементы в обеих базах существуют и называются одинаково.
В этой статье мы разберем природу возникновения «битых ссылок» при переносе предопределенных данных, выясним, почему стандартные механизмы могут давать сбой, и изучим пошаговые алгоритмы решения этой проблемы с использованием различных инструментов платформы 1С:Предприятие 8.3.
Прежде всего, нам необходимо понять, как платформа 1С работает с предопределенными данными. Предопределенный элемент — это объект, описание которого заложено в конфигураторе, но сам экземпляр создается в информационной базе. Основная сложность заключается в том, что в разных базах у одного и того же предопределенного элемента могут быть разные Уникальные Идентификаторы (UUID/GUID).
Проанализируем типичные ситуации, когда это происходит:
Стандартная обработка ВыгрузкаЗагрузкаДанныхXML при переносе ищет объект именно по УИД. Если в приемнике УИД другой, система считает, что объекта не существует, и в документе появляется «битая ссылка».
Самый простой и эффективный способ, который упоминается опытными разработчиками, — это использование модифицированной обработки ВыгрузкаЗагрузкаXML.epf. Рассмотрим подробнее, где ее взять и как она работает.
Нам потребуется обработка из комплекта поставки конфигурации «Конвертация данных 2.1» (рекомендуемая версия 2.1.8.2 и выше). В отличие от типовой обработки, входящей в состав БСП или ИТС, версия из состава КД обладает важной особенностью: при выгрузке она анализирует, является ли объект предопределенным.
Если объект предопределенный, в XML-файл записывается не только его УИД, но и его Имя предопределенного (строковое имя из конфигуратора). При загрузке в базу-приемник обработка действует по следующему алгоритму:
Иногда нам требуется более тонкий контроль над тем, как база-приемник создает или сопоставляет предопределенные элементы. Разберем инструменты, которые предоставляет платформа для управления этим процессом.
Посмотрим на свойство конфигурации ОбновлениеПредопределенныхДанных. У каждого справочника, плана видов характеристик или плана счетов есть это свойство. Оно может принимать значения:
Если мы хотим жестко синхронизировать базы, имеет смысл в базе-приемнике установить значение «Не обновлять». В этом случае мы сможем перенести предопределенные элементы из «эталонной» базы-источника как обычные данные, сохранив их УИДы. Для этого в коде загрузки или в специализированной обработке можно использовать метод:
// Отключаем автоматическое создание предопределенных данных для конкретного справочника
УстановитьОбновлениеПредопределенныхДанныхИнформационнойБазы(Метаданные.Справочники.Склады, ОбновлениеПредопределенныхДанных.НеОбновлять);
После этого, при загрузке данных через XML, система не будет конфликтовать с уже существующими (или еще не созданными) элементами, и позволит записать объекты с УИДами из источника.
Если «битые ссылки» уже возникли, или мы хотим заставить платформу сопоставить существующие объекты с метаданными, рассмотрим метод СинхронизироватьПредопределенныеДанные(). Этот метод позволяет программно запустить процесс связки объектов в базе с описанием в конфигураторе.
Проанализируем ситуацию: в базе есть элемент, который должен быть предопределенным, но связь потеряна (или УИД не совпадает с тем, что ожидает конфигурация). Мы можем выполнить следующий код:
Процедура СинхронизироватьДанные()
// Метод выполняет сопоставление данных для всех типов метаданных
СинхронизироватьПредопределенныеДанные();
КонецПроцедуры
Однако стоит помнить, что этот метод не всегда исправляет ссылки в документах, если объекты уже «размножились». В таких случаях потребуется ручное «лечение» базы.
Если обмен уже прошел и база заполнена объектами вида <Объект не найден>, простого изменения настроек обмена будет недостаточно. Разберем шаги по исправлению ситуации:
Пример кода для программного создания объекта с конкретным УИД, если его еще нет в базе:
НовыйУИД = Новый УникальныйИдентификатор("здесь-ваш-uuid-из-источника");
СсылкаНаОбъект = Справочники.Склады.ПолучитьСсылку(НовыйУИД);
Если СсылкаНаОбъект.ПолучитьОбъект() = Неопределено Тогда
НовыйОбъект = Справочники.Склады.СоздатьЭлемент();
НовыйОбъект.УстановитьСсылкуНового(СсылкаНаОбъект);
НовыйОбъект.Наименование = "Основной склад (синхронизированный)";
НовыйОбъект.ИмяПредопределенныхДанных = "ОсновнойСклад";
НовыйОбъект.Записать();
КонецЕсли;
Подводя итог, проанализируем лучшие практики для предотвращения подобных проблем в будущем:
Во-первых, если базы однотипные, старайтесь создавать их через механизм РИБ. Это гарантирует 100% совпадение всех идентификаторов метаданных и данных «из коробки».
Во-вторых, если использование РИБ невозможно, рассмотрите переход на формат EnterpriseData. В современных конфигурациях 1С (УТ 11, ERP 2, БП 3.0) этот формат по умолчанию использует синхронизацию предопределенных данных по их строковым именам, что делает обмен гораздо более устойчивым к различиям в УИДах.
В-третьих, всегда проверяйте версию обработки ВыгрузкаЗагрузкаДанныхXML. Как мы выяснили, версия из состава КД 2.1 является наиболее интеллектуальной при работе с предопределенными значениями.
Соблюдение этих правил позволит вам избежать трудоемкой работы по ручному исправлению ссылок и обеспечит целостность данных в ваших информационных системах.