Ошибка "Записи регистра сведений стали неуникальными" при обновлении с 2.0 на 3.0: как исправить и сохранить данные?

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

При переходе с старых редакций конфигураций (например, Бухгалтерия Предприятия 2.0) на новые (редакция 3.0) администраторы и программисты часто сталкиваются с ошибками реструктуризации базы данных. Одной из самых распространенных и неприятных является ошибка: "Записи регистра сведений стали неуникальными". Чаще всего она возникает на регистрах, которые в новой редакции помечены префиксом "Удалить" (например, УдалитьКонтактнаяИнформация, УдалитьСтраховыеВзносыСкидкиКДоходам).

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

Суть проблемы и анализ причин

Давайте разберемся, что происходит в момент обновления. Платформа пытается изменить структуру регистра сведений. В редакции 3.0 многие данные (например, контактная информация) переносятся из регистров сведений в табличные части справочников. Старые регистры переименовываются (добавляется префикс "Удалить") и остаются в системе временно для корректного переноса данных обработчиками обновления.

Ошибка уникальности возникает по следующим причинам:

  1. Изменение состава измерений. В исходной конфигурации (2.0) уникальность записи обеспечивалась набором из трех измерений (например, Объект + Вид + Тип). В целевой конфигурации (3.0) регистр УдалитьКонтактнаяИнформация может иметь более строгий ключ уникальности (например, только Объект + Вид). Если в базе есть записи, различающиеся только полем Тип, для новой структуры они станут полными дублями.
  2. Дублирование предопределенных элементов. Часто в справочнике ВидыКонтактнойИнформации возникают дубли предопределенных элементов, созданные пользователями. При обновлении платформа пытается "свернуть" их, что приводит к появлению дублей записей в регистре.
  3. Ошибки SQL и NULL значения. На уровне СУБД (SQL Server) поля могут содержать значение NULL, которое 1С обрабатывает специфически. При реструктуризации таблицы это может вызвать конфликт.

Автор темы столкнулся с тем, что его скрипт поиска дублей не находил проблем в текущей базе. Давайте посмотрим на код, который использовался, и поймем его ошибку.


// Пример кода автора, который НЕ нашел дубли
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ 
| КонтактнаяИнформация.Объект, 
| КонтактнаяИнформация.Вид 
|ИЗ 
| РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация";
// Далее шел перебор и поиск строк в ТЗ

Почему этот код неэффективен? Он ищет дубли, исходя из текущей структуры данных. Но ошибка возникает при попытке записать эти данные в новую структуру. Чтобы найти реальные дубли, нужно моделировать ограничения уникальности именно целевой конфигурации.

Решение 1: Выгрузка данных и очистка (Самый надежный способ)

Если мы хотим гарантированно сохранить данные (адреса, телефоны контрагентов и сотрудников) и при этом успешно обновиться, лучшим решением будет временное изъятие данных из "проблемного" регистра. Этот метод предложили опытные участники обсуждения.

Рассмотрим алгоритм действий по шагам:

  1. Подготовка инструментов. Нам понадобится обработка ВыгрузкаЗагрузкаДанныхXML (она есть на ИТС или в составе конвертации данных).
  2. Выгрузка данных.
    • Запускаем базу версии 2.0.
    • Открываем обработку выгрузки.
    • Отмечаем галочкой проблемный регистр (например, КонтактнаяИнформация).
    • Выгружаем данные в XML-файл.
  3. Очистка регистра.

    Теперь, когда копия данных у нас есть, мы можем очистить регистр, чтобы он не мешал обновлению. Это можно сделать с помощью обработки "Корректировка записей регистров" или простым кодом:

    
    Набор = РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
    Набор.Записать(); // Записываем пустой набор, удаляя все записи
    
  4. Выполнение обновления конфигурации.

    Запускаем обновление в Конфигураторе. Так как регистр пуст, ошибка уникальности не возникнет. Доходим до этапа принятия изменений.

  5. Загрузка данных обратно.

    Здесь есть нюанс. После обновления конфигурации, но ДО запуска в режиме "Предприятие" (где отрабатывают обработчики переноса данных), нам нужно вернуть данные.

    Для этого можно воспользоваться приемом "заглушки". В модуле обычного приложения (или в общем модуле, отвечающем за обновление, например ОбновлениеИнформационнойБазы) можно временно поставить Возврат в начале процедуры обновления, чтобы база открылась, но обработчики не запустились.

    Либо, как предложил автор темы, использовать встроенную обработку загрузки:

    1. В конфигураторе 3.0 (до первого запуска) внедрить обработку ВыгрузкаЗагрузкаДанныхXML.
    2. В модуле приложения прописать открытие этой обработки при старте системы.
    3. Запустить базу, загрузить XML файл (данные попадут в регистр УдалитьКонтактнаяИнформация, так как имя в файле и в базе будет сопоставлено).
  6. Завершение обновления.

    После загрузки данных убираем "заглушки" и перезапускаем 1С в обычном режиме. Отработают регламентные процедуры перехода на 3.0 (например, ПереносКИПриОбновленииС20), которые корректно разнесут данные из регистра УдалитьКонтактнаяИнформация по табличным частям справочников.

Решение 2: Переименование метаданных (Метод сопоставления)

Существует более изящный метод, который помогает избежать конфликтов сопоставления объектов метаданных. Он основан на том, чтобы явно указать платформе, что наш старый регистр — это и есть тот самый "удаляемый" регистр в новой конфигурации.

Рассмотрим последовательность действий:

  1. В конфигураторе исходной базы (2.0) находим проблемный регистр КонтактнаяИнформация.
  2. Переименовываем его в УдалитьКонтактнаяИнформация (точно так, как он называется в новой конфигурации 3.0).
  3. То же самое делаем для связанных объектов, например, справочник ВидыКонтактнойИнформации переименовываем в УдалитьВидыКонтактнойИнформации.
  4. Сохраняем конфигурацию базы данных.
  5. Запускаем процесс обновления на 3.0.

Почему это работает? При обновлении платформа сопоставляет объекты по внутренним идентификаторам (UUID) и именам. Если имена совпадают, система понимает: "Ага, этот объект не меняется кардинально, мы просто накатываем структуру". Это часто позволяет избежать жесткой конвертации данных, которая вызывает ошибку уникальности.

Решение 3: Радикальная очистка (Если данные не нужны)

Если вы уверены, что данные в конкретном регистре являются "мусором" или служебной информацией, которую можно пересчитать (например, СтраховыеВзносыСкидкиКДоходам, которые актуализируются при расчетах, но не КонтактнаяИнформация!), можно просто удалить содержимое регистра.

Если регистр уже переименован в Удалить... и обновление зависло на этом этапе, удалить данные стандартными средствами 1С может быть невозможно (так как база не запускается). В этом случае поможет прямой SQL-запрос (только для клиент-серверных баз и опытных администраторов):


TRUNCATE TABLE _InfoRegXXXXX 
-- Где _InfoRegXXXXX - имя таблицы соответствующего регистра в базе данных SQL

Важно: Всегда делайте резервную копию перед выполнением SQL-команд. Для файловой базы данный метод неприменим, там можно использовать редакторы dbf/cd (инструменты разработчика), но это рискованно.

Дополнительные рекомендации по диагностике

Если вы хотите найти и устранить причину (конкретные дублирующиеся записи), а не просто обойти проблему, используйте следующий подход:

1. Правильный поиск дублей.
Ищите записи, у которых совпадают ключевые измерения целевой структуры. Для регистра контактной информации чаще всего это пара Объект и Вид. Игнорируйте измерения, которые удаляются в новой версии.


ВЫБРАТЬ
    КИ.Объект,
    КИ.Вид,
    КОЛИЧЕСТВО(*) КАК КоличествоДублей
ИЗ
    РегистрСведений.КонтактнаяИнформация КАК КИ
СГРУППИРОВАТЬ ПО
    КИ.Объект,
    КИ.Вид
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(*) > 1

2. Проверка через "Тестирование и исправление".
Перед обновлением обязательно выполняйте "Тестирование и исправление" (ТИИ) в конфигураторе с галочками "Проверка логической целостности" и "Реструктуризация таблиц". Часто это помогает выявить скрытые проблемы до начала основного процесса обновления.

3. Проверка предопределенных элементов.
Проверьте справочник ВидыКонтактнойИнформации. Если у вас есть два элемента с похожим названием (например, "Телефон рабочий" предопределенный и "Телефон рабочий" созданный пользователем), замените ссылки на созданный элемент ссылками на предопределенный и удалите дубль. Это предотвратит "схлопывание" записей при обновлении.

Заключение

Ошибка уникальности записей при обновлении — это сигнал о том, что данные в старой базе не соответствуют более строгим требованиям новой структуры. Самым безопасным методом решения является выгрузка данных в XML, очистка регистра и последующая загрузка после обновления конфигурации. Это гарантирует, что важная информация (контакты клиентов, сотрудников) не будет потеряна в процессе перехода на редакцию 3.0.

← На главную