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

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

При переходе на платформу 1С:Предприятие со старых плоских систем управления базами данных (например, FoxPro, Access или dBase) начинающие разработчики часто сталкиваются с фундаментальной методологической трудностью. Они пытаются использовать новые для себя объекты конфигурации, такие как Регистры сведений, в качестве обычных таблиц для хранения логов или списков документов. Это неизбежно приводит к ошибкам записи уникальности и концептуальным тупикам при попытке построить складской или производственный учет.

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

Выясняем причину: почему регистр сведений выдает ошибку уникальности?

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

Главное архитектурное назначение объекта РегистрСведений — это хранение разрезов информации в виде "свойство — значение" на определенный момент времени (или без привязки ко времени). Ключевым свойством этого регистра является уникальность записей по набору его измерений.

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

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

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

Решение №1: Свертывание таблицы перед записью (технический костыль)

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

Разберем по шагам, как это сделать в модуле проведения документа с помощью встроенного языка 1С:


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

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

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

Решение №2: Переход на Регистры накопления (Архитектурно правильный подход)

Для отражения движения материальных ценностей (приход, расход, внутреннее перемещение, списание, продажа) необходимо использовать РегистрыНакопления с видом "Остатки".

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

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

Для драгоценных камней крайне важно вести параллельный учет в двух независимых ресурсах — количестве и весе, так как зависимость между ними не является линейной (два камня одинакового размера и качества могут иметь разный вес).

Посмотрим на пример кода проведения приходного документа по регистру накопления остатков:


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

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

Проектируем двухэтапную систему поштучного учета алмазов

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

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

Этап 2. Документ "Нумерация и разметка"
На этом этапе технолог берет коробку с сырьем, достает из нее камни по одному, оценивает их и присваивает каждому уникальный номер (или штрихкод). Этот документ должен делать два противоположных движения:

  1. Расход по регистру "ОстаткиСырья": списывает необходимое количество безымянных камней определенной характеристики из конкретной партии (коробки).
  2. Приход по регистру "УникальныеКамни": приходует каждый камень на поштучный учет с заполнением измерения НомерКамня (уникальный серийный номер или штрихкод индивидуального пакета).

Регистр накопления УникальныеКамни будет иметь следующую структуру:

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

Рекомендация: Использование механизма серий номенклатуры

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

Настроим политику учета серий для вида номенклатуры "Алмазы":

Интеграция с государственными системами (ГИИС ДМДК)

При проектировании систем учета драгоценных камней и металлов на территории РФ крайне важно помнить о законодательном регулировании. Свободный учет "внутренних" номеров без связи с государственным контролем невозможен. Программа должна поддерживать интеграцию с ГИИС ДМДК.

Каждому алмазу массой от 0.3 карата при нумерации и разметке в обязательном порядке присваивается государственный УИН (Уникальный идентификационный номер). Нам необходимо заложить в структуру регистра сведений или в реквизиты серии номенклатуры поле для хранения УИН, получаемого по API из государственной системы маркировки, а также штриховой код для маркировки пакета, в котором перемещается камень.

Резюме для разработчика

Подводя итоги, сформулируем краткие правила по работе с регистрами в 1С:

← На главную