Часто от пользователей поступает запрос: «Мы хотим, чтобы номер документа выглядел как 0001/2024». На первый взгляд задача кажется простой — достаточно добавить строку с годом к номеру. Однако в системе 1С:Предприятие стандартный механизм автонумерации завязан на строгих алгоритмах. Если их нарушить, нумерация «слетит», начнут появляться дубли или программа перестанет автоматически предлагать следующий номер. В этой статье мы разберем, почему суффиксы (год в конце) — это технически сложное решение, и рассмотрим правильные способы реализации этой задачи.
Давайте проанализируем, как платформа 1С формирует новый номер. Когда вызывается метод УстановитьНовыйНомер(), система выполняет следующие действия:
Рассмотрим ситуацию: вы программно установили номер 0001/2023. При создании следующего документа 1С увидит, что крайнее число справа — это 2023. Она прибавит к нему 1 и выдаст номер 0001/2024. Вместо инкремента порядкового номера система начнет «растить» год. Если же вы добавите в конец букву, например 0001/2023г, автонумерация может вообще остановиться, так как система не сможет однозначно выделить числовую часть для прибавления единицы.
Самый стабильный и простой в поддержке способ — перенести год в начало номера. Например: 2024/00001. В этом случае 2024/ выступает в роли префикса. Платформа будет автоматически находить правую часть (00001), увеличивать её до 00002 и сохранять префикс неизменным.
Проанализируем преимущества такого подхода:
0001/2023 и 0001/2024 могут перемешаться, если сортировка строковая.Для реализации через подписку на событие ПриУстановкеНовогоНомера (если нужно автоматизировать смену года) можно использовать следующий подход:
Процедура ПриУстановкеНовогоНомера(Источник, СтандартнаяОбработка, Префикс)
ТекущийГод = Формат(ТекущаяДата(), "ДФ=yyyy");
Префикс = ТекущийГод + "/";
КонецПроцедуры
Если пользователи настаивают именно на формате Номер/Год, нам придется полностью отказаться от стандартного механизма автонумерации, так как он не умеет работать с суффиксами. В этом случае нам нужно самостоятельно найти последний номер в базе, выделить из него левую часть, увеличить её и приклеить год обратно.
Разберем пример реализации в событии ПередЗаписью документа (или через подписку):
Если Источник.ЭтоНовый() Тогда
// Отключаем стандартную логику, если нужно, или просто пересчитываем
// Нам нужно найти максимальный номер за текущий год
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Док.Номер КАК Номер
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Док
|ГДЕ
| Док.Дата МЕЖДУ &НачалоГода И &КонецГода
|УПОРЯДОЧИТЬ ПО
| Док.Номер УБЫВАЮЩИЕ";
Запрос.УстановитьПараметр("НачалоГода", НачалоГода(Источник.Дата));
Запрос.УстановитьПараметр("КонецГода", КонецГода(Источник.Дата));
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
// Извлекаем число из строки вида "00005/2024"
ПозицияДроби = Найти(Выборка.Номер, "/");
Если ПозицияДроби > 0 Тогда
СтарыйНомерЧислом = Число(Лев(Выборка.Номер, ПозицияДроби - 1));
НовыйПорядковыйНомер = СтарыйНомерЧислом + 1;
Иначе
НовыйПорядковыйНомер = 1;
КонецЕсли;
Иначе
НовыйПорядковыйНомер = 1;
КонецЕсли;
// Формируем строку с ведущими нулями
Суффикс = "/" + Формат(Источник.Дата, "ДФ=yyyy");
Источник.Номер = Пр_ДополнитьСтрокуЛ(Строка(НовыйПорядковыйНомер), 5, "0") + Суффикс;
КонецЕсли;
Важный нюанс: При таком подходе вы должны следить за длиной номера в конфигураторе. Если длина поля Номер — 11 символов, а вы пытаетесь записать 00001/2024 (10 символов), всё поместится. Но если добавится префикс организации (еще 2-3 символа), номер будет обрезан, и логика сломается.
Выясним причину, по которой пользователям нужен год в номере. Чаще всего это поиск в списках или печать. Если это так, то самым «чистым» решением будет оставить системный номер стандартным (например, 000000001), а год добавлять только при выводе на экран или в печатную форму.
Для отображения в списках в управляемых формах можно использовать событие ОбработкаПолученияПредставления в модуле менеджера документа:
Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Год = Формат(Данные.Дата, "ДФ=yyyy");
Представление = "№ " + СокрЛП(Данные.Номер) + "/" + Год + " от " + Формат(Данные.Дата, "ДЛФ=D");
КонецПроцедуры
При таком подходе:
Подведем итоги нашего анализа. Выбор метода зависит от строгости требований:
Номер.Посмотрим еще раз на типичную ошибку новичков: попытка изменить номер в ПриУстановкеНовогоНомера без отключения СтандартнаяОбработка. Помните, что если вы не установите СтандартнаяОбработка = Ложь, платформа применит свои правила поверх ваших, что часто приводит к непредсказуемым результатам в виде пустых номеров или странных символов.