При переходе на платформу 1С:Предприятие со старых плоских систем управления базами данных (например, FoxPro, Access или dBase) начинающие разработчики часто сталкиваются с фундаментальной методологической трудностью. Они пытаются использовать новые для себя объекты конфигурации, такие как Регистры сведений, в качестве обычных таблиц для хранения логов или списков документов. Это неизбежно приводит к ошибкам записи уникальности и концептуальным тупикам при попытке построить складской или производственный учет.
В этой статье мы подробно разберем, почему возникает популярная ошибка уникальности записей в регистре сведений, почему простое отключение периодичности регистра не решает проблему, и как правильно спроектировать архитектуру учета уникального (поштучного) товара на примере драгоценных камней (алмазов), проходящих путь от сырой россыпи до ограненных бриллиантов.
Рассмотрим ситуацию: при проведении документа, фиксирующего приход сырья, система выдает ошибку о невозможности записать данные в регистр сведений. Начинающий разработчик пытается сделать регистр непериодическим, однако ошибка дублирования записей сохраняется. Проанализируем, почему так происходит.
Главное архитектурное назначение объекта РегистрСведений — это хранение разрезов информации в виде "свойство — значение" на определенный момент времени (или без привязки ко времени). Ключевым свойством этого регистра является уникальность записей по набору его измерений.
Набор ключевых полей, определяющих уникальность записи в регистре сведений, формируется следующим образом:
Номенклатура, Качество, Цвет и Сито, то система физически не сможет хранить две записи, у которых все эти четыре поля совпадают.Если в табличной части вашего приходного документа содержатся две разные строки с одинаковым набором характеристик (например, две строки с алмазами одинакового качества, цвета и размера сита, но с разным весом или количеством), при попытке построчно записать их в регистр сведений платформа 1С выдаст ошибку неуникальности. Система считает, что вторая строка пытается перезаписать первую, так как их ключевые поля (измерения) полностью идентичны.
Если вам все же по какой-то причине необходимо записать данные из табличной части документа в регистр сведений, и при этом числовые ресурсы (такие как вес или количество) должны суммироваться по одинаковым строкам, перед записью необходимо программно свернуть таблицу значений.
Разберем по шагам, как это сделать в модуле проведения документа с помощью встроенного языка 1С:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// 1. Устанавливаем признак записи для нашего регистра сведений
Движения.СведенияОСырье.Записывать = Истина;
Движения.СведенияОСырье.Очистить();
// 2. Выгружаем табличную часть документа в коллекцию "ТаблицаЗначений"
ТаблицаДвижений = Товары.Выгрузить();
// 3. Сворачиваем строки, дублирующиеся по ключевым свойствам.
// Первый параметр метода Свернуть() - список измерений (группировка).
// Второй параметр - список суммируемых ресурсов (показателей).
ТаблицаДвижений.Свернуть("Номенклатура, Качество, Цвет, Сито", "Количество, Вес");
// 4. Записываем свернутые данные в регистр сведений
Для Каждого СтрокаТЧ Из ТаблицаДвижений Цикл
НоваяЗапись = Движения.СведенияОСырье.Добавить();
НоваяЗапись.Период = Дата;
НоваяЗапись.Номенклатура = СтрокаТЧ.Номенклатура;
НоваяЗапись.Качество = СтрокаТЧ.Качество;
НоваяЗапись.Цвет = СтрокаТЧ.Цвет;
НоваяЗапись.Сито = СтрокаТЧ.Сито;
// Заполняем ресурсы
НоваяЗапись.Количество = СтрокаТЧ.Количество;
НоваяЗапись.Вес = СтрокаТЧ.Вес;
КонецЦикла;
КонецПроцедуры
Этот метод решает техническую проблему проведения документа без ошибок, однако он концептуально неверен, если мы создаем систему складского или оперативного учета остатков. Для этих целей в платформе 1С существует принципиально другой объект метаданных.
Для отражения движения материальных ценностей (приход, расход, внутреннее перемещение, списание, продажа) необходимо использовать РегистрыНакопления с видом "Остатки".
В отличие от регистров сведений, регистры накопления спроектированы специально для ведения количественного и суммового баланса. Они не перезаписывают записи при совпадении ключевых полей, а увеличивают или уменьшают итоговые остатки на указанную величину. Каждое проведение документа добавляет отдельное движение типа Приход или Расход.
Проанализируем структуру гипотетического регистра накопления для учета сырья на складе:
Номенклатура, Партия (документ прихода, коробка или ящик), Качество, Цвет, Сито.Количество (штуки), ВесВКаратах (вес).Для драгоценных камней крайне важно вести параллельный учет в двух независимых ресурсах — количестве и весе, так как зависимость между ними не является линейной (два камня одинакового размера и качества могут иметь разный вес).
Посмотрим на пример кода проведения приходного документа по регистру накопления остатков:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// Включаем запись движений по регистру накопления "ОстаткиСырья"
Движения.ОстаткиСырья.Записывать = Истина;
Движения.ОстаткиСырья.Очистить();
// Выгружаем и сворачиваем таблицу во избежание избыточности движений в рамках одной транзакции
ТаблицаТоваров = Товары.Выгрузить();
ТаблицаТоваров.Свернуть("Номенклатура, Качество, Цвет, Сито", "Количество, Караты");
Для Каждого СтрокаТЧ Из ТаблицаТоваров Цикл
// Создаем новое движение прихода
Движение = Движения.ОстаткиСырья.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
Движение.Период = Дата;
// Заполняем аналитику (измерения)
Движение.Номенклатура = СтрокаТЧ.Номенклатура;
Движение.Качество = СтрокаТЧ.Качество;
Движение.Цвет = СтрокаТЧ.Цвет;
Движение.Сито = СтрокаТЧ.Сито;
Движение.Партия = Ссылка; // В качестве партии выступает сам документ прихода
// Заполняем показатели (ресурсы)
Движение.Количество = СтрокаТЧ.Количество;
Движение.ВесВКаратах = СтрокаТЧ.Караты;
КонецЦикла;
КонецПроцедуры
В гранильном производстве и ювелирном деле учет часто делится на два принципиально разных этапа: общий (партионный) учет сырья и уникальный (поштучный) учет готовых полуфабрикатов и изделий. Разберем, как правильно реализовать эту логику с использованием двух документов и двух регистров накопления.
Этап 1. Документ "Поступление сырья"
Сырье поступает на завод в ящиках или пакетах (россыпью). Нам пока неизвестны уникальные номера конкретных камней, они хранятся общей кучей.
Мы приходуем их на первый регистр накопления — ОстаткиСырья. В качестве аналитики мы фиксируем только базовые геммологические свойства (цвет, чистота, группа сит) и документ партии.
Этап 2. Документ "Нумерация и разметка"
На этом этапе технолог берет коробку с сырьем, достает из нее камни по одному, оценивает их и присваивает каждому уникальный номер (или штрихкод).
Этот документ должен делать два противоположных движения:
НомерКамня (уникальный серийный номер или штрихкод индивидуального пакета).Регистр накопления УникальныеКамни будет иметь следующую структуру:
НомерКамня (ссылка на справочник или строка с уникальным кодом), Номенклатура, ТекущаяОперация (например: разметка, распиловка, обдирка, огранка).Количество (всегда равно 1 для уникального камня), ВесВКаратах.Использование уникального номера в качестве измерения гарантирует, что мы всегда сможем отследить конкретную физическую единицу на любом этапе производства.
Чтобы не создавать для каждого камня отдельный элемент в справочнике Номенклатура (что быстро приведет к замусориванию базы данных миллионами записей), в 1С рекомендуется использовать встроенный типовой функционал — Серии номенклатуры.
Настроим политику учета серий для вида номенклатуры "Алмазы":
При проектировании систем учета драгоценных камней и металлов на территории РФ крайне важно помнить о законодательном регулировании. Свободный учет "внутренних" номеров без связи с государственным контролем невозможен. Программа должна поддерживать интеграцию с ГИИС ДМДК.
Каждому алмазу массой от 0.3 карата при нумерации и разметке в обязательном порядке присваивается государственный УИН (Уникальный идентификационный номер). Нам необходимо заложить в структуру регистра сведений или в реквизиты серии номенклатуры поле для хранения УИН, получаемого по API из государственной системы маркировки, а также штриховой код для маркировки пакета, в котором перемещается камень.
Подводя итоги, сформулируем краткие правила по работе с регистрами в 1С:
Регистры сведений для ведения количественных остатков товаров или сырья.Регистров накопления.