В процессе сопровождения и обновления измененных (нетиповых) конфигураций 1С разработчики часто сталкиваются с неприятной ситуацией. При обновлении базы данных через поддержку типовой объект (например, перечисление, справочник или документ) помечается платформой на удаление, а рядом создается точно такой же новый объект. При этом стандартная попытка сопоставить эти объекты вручную в окне сравнения и объединения ни к чему не приводит — исходного (старого) объекта просто нет в списке доступных для сопоставления.
Особенно остро эта проблема проявляется в крупных и тяжелых прикладных решениях, таких как Управление производственным предприятием (УПП) или ERP Управление предприятием, где на исходный объект (например, перечисление ВариантыРасширенногоПервогоНалоговогоПериода) уже завязано множество документов, движений регистров и логики в программном коде. Если выполнить обновление «по умолчанию», мы получим заблокированную базу с «задвоенными» объектами и ошибками целостности метаданных.
В рамках этой статьи мы подробно разберем, почему возникает эта проблема, как устроена внутренняя механика сопоставления объектов платформой 1С:Предприятие, и рассмотрим несколько надежных практических способов ее решения.
Для того чтобы эффективно решить проблему, нам необходимо понять логику работы конфигуратора. При сопоставлении объектов во время обновления платформа опирается на два ключевых фактора:
ВариантыРасширенногоПервогоНалоговогоПериода) вторично. Первичным является уникальный 128-битный идентификатор (UUID), присваиваемый объекту при создании. Если в обновлении поставщика объект был пересоздан (даже с сохранением прежнего имени), его UUID изменился. Для конфигуратора это два абсолютно разных, не связанных друг с другом объекта.Проанализируем ситуацию: чтобы вернуть старый объект в список доступных для сопоставления, нам нужно временно вывести его из-под жесткого контроля механизма поддержки. Рассмотрим подробнее, как это сделать на практике.
Это наиболее простой, быстрый и безопасный способ, не требующий выгрузки метаданных или программирования. Мы локально снимем проблемный объект с поддержки, выполним сопоставление, а затем вернем правила поддержки в исходное состояние.
Разберем этот процесс по шагам:
ВариантыРасширенногоПервогоНалоговогоПериода..cf или .cfu).После успешного завершения обновления объект автоматически вернется на поддержку поставщика с новыми реквизитами и идентификаторами.
Если конфигурация очень большая, работает на сервере и любые манипуляции с интерактивным сопоставлением занимают слишком много времени, опытные разработчики могут решить проблему на уровне исходных кодов метаданных.
Рассмотрим подробнее этот алгоритм:
C:\XML_Active\)..cf) в отдельном окне конфигуратора и аналогичным образом выгрузим его в другую папку (например, C:\XML_Vendor\).C:\XML_Vendor\ найдем XML-файл, описывающий перечисление ВариантыРасширенногоПервогоНалоговогоПериода. Имя файла обычно соответствует внутреннему имени объекта.<uuid>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</uuid>).C:\XML_Active\. Нам нужно заменить старый UUID перечисления на новый скопированный UUID во всех конфигурационных файлах. Обязательно выполним замену в самом файле описания перечисления, а также в служебном файле связей поддержки ConfigDumpInfo.xml. Для этого удобно использовать функцию массового поиска и замены по файлам в текстовом редакторе.Теперь платформа будет считать, что объект в нашей базе и объект в обновлении поставщика имеют абсолютно одинаковый UUID. При последующем запуске обновления сопоставление произойдет автоматически без каких-либо ручных манипуляций.
Посмотрим на ситуацию, когда обновление уже было завершено некорректно: в базе данных появились два одинаковых перечисления (старое, на которое ссылаются существующие документы, и новое пустое от поставщика). Поскольку старое перечисление используется в базе данных, удалить его простым способом в конфигураторе не получится из-за контроля ссылочной целостности.
В этом случае нам поможет стандартная обработка «Поиск и замена дублей» (доступна в составе БСП или на портале ИТС), либо мы можем написать простой программный сценарий для замены ссылок в транзакции.
Проанализируем пример кода для программного поиска и замены ссылок одного значения перечисления на другое:
Процедура ЗаменитьСсылкиНаПеречисление(СтароеЗначение, НовоеЗначение) Экспорт
// Помещаем старое значение в массив для поиска
МассивСтарыхЗначений = Новый Массив;
МассивСтарыхЗначений.Добавить(СтароеЗначение);
// Находим все места использования старого значения в базе данных
ТаблицаСсылок = НайтиПоСсылкам(МассивСтарыхЗначений);
Для Каждого СтрокаТаблицы Из ТаблицаСсылок Цикл
СсылкаНаОбъект = СтрокаТаблицы.Данные;
ОбъектМетаданных = СсылкаНаОбъект.Метаданные();
// Проверяем, что это документ, и мы можем его перезаписать
Если Метаданные.Документы.Содержит(ОбъектМетаданных) Тогда
ДокументОбъект = СсылкаНаОбъект.ПолучитьОбъект();
ИмяРеквизита = СтрокаТаблицы.Метаданные.Имя;
// Заменяем старое значение на новое в найденном реквизите
ДокументОбъект[ИмяРеквизита] = НовоеЗначение;
Попытка
// Записываем документ без проведения для ускорения процесса
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Успешно обработан документ: " + Строка(СсылкаНаОбъект));
Исключение
Предупреждение("Не удалось записать документ: " + Строка(СсылкаНаОбъект) + ". Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
После запуска данного алгоритма все документы и регистры переориентируются на новое перечисление от поставщика. Старое перечисление останется полностью свободным от ссылок, и вы сможете безболезненно удалить его через конфигуратор при следующем сеансе работы.
Чтобы минимизировать появление подобных коллизий при обновлении баз данных 1С в будущем, рекомендуем придерживаться следующих правил:
%userprofile%\AppData\Local\1C\1Cv8 и %userprofile%\AppData\Roaming\1C\1Cv8).