Как исправить ошибку с неуникальными записями регистра сведений при обновлении 1С

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

При обновлении конфигураций 1С на очередную версию разработчики иногда сталкиваются с ошибкой реструктуризации базы данных: «Записи регистра не уникальны». Процесс реструктуризации при этом аварийно прерывается, и платформа не позволяет завершить сохранение конфигурации базы данных. Чаще всего это происходит с непериодическими или независимыми регистрами сведений, такими как ЦеныНоменклатурыДокументов. Разберем по шагам, почему возникает эта ошибка и как восстановить работоспособность базы без безвозвратной потери накопленных данных.

Выясним причину нарушения уникальности

Механизм реструктуризации в платформе 1С переносит существующие данные во временную таблицу новой структуры и затем создает уникальный индекс по ключевым полям (период плюс измерения). Если в исходных данных после приведения к новой структуре образуются две или более строки с одинаковым набором ключевых полей, СУБД возвращает ошибку нарушения уникальности, и транзакция отменяется.

Проанализируем основные причины, приводящие к появлению дублей:

  1. Пропуск промежуточных запусков в режиме «1С:Предприятие»: очень часто разработчики обновляют базу через несколько релизов подряд исключительно через конфигуратор. При этом в промежуточных релизах поставщик часто включает специальные обработчики обновления Библиотеки стандартных подсистем (БСП), которые плавно преобразуют, сжимают или переносят данные. Если не запустить базу в пользовательском режиме между релизами и не дождаться окончания процедур БСП, то следующий релиз, удаляющий лишние поля или меняющий тип, застанет исходные «сырые» данные врасплох.
  2. Изменение периодичности регистра: если в регистре была установлена периодичность По позиции регистратора или регистр был непериодическим, а разработчики перевели его на периодичность День или Месяц, все записи, созданные внутри одного дня, склеиваются по ключу периода.
  3. Удаление или смена типа одного из измерений: если из состава измерений регистра исключается разрез (или измерение превращается в обычный реквизит), записи, которые раньше отличались только этим полем, становятся абсолютно идентичными с точки зрения уникального индекса.
  4. «Битые» ссылки и объекты, помеченные на удаление: если ссылки в измерениях превратились в «Объект не найден», либо при сужении составного типа превращаются в пустое значение, платформа формирует несколько записей с одинаковыми пустыми ключами.

Способ 1. Пошаговое обновление с выполнением процедур БСП

Если обновление выполнялось сразу через релиз (например, переход через 2–3 версии за один раз), наиболее правильный путь — вернуться на шаг назад:

  1. Восстановим информационную базу из резервной копии до проблемного обновления.
  2. Применим обновление только на один промежуточный релиз.
  3. Обязательно запустим базу в режиме «1С:Предприятие» от имени администратора.
  4. Дождемся полного окончания фоновых и регламентных заданий обновления (раздел Администрирование — Обслуживание — Результаты обновления программы).
  5. Только после того, как все обработчики БСП успешно отработают, перейдем к обновлению на следующий релиз.

Способ 2. Поиск и свертка дублей запросом до применения обновления

Если обновление выполняется строго по инструкции, но ошибка все равно возникает, локализуем дублирующиеся строки запросом. Выясним, какие измерения регистра остаются в новом релизе, и выполним запрос к проблемной таблице еще до применения реструктуризации.

Посмотрим на пример запроса для поиска коллизий:


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

После выявления записей, которые образуют дубли, напишем простую внешнюю обработку, которая очистит дубликаты, оставив только актуальные данные. Для независимого регистра сведений удаление и перезапись осуществляются через объект РегистрСведенийНаборЗаписей:


Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Набор = РегистрыСведений.ЦеныНоменклатурыДокументов.СоздатьНаборЗаписей();
    Набор.Отбор.Номенклатура.Установить(Выборка.Номенклатура);
    Набор.Отбор.Характеристика.Установить(Выборка.Характеристика);
    
    // Считываем текущие дублирующиеся записи
    Набор.Прочитать();
    
    Если Набор.Количество() > 1 Тогда
        // Оставляем только последнюю актуальную запись
        Пока Набор.Количество() > 1 Цикл
            Набор.Удалить(0);
        КонецЦикла;
        Набор.Записать(Истина);
    КонецЕсли;
КонецЦикла;

Способ 3. Выгрузка во внешний файл и постобработка

Если записей слишком много, либо структура кардинально перерабатывается поставщиком, воспользуемся проверенным сценарием с выгрузкой данных во внешнее хранилище:

  1. Развернем копию базы до обновления.
  2. С помощью типовой обработки «Выгрузка и загрузка данных XML» или через правила обмена «Конвертация данных» выгрузим проблемный регистр сведений в файл. В правилах выборки данных можно сразу предусмотреть группировку, отсекающую дубликаты.
  3. В рабочей базе полностью очистим проблемный регистр перед реструктуризацией. Поскольку регистр ЦеныНоменклатурыДокументов является независимым и вспомогательным (кэширующим), его очистка не нарушит целостность финансовых или складских проводок.
  4. Успешно применим обновление конфигурации в конфигураторе.
  5. Загрузим сохраненные данные обратно. При загрузке наборы записей будут сформированы в соответствии с новой структурой, а дубли перезапишутся корректно.

Почему не стоит добавлять свое измерение

Иногда возникает соблазн «обмануть» платформу: добавить в регистр сведений еще одно измерение с уникальным идентификатором (например, типа УникальныйИдентификатор или Число), чтобы все записи формально стали уникальными. Делать этого категорически не рекомендуется по следующим причинам:

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