Почему возникает ошибка «Запись уже существует» в регистре сведений и как правильно настроить уникальность данных?

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

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

Суть проблемы и анализ структуры данных

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

  1. Объект (СправочникСсылка.Объекты) — Измерение
  2. КомплектЧертежей (СправочникСсылка.КомплектыЧертежей) — Измерение
  3. ПереченьСогласований (СправочникСсылка.ПереченьСогласований) — Ресурс
  4. ДатаНачала (Дата) — Ресурс
  5. ДатаОкончания (Дата) — Ресурс

Проанализируем логику: разработчик хочет, чтобы для одного «Объекта» и одного «Комплекта» можно было добавить несколько «Согласований». Однако при попытке записи второго согласования система выдает ошибку. Выясним причину: в 1С уникальность записи в непериодическом регистре определяется исключительно набором значений его измерений. Этот набор называется Ключом записи.

В текущей структуре ключом является комбинация Объект + КомплектЧертежей. Если в базе уже есть запись для «Объекта А» и «Комплекта 1», то любая новая попытка записать данные по этим же координатам (даже с другим согласованием в ресурсах) будет восприниматься системой как попытка изменить существующую строку, а не создать новую. Если же запись производится через МенеджерЗаписи с установленным признаком обмена или специфическими методами набора, платформа выдаст ошибку неуникальности.

Решение №1: Перенос поля в измерения

Самый простой и логичный способ решить проблему — сделать поле ПереченьСогласований измерением. Разберем, как изменится ситуация:

Теперь ключ записи будет состоять из трех полей: Объект + КомплектЧертежей + ПереченьСогласований. Это позволит нам хранить в регистре следующие строки:

Важно: этот метод подходит, если для одного комплекта одно и то же согласование не может повторяться дважды. Если же вам нужно хранить историю повторных согласований одного и того же типа, этот метод потребует дополнительного измерения (например, НомерПопытки или ДатаНачала в измерениях).

Решение №2: Использование периодичности

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

В периодическом регистре к ключу записи (измерениям) автоматически добавляется поле Период. Это позволяет хранить одинаковые комбинации Объект + КомплектЧертежей, но на разные даты. Однако стоит помнить:

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

Решение №3: Нормализация данных (Разделение регистров)

Рассмотрим более сложный, но архитектурно правильный подход при больших объемах данных. Хранение «Объекта» в каждой строке согласования может привести к избыточности. Проанализируем вариант разделения на два регистра:

Регистр №1: Состав комплектов объектов

Регистр №2: Ход согласований

Такой подход позволяет избежать дублирования информации об объекте в каждой строке согласования. Объект «привязан» к комплекту один раз в первом регистре, а во втором мы работаем только с комплектами и их согласованиями.

Технические нюансы настройки измерений

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

Свойство «Ведущее»
Если вы установите флаг Ведущее у измерения КомплектЧертежей, то при удалении карточки комплекта из справочника, все записи в регистре, связанные с этим комплектом, будут удалены автоматически. Это критически важно для поддержания ссылочной целостности базы данных.

Использование Реквизитов регистра
Помните, что помимо Измерений и Ресурсов в регистре есть Реквизиты. В чем разница?

Пример программной записи в регистр

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


НоваяЗапись = РегистрыСведений.СогласованияЧертежей.СоздатьМенеджерЗаписи();
НоваяЗапись.Объект = ВыбранныйОбъект;
НоваяЗапись.КомплектЧертежей = ВыбранныйКомплект;
НоваяЗапись.ПереченьСогласований = ТекущееСогласование;

// Устанавливаем ресурсы
НоваяЗапись.ДатаНачала = ТекущаяДата();
НоваяЗапись.ДатаОкончания = КонецДня(ТекущаяДата());

// Метод Записать(Истина) перезапишет ресурсы, если ключ совпадет.
// Метод Записать(Ложь) выдаст ошибку при совпадении ключа.
Попытка
    НоваяЗапись.Записать(Ложь);
Исключение
    Сообщить("Такое согласование для этого комплекта уже зарегистрировано!");
КонецПопытки;

Выводы

Выясним причину ошибки: платформа 1С блокирует запись, если в регистре уже существует строка с идентичным набором Измерений. Резюмируем наши действия для решения проблемы:

  1. Проверьте, все ли поля, определяющие уникальность строки, являются измерениями.
  2. Если нужно хранить несколько «Согласований» для одной пары «Объект + Комплект», поле «Согласование» обязано быть измерением.
  3. Используйте свойство Ведущее для основных разрезов учета, чтобы избежать появления «битых ссылок».
  4. Рассмотрите возможность разделения регистра, если данные становятся слишком избыточными.
← На главную