В процессе эксплуатации систем на базе 1С:Предприятие 8.3 часто возникают задачи, связанные с нестандартным поведением нумератора. Типичный пример — необходимость сбросить номер документа на «единицу» при достижении определенного порога (например, после 9999) или организовать циклическую нумерацию в рамках специфических бизнес-процессов. В данной статье мы подробно разберем, как реализовать подобную задачу в конфигурации 1С:ERP 2.4, проанализируем возможные риски и выберем наиболее оптимальные методы реализации. Для решения подобных проблем без ручной настройки можно применить инструмент для автоматического исправления сбившейся нумерации в 1С:ERP.
Прежде чем приступать к программированию, нам необходимо разобраться, как платформа 1С генерирует номера. Стандартный механизм всегда ищет максимальный номер в заданном периоде (год, квартал, месяц или день) и прибавляет к нему единицу. Если в базе данных уже существует документ с номером 000009999, система автоматически предложит номер 000010000. Простое принудительное присвоение номера 000000001 в коде одного документа не заставит платформу «забыть» о существовании больших номеров. Следующий созданный документ снова попытается получить номер 000010000.
Поэтому наша задача состоит не просто в разовой замене номера, а в переопределении логики поиска следующего свободного значения. Разберем основные способы реализации этой задачи.
Проанализируем наиболее корректный с точки зрения архитектуры 1С метод — использование специализированного обработчика события ПриУстановкеНовогоНомера. Это событие вызывается платформой в тот момент, когда объект запрашивает новый номер. Лучше всего реализовывать эту логику в подписке на событие или через расширение конфигурации, чтобы не снимать документ с поддержки.
Рассмотрим пример кода, который проверяет текущий номер и сбрасывает его, если достигнут предел:
Процедура ПриУстановкеНовогоНомера(Источник, СтандартнаяОбработка, Префикс)
// Если мы хотим полностью управлять процессом, отключаем стандартную обработку
// Однако в данном случае мы можем просто скорректировать результат
// Пример логики: если текущий максимальный номер достиг 9999,
// нам нужно найти возможность начать заново.
// Внимание: прямая установка Номер = "000000001" приведет к ошибке уникальности,
// если документ с таким номером уже есть в этом году.
КонецПроцедуры
Важно помнить: параметр СтандартнаяОбработка при установке в значение Ложь позволяет полностью перехватить управление нумерацией. Однако помните, что вы берете на себя ответственность за проверку уникальности. Если в системе уже есть документ 000000001 за текущий период, попытка записать новый документ с таким же номером вызовет исключение.
Выясним, можно ли решить задачу без написания сложного кода. В конфигураторе у каждого типа документа на вкладке «Нумерация» есть свойство «Периодичность». По умолчанию в ERP для большинства документов установлена периодичность В пределах года. Это означает, что 1 января каждого года нумерация автоматически начинается с единицы.
Если специфика вашего бизнеса требует более частого обнуления (например, каждые 10 000 документов, которые набираются за месяц), рассмотрите возможность смены периодичности на В пределах месяца или В пределах дня. В этом случае платформа сама будет сбрасывать номер в начале каждого нового периода, и вам не придется вмешиваться в программный код. Однако будьте осторожны: это изменит логику для всех документов данного типа в базе.
Разберем ситуацию, когда нам нужно начать нумерацию с единицы, не дожидаясь конца года и не меняя периодичность. Самый надежный способ сделать это в 1С — использовать префиксы. Механизм автонумерации ищет максимальный номер в разрезе префикса.
Допустим, текущие номера имеют вид 000009999. Если мы программно или в настройках организации сменим префикс (например, добавим букву «Б»), то следующий документ с префиксом «Б» получит номер Б00000001, даже если в базе есть документы без префикса с номером 000010000. Рассмотрим, как это можно реализовать через расширение в модуле менеджера или через подписку:
Процедура ПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения)
Если Источник.ЭтоНовый() Тогда
// Проверяем условие для смены префикса
// Например, если количество документов за период превысило порог
Источник.УстановитьНовыйНомер("Б");
КонецЕсли;
КонецПроцедуры
Этот метод исключает конфликты уникальности, так как номера А001 и Б001 являются разными строками для платформы.
Иногда возникают ситуации, когда вы уже удалили документы с большими номерами или изменили их вручную, но 1С продолжает предлагать старый (большой) номер. Это происходит из-за кэширования номеров на стороне сервера приложений для повышения производительности. Если для сброса порядка номеров требуется полностью очистить базу от документов отдельного юрлица, применяется обработка для выборочного удаления данных организации.
Чтобы заставить систему пересчитать последний номер «здесь и сейчас», воспользуемся методом ОбновитьНумерациюОбъектов(). Его можно запустить из внешней обработки для конкретного метаданного:
// Пример для документа "ПриобретениеТоваровУслуг"
МетаданныеОбъекта = Метаданные.Документы.ПриобретениеТоваровУслуг;
ОбновитьНумерациюОбъектов(МетаданныеОбъекта);
Сообщить("Нумерация обновлена. Кэш сброшен.");
Проанализируем ситуацию: этот метод полезен, если «сбой» нумерации произошел из-за случайного ввода номера вручную (например, пользователь случайно ввел 99999, и система подхватила этот порядок). После исправления номера вручную на правильный, вызов этой функции вернет автонумерацию в нужное русло.
Посмотрим на проблему под другим углом. Если требование «сбрасывать номер после 9999» продиктовано исключительно удобством визуального восприятия или требованиями к печатным формам, не рекомендуется ломать стандартный механизм 1С. Нарушение уникальности системных номеров может привести к критическим ошибкам в распределенных базах данных (РИБ) или при обмене с другими системами. Для контроля результата обмена и поиска ошибок в учёте используется автоматическая сверка бухгалтерских и налоговых проводок между базами.
Вместо этого мы можем предложить следующее решение:
Номер как есть (пусть он будет 000010001, 000010002 и т.д.).НомерДляПечати.ПередЗаписью, например для акта сверки взаиморасчетов, реализуем логику заполнения этого реквизита по циклу от 1 до 9999.НомерДляПечати.Такой подход гарантирует техническую стабильность базы данных и при этом полностью удовлетворяет требования бизнес-заказчика к внешнему виду документов.
Проанализировав все варианты, подведем итог по рискам:
000000001, убедитесь, что в текущем периоде (году) такого номера точно нет. В ERP 2.4 проверка уникальности включена по умолчанию, и документ просто не запишется.ПередЗаписью при высокой интенсивности работы пользователей (много транзакций одновременно) может вызвать блокировки таблиц. Метод ПриУстановкеНовогоНомера более предпочтителен.Таким образом, для реализации циклической нумерации лучше всего подходит программная корректировка в событии ПриУстановкеНовогоНомера с использованием префиксации или ведение отдельного счетчика в дополнительном реквизите.