При разработке конфигураций на платформе 1С программисты часто сталкиваются с задачей реализации периодической нумерации. Если для документов этот механизм является стандартным и настраивается в свойствах объекта (периодичность нумерации в пределах года, месяца и т.д.), то для справочников такая возможность «из коробки» отсутствует. По умолчанию нумерация справочников в 1С является сквозной за все время ведения учета.
В этой статье мы разберем, как заставить систему сбрасывать номер справочника в начале каждого нового года, рассмотрим использование префиксов, программные методы установки кода и архитектурные подходы, используемые в типовых конфигурациях.
Это самый простой и эффективный способ, использующий стандартный механизм платформы. Платформа 1С при генерации нового кода ищет максимальное числовое значение среди элементов, имеющих одинаковый текстовый префикс. Если в начале года префикс изменится, система не найдет старых кодов с таким префиксом и автоматически начнет отсчет с единицы.
Рассмотрим, как реализовать это в модуле объекта справочника или через подписку на событие ПриУстановкеНовогоКода. Нам необходимо динамически формировать префикс, включающий текущий год.
Проанализируем пример кода для подписки на событие:
Процедура ПриУстановкеНовогоКодаСправочника(Источник, СтандартнаяОбработка, Префикс) Экспорт
// Формируем префикс вида "2024-"
ГодПрефикса = Формат(ТекущаяДата(), "ДФ=yyyy");
// Добавляем пользовательский префикс, если он нужен (например, "ДГ-")
Префикс = "ДГ" + ГодПрефикса + "-";
КонецПроцедуры
Выясним, как это работает на практике. Когда пользователь создает новый элемент в 2023 году, префикс будет ДГ2023-. Номер будет выглядеть как ДГ2023-00001. Как только наступит 1 января 2024 года, префикс изменится на ДГ2024-. Платформа выполнит поиск максимального кода, начинающегося на ДГ2024-, не найдет ни одной записи и предложит номер 00001. Таким образом, мы получаем «сброс» нумерации без дополнительных усилий по хранению счетчиков.
Если вы работаете в современной типовой конфигурации (например, 1С:ERP, 1С:УТ 11 или 1С:Бухгалтерия 3.0), рекомендуется использовать встроенную подсистему «Префиксация объектов». Это более гибкий инструмент, который позволяет централизованно управлять префиксами организаций, подразделений и информационных баз.
Разберем алгоритм работы с БСП по шагам:
УстановитьПрефиксКодаСправочника (название может варьироваться в зависимости от версии БСП).ПрефиксацияОбъектовСобытия.УстановитьПрефикс.ПрефиксацияОбъектовПереопределяемый, добавив в формирование префикса текущую дату.Важный нюанс: Платформа 1С воспринимает строку префикса целиком. Если длина кода справочника составляет 10 символов, а ваш префикс (включая год и разделители) занимает 7 символов, то под сам номер остается всего 3 знака (максимум 999). Обязательно контролируйте длину реквизита Код в метаданных справочника, чтобы номер не «заткнулся» при достижении лимита.
Иногда бизнес-требования запрещают использование года в строке кода или требуют сложной логики (например, отдельная нумерация для разных видов договоров в одном справочнике). В этом случае стандартный механизм префиксов не подходит, так как он проверяет уникальность кода по всему справочнику.
Проанализируем ситуацию: нам нужно, чтобы код в 2024 году был просто 1, но при этом в базе уже есть код 1 за 2023 год. Платформа выдаст ошибку неуникальности. В такой ситуации опытные разработчики рекомендуют оставить стандартный Код для системных нужд, а для пользователя создать отдельный реквизит Номер (строка или число).
Для реализации собственного нумератора нам понадобится непериодический Регистр Сведений (например, НумерацияДоговоров) со следующей структурой:
Год (Число), ВидДоговора (СправочникСсылка).ПоследнийНомер (Число).Рассмотрим пример функции получения нового номера в транзакции:
Функция ПолучитьСледующийНомер(ТекущийГод, ТипОбъекта)
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.НумерацияДоговоров");
ЭлементБлокировки.УстановитьЗначение("Год", ТекущийГод);
ЭлементБлокировки.Заблокировать();
Менеджер = РегистрыСведений.НумерацияДоговоров.СоздатьМенеджерЗаписи();
Менеджер.Год = ТекущийГод;
Менеджер.Прочитать();
Если Менеджер.Выбран() Тогда
НовыйНомер = Менеджер.ПоследнийНомер + 1;
Иначе
НовыйНомер = 1;
Менеджер.Год = ТекущийГод;
КонецЕсли;
Менеджер.ПоследнийНомер = НовыйНомер;
Менеджер.Записать();
Возврат НовыйНомер;
КонецФункции
Эту функцию следует вызывать в событии ПередЗаписью объекта. Использование БлокировкаДанных критически важно: оно гарантирует, что если два пользователя одновременно нажмут кнопку «Записать», они не получат один и тот же номер.
Выясним, какой метод выбрать для вашей задачи:
2024-0001).УстановитьНовыйКод() резервирует номер при открытии формы. Если пользователь закроет форму без сохранения, номер пропадет. В этом случае используйте программное присвоение номера в событии ПередЗаписью (внутри транзакции).1 может повторяться у разных контрагентов. Но для ежегодного сброса это не поможет — тут все равно нужен либо префикс с годом, либо свой реквизит.НомерДоговора, а системный Код скрыть с формы.Подведем итог: Для реализации нумерации в пределах года в справочнике 1С оптимальным является путь модификации префикса. Это позволяет сохранить высокую производительность системы и использовать встроенную оптимизацию СУБД для поиска свободных номеров. В более сложных бизнес-сценариях следует переходить к использованию регистров-нумераторов и дополнительных реквизитов.