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

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

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

Выясним причину возникновения ошибки

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

  1. Период (для периодических регистров).
  2. Регистратор (ссылка на документ, создавший запись).
  3. Измерения (все поля, для которых в конфигураторе установлен признак «Измерение»).

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

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

Решение 1: Добавление уникального измерения

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

Пошаговый алгоритм реализации:

  1. Перейдем в конфигуратор и откроем структуру нужного регистра сведений.
  2. Добавим новое Измерение с именем НомерСтрокиДокумента (или КлючСвязи).
  3. Установим тип данных Число (длина 10, точность 0) или УникальныйИдентификатор.
  4. В модуле объекта документа, в процедуре ОбработкаПроведения, добавим заполнение этого поля.

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


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

КонецПроцедуры

В данном примере, даже если в документе выбрана одна и та же номенклатура дважды, значение НомерСтрокиДокумента будет разным (например, 1 и 5), что сделает записи уникальными для платформы.

Решение 2: Перенос данных из Измерений в Ресурсы

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

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

Решение 3: Использование Ключа связи (UUID)

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

Рассмотрим, как это работает: В табличную часть документа добавляется скрытый реквизит КлючСвязи с типом УникальныйИдентификатор. При добавлении новой строки в документ генерируется новый GUID. В регистре сведений также создается измерение КлючСвязи с таким же типом. Это гарантирует 100% уникальность записей, даже если все остальные параметры (номенклатура, цена, дата) полностью совпадают.

Технические нюансы режима «По позиции регистратора»

Проанализируем работу системы в режиме подчинения регистратору. Когда мы выполняем проведение документа, 1С автоматически создает НаборЗаписей. Если в этом наборе данных перед вызовом метода Записать() окажутся две строки с одинаковыми измерениями, транзакция будет прервана.

Важные моменты, которые стоит учитывать:

Когда стоит выбрать другой тип регистра?

Если ваша задача подразумевает хранение неограниченного количества одинаковых записей (событий), которые не являются «срезами состояния», возможно, регистр сведений — не лучший выбор. Рассмотрим альтернативы:

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

Таким образом, для исправления ошибки в подчиненном регистре сведений наиболее правильным путем будет добавление измерения «Номер строки» или использование Ключа связи. Это позволит документу хранить любое количество строк с повторяющимися данными, не нарушая механизмов платформы 1С.

← На главную