Как сопоставить объекты при обновлении конфигурации 1С, если исходного объекта нет в списке?

Программист 1С v8.3 (Обычные формы) Налоговый учет IT и автоматизация бизнеса
← На главную

В процессе сопровождения и обновления измененных (нетиповых) конфигураций 1С разработчики часто сталкиваются с неприятной ситуацией. При обновлении базы данных через поддержку типовой объект (например, перечисление, справочник или документ) помечается платформой на удаление, а рядом создается точно такой же новый объект. При этом стандартная попытка сопоставить эти объекты вручную в окне сравнения и объединения ни к чему не приводит — исходного (старого) объекта просто нет в списке доступных для сопоставления.

Особенно остро эта проблема проявляется в крупных и тяжелых прикладных решениях, таких как Управление производственным предприятием (УПП) или ERP Управление предприятием, где на исходный объект (например, перечисление ВариантыРасширенногоПервогоНалоговогоПериода) уже завязано множество документов, движений регистров и логики в программном коде. Если выполнить обновление «по умолчанию», мы получим заблокированную базу с «задвоенными» объектами и ошибками целостности метаданных.

В рамках этой статьи мы подробно разберем, почему возникает эта проблема, как устроена внутренняя механика сопоставления объектов платформой 1С:Предприятие, и рассмотрим несколько надежных практических способов ее решения.

Выясняем причину: почему платформа «не видит» исходный объект?

Для того чтобы эффективно решить проблему, нам необходимо понять логику работы конфигуратора. При сопоставлении объектов во время обновления платформа опирается на два ключевых фактора:

  1. Внутренний идентификатор (UUID/GUID): Для платформы 1С имя объекта (например, перечисление ВариантыРасширенногоПервогоНалоговогоПериода) вторично. Первичным является уникальный 128-битный идентификатор (UUID), присваиваемый объекту при создании. Если в обновлении поставщика объект был пересоздан (даже с сохранением прежнего имени), его UUID изменился. Для конфигуратора это два абсолютно разных, не связанных друг с другом объекта.
  2. Правила поддержки и блокировка: Главная причина, по которой старый объект отсутствует в списке сопоставления при обновлении — он все еще находится на поддержке (пусть даже с установленным правилом «Редактируется с сохранением поддержки»). Платформа считает его «неприкосновенным» объектом поставщика прежней версии и запрещает связывать с новыми объектами из файла обновления.

Проанализируем ситуацию: чтобы вернуть старый объект в список доступных для сопоставления, нам нужно временно вывести его из-под жесткого контроля механизма поддержки. Рассмотрим подробнее, как это сделать на практике.

Способ 1. Временное изменение правил поддержки для ручного сопоставления

Это наиболее простой, быстрый и безопасный способ, не требующий выгрузки метаданных или программирования. Мы локально снимем проблемный объект с поддержки, выполним сопоставление, а затем вернем правила поддержки в исходное состояние.

Разберем этот процесс по шагам:

  1. Откроем информационную базу в режиме Конфигуратор.
  2. Перейдем в главное меню: Конфигурация — Поддержка — Настройка поддержки...
  3. В открывшемся окне настроек развернем дерево метаданных и найдем наш проблемный объект. В данном случае это перечисление ВариантыРасширенногоПервогоНалоговогоПериода.
  4. Дважды кликнем по правилу поддержки напротив этого объекта. В появившемся окне выбора правил установим вариант «Объект поставщика снят с поддержки». Нажмем кнопку «ОК» и закроем окно настройки поддержки. При этом саму конфигурацию базы данных (БД) обновлять (F7) на данном этапе не требуется.
  5. Запустим процедуру обновления штатным образом через меню: Конфигурация — Поддержка — Обновить конфигурацию... и укажем файл обновления (.cf или .cfu).
  6. В открывшемся окне сравнения и объединения найдем новое перечисление от поставщика (оно будет помечено иконкой создания нового объекта). Кликнем по нему правой кнопкой мыши и выберем пункт «Сопоставить с объектом существующей конфигурации».
  7. Поскольку мы предварительно сняли старое перечисление с поддержки, оно перешло в категорию «собственных» объектов конфигурации. Теперь оно гарантированно появится в списке доступных для сопоставления. Выберем его.
  8. После сопоставления старый UUID нашего перечисления будет заменен на новый UUID из конфигурации поставщика, сохранив при этом все связи и ссылки. Выполним объединение конфигураций и обновим конфигурацию базы данных (F7).

После успешного завершения обновления объект автоматически вернется на поддержку поставщика с новыми реквизитами и идентификаторами.

Способ 2. Корректировка UUID через выгрузку конфигурации в файлы XML

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

Рассмотрим подробнее этот алгоритм:

  1. Выгрузим структуру нашей рабочей конфигурации в файлы XML. Для этого в меню выберем: Конфигурация — Выгрузить конфигурацию в файлы... и укажем пустую локальную папку (например, C:\XML_Active\).
  2. Откроем файл обновления поставщика (.cf) в отдельном окне конфигуратора и аналогичным образом выгрузим его в другую папку (например, C:\XML_Vendor\).
  3. Нам необходимо узнать новый UUID перечисления из обновления. Для этого в папке C:\XML_Vendor\ найдем XML-файл, описывающий перечисление ВариантыРасширенногоПервогоНалоговогоПериода. Имя файла обычно соответствует внутреннему имени объекта.
  4. Откроем этот файл через любой текстовый редактор (например, Notepad++ или VS Code) и скопируем значение его уникального идентификатора (строка вида <uuid>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</uuid>).
  5. Перейдем в папку выгрузки нашей рабочей конфигурации C:\XML_Active\. Нам нужно заменить старый UUID перечисления на новый скопированный UUID во всех конфигурационных файлах. Обязательно выполним замену в самом файле описания перечисления, а также в служебном файле связей поддержки ConfigDumpInfo.xml. Для этого удобно использовать функцию массового поиска и замены по файлам в текстовом редакторе.
  6. После успешной замены загрузим измененные файлы обратно в нашу базу через меню: Конфигурация — Загрузить конфигурацию из файлов...

Теперь платформа будет считать, что объект в нашей базе и объект в обновлении поставщика имеют абсолютно одинаковый UUID. При последующем запуске обновления сопоставление произойдет автоматически без каких-либо ручных манипуляций.

Способ 3. Программное перенаправление ссылок (если обновление уже выполнено «по умолчанию»)

Посмотрим на ситуацию, когда обновление уже было завершено некорректно: в базе данных появились два одинаковых перечисления (старое, на которое ссылаются существующие документы, и новое пустое от поставщика). Поскольку старое перечисление используется в базе данных, удалить его простым способом в конфигураторе не получится из-за контроля ссылочной целостности.

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

Проанализируем пример кода для программного поиска и замены ссылок одного значения перечисления на другое:


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

После запуска данного алгоритма все документы и регистры переориентируются на новое перечисление от поставщика. Старое перечисление останется полностью свободным от ссылок, и вы сможете безболезненно удалить его через конфигуратор при следующем сеансе работы.

Рекомендации по профилактике проблем сопоставления

Чтобы минимизировать появление подобных коллизий при обновлении баз данных 1С в будущем, рекомендуем придерживаться следующих правил:

← На главную