При совместной разработке и поддержке распределенных информационных систем 1С специалисты часто сталкиваются с ситуацией, когда две базы (например, рабочая и копия для доработок) изначально создаются копированием одной базы, но со временем начинают вести себя странно при сравнении конфигураций. Сравнение баз может длиться бесконечно долго, хотя визуально конфигурации абсолютно идентичны, а таблица изменений после завершения процесса оказывается пустой.
В таких ситуациях возникает соблазн решить проблему радикально — использовать операцию «Загрузить конфигурацию из файла» (загрузка файла .cf). Однако здесь кроется серьезный страх любого разработчика: не «слетят» ли при этой операции уникальные идентификаторы (GUID) уже существующих в базе объектов? Не приведет ли это к катастрофическому задвоению элементов справочников или документов при последующем обмене данными через обработку ВыгрузкаЗагрузкаДанныхXML? Рассмотрим эти вопросы подробно и разберем глубинные механизмы работы платформы «1С:Предприятие».
Для начала проанализируем архитектурную основу платформы и разделим понятия уникальных идентификаторов, поскольку именно их путаница часто приводит к ошибочным решениям.
---
В среде 1С термин «идентификатор» или «ГУИД» может относиться к совершенно разным сущностям. Выясним разницу между ними:
Справочник.Номенклатура, документ Документ.РеализацияТоваровУслуг, любой их реквизит, табличная часть или даже общий модуль. Эти идентификаторы жестко определяют физическую структуру таблиц базы данных в СУБД (например, имена таблиц вида _Reference15 или полей _Fld123 привязываются именно к этим UUID).Разберем, как эти типы идентификаторов ведут себя при различных операциях обновления и загрузки.
---
Если база-приемник была изначально получена путем копирования базы-источника (файловым копированием, разворачиванием бэкапа СУБД или через выгрузку/загрузку файла .dt), то нет, GUID существующих объектов базы данных (Ref UUID) при загрузке конфигурации из файла не изменятся. На них эта операция никак не влияет.
Стандартная обработка ВыгрузкаЗагрузкаДанныхXML работает исключительно с Ref UUID (идентификаторами ссылочных данных). Метаданные (структура таблиц) ее напрямую не интересуют. Если в обеих базах физические элементы данных имеют одинаковые GUID, то при повторной загрузке никакого задвоения объектов не произойдет — платформа просто перезапишет существующие объекты актуальными данными.
Однако здесь кроется критически важный нюанс, который необходимо проанализировать, чтобы избежать полной потери данных.
---
Почему же опытные специалисты бьют тревогу при использовании функции «Загрузить конфигурацию из файла»? Дело в том, что эта операция выполняет жесткое затирание старой конфигурации и накат новой структуры «один в один» по идентификаторам метаданных (Metadata UUID).
Посмотрим на пример из практики автора темы. Он вручную создал общий модуль в Базе 2, а затем вручную создал точно такой же общий модуль в Базе 1. Поскольку объекты создавались вручную в разных базах, платформа присвоила им разные Metadata UUID, несмотря на идентичные имена и программный код. Поскольку это был общий модуль (который не хранит данные в таблицах СУБД), последующая загрузка .cf-файла прошла успешно и безболезненно. Платформа просто заменила один модуль на другой.
Но что произошло бы, если бы разработчик вручную создал в двух базах справочник или документ?
Если бы UUID метаданных разошлись у объектов, хранящих информацию (например, у справочника Номенклатура), сценарий развивался бы следующим образом:
Номенклатура в загружаемом файле отличается от UUID в текущей базе, платформа воспринимает это как два разных действия: «Удалить старый справочник Номенклатура (так как его UUID нет в файле)» и «Создать новый пустой справочник Номенклатура (так как пришел новый UUID)».Поэтому использовать операцию «Загрузить конфигурацию из файла» можно только в том случае, если вы абсолютно уверены, что UUID всех объектов метаданных, хранящих данные, в обеих базах идентичны. Если есть сомнения, безопаснее использовать режим «Сравнить и объединить с конфигурацией из файла».
---
Выясним причину, по которой конфигуратор тратит минуты или даже десятки минут на сравнение визуально одинаковых конфигураций. Алгоритм сравнения в 1С устроен следующим образом:
Metadata UUID.После того как конфигурация была полностью загружена из файла .cf, UUID метаданных синхронизировались. Именно поэтому при повторном запуске сравнение стало отрабатывать за 5 секунд вместо прежних 6 минут.
---
Для понимания того, как платформа работает со ссылочными данными, полезно уметь программно извлекать и анализировать уникальные идентификаторы объектов. Напишем небольшой пример кода, демонстрирующий получение GUID ссылки:
// Пример получения Уникального Идентификатора (Ref UUID) конкретного элемента
СсылкаНаОбъект = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", "00-000123");
Если Не СсылкаНаОбъект.Пустая() Тогда
// Получаем объект типа УникальныйИдентификатор
УникальныйИдДанных = СсылкаНаОбъект.УникальныйИдентификатор();
// Выводим строковое представление GUID в формате XML (36 символов)
Сообщить("Уникальный идентификатор ссылки (Ref UUID): " + Строка(УникальныйИдДанных));
КонецЕсли;
Этот GUID останется неизменным при любых обновлениях конфигурации, если сама таблица справочника не подверглась полному удалению и пересозданию из-за рассинхронизации метаданных.
---
Если в ваших базах действительно разъехались UUID метаданных у объектов, хранящих информацию (справочники, документы, регистры), прямая загрузка .cf-файла уничтожит данные. Проанализируем безопасные методы решения этой проблемы, используемые профессиональными разработчиками.
Начиная с платформы 8.3, разработчикам доступен мощный инструмент выгрузки конфигурации в текстовые файлы. Разберем этот процесс по шагам:
Если объем данных небольшой, можно воспользоваться классическим приемом обхода ограничений платформы:
Контрагенты переименуйте в Удалить_Контрагенты).Контрагенты с правильным UUID из эталонной конфигурации Базы 1. Примените изменения. У вас в базе образуется две таблицы: старая с данными (под префиксом Удалить_) и новая пустая (с верным UUID).
НовыйЭлемент = Справочники.Контрагенты.СоздатьЭлемент();
// Устанавливаем тот же самый GUID ссылки, который был в старой таблице
НовыйЭлемент.УстановитьСсылкуНового(Справочники.Контрагенты.ПолучитьСсылку(СтарыйGUID));
ЗаполнитьЗначенияСвойств(НовыйЭлемент, СтарыйОбъект);
НовыйЭлемент.Записать();
Удалить_ из конфигурации.Этот метод подходит для небольших и средних по размеру баз данных:
ВыгрузкаЗагрузкаДанныхXML полностью выгрузите все данные проблемных объектов из Базы 2 во внешний файл.Таким образом, мы выяснили, что сама по себе загрузка идентичной конфигурации из файла безопасна для GUID объектов данных, если структуры метаданных изначально были синхронизированы. В противном случае всегда используйте описанные выше профессиональные методики обхода рассинхронизации UUID метаданных.