Как настроить регистр сведений в 1С для контроля уникальности номера и литера в пределах года?

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

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

Разбор причины ошибки при создании записей

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

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

Правильная настройка структуры регистра сведений

Чтобы встроенный механизм 1С автоматически отслеживал уникальность значений в течение года, разберем по шагам правильный алгоритм настройки регистра сведений в конфигураторе:

  1. Настройка периодичности: Укажем у регистра сведений свойство Периодичность в значение В пределах года. При такой настройке платформа автоматически приводить значение стандартного реквизита Период к началу года (01 января 00:00:00) для любой создаваемой записи.
  2. Отказ от лишних измерений даты: Не создаем пользовательские реквизиты и измерения типа Дата. Для отслеживания времени в периодических регистрах используется исключительно реквизит Период.
  3. Добавление состава измерений: В состав измерений добавляем только нужные разрезы учета:
    • Номер (тип Строка ограниченной длины);
    • Литер (тип ПеречислениеСсылка...).

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

Особенности режима записи регистра: независимый или подчиненный

Рассмотрим важную техническую деталь работы платформы 1С при выборе режима записи:

1. Независимый регистр сведений: Первичный ключ СУБД состоит из полей Период и всех составных измерений. Платформа 1С гарантирует контроль уникальности комбинации измерений между совершенно разными документами на уровне базы данных.

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

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

Альтернативное решение: Программная проверка в документе

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

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |	Док.Ссылка КАК Ссылка
    |ИЗ
    |	Документ.ПриходнаяНакладная КАК Док
    |ГДЕ
    |	Док.Дата МЕЖДУ &НачалоГода И &КонецГода
    |	И Док.Номер = &Номер
    |	И Док.Литер = &Литер
    |	И Док.Ссылка <> &Ссылка";

Запрос.УстановитьПараметр("НачалоГода", НачалоГода(ПроводимыйДокумент.Дата));
Запрос.УстановитьПараметр("КонецГода", КонецГода(ПроводимыйДокумент.Дата));
Запрос.УстановитьПараметр("Номер", СокрЛП(ПроводимыйДокумент.Номер));
Запрос.УстановитьПараметр("Литер", ПроводимыйДокумент.Литер);
Запрос.УстановитьПараметр("Ссылка", ПроводимыйДокумент.Ссылка);

РезультатЗапроса = Запрос.Выполнить();

Если НЕ РезультатЗапроса.Пустой() Тогда
    ВызватьИсключение "Документ с таким номером и литером уже зарегистрирован в текущем году!";
КонецЕсли;

Для предотвращения обхода проверки из-за случайных пробелов или разного регистра букв рекомендуется всегда нормализовать текстовые поля перед проверкой и записью с помощью функций СокрЛП() и ВРЕГ().

← На главную