При программном создании документов или интеграции со сторонними системами часто возникает необходимость сформировать номер по специфическому алгоритму без интерактивного участия пользователя. Например, требуется включить в номер код организации, текущий год и месяц либо переопределить префиксацию для определенного списка документов. Разберем по шагам, как правильно управлять нумерацией из встроенного языка 1С, какие механизмы платформы для этого предназначены и каких грубых ошибок следует избегать.
Самым простым и правильным способом генерации очередного номера является вызов платформенного метода УстановитьНовыйНомер у объекта документа. Платформа 1С берет на себя блокировку таблицы нумерации, поиск максимального значения с учетом заданного префикса и автоинкремент числовой части с сохранением лидирующих нулей.
Рассмотрим пример программного создания документа с явной установкой префикса:
НовыйДокумент = Документы.АвансовыйОтчет.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДатаСеанса();
НовыйДокумент.Организация = ВыбраннаяОрганизация;
// Формируем нужный префикс, например: ПрефиксОрганизации + ГодМесяц
ПрефиксНомера = "ЧА" + Формат(НовыйДокумент.Дата, "ДФ=yyyyMM");
НовыйДокумент.УстановитьНовыйНомер(ПрефиксНомера);
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
Обратите внимание на важный нюанс: если номер не требуется получать заранее (до записи) для передачи во внешние системы или печатные формы, явно вызывать метод УстановитьНовыйНомер перед Записать() не обязательно. Если реквизит Номер остается пустым, платформа автоматически сгенерирует его в момент физической записи документа в транзакции. Лишний предварительный вызов метода может привести к появлению неиспользуемых пропусков в нумерации.
Когда требуется централизованно изменить логику префиксации для документов определенного вида, логику выносят в модуль объекта документа в процедуру-обработчик ПриУстановкеНовогоНомера.
Посмотрим на пример реализации внутри модуля объекта документа:
Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
// Формируем собственный префикс
ПрефиксОрганизации = "ЧА";
ПрефиксПериода = Формат(ЭтотОбъект.Дата, "ДФ=yyyyMM");
Префикс = ПрефиксОрганизации + ПрефиксПериода;
КонецПроцедуры
Параметр Префикс передается по ссылке. Платформа берет возвращенную строку, подставляет ее в начало номера и автоматически дополняет оставшуюся длину числовым счетчиком.
Если логику нумерации нужно применить сразу к нескольким видам документов без изменения их индивидуальных модулей объектов, оптимальным решением является создание подписки на событие. Разберем порядок действий:
ДокументОбъект).ПриУстановкеНовогоНомера.Реализуем процедуру в общем серверном модуле:
Процедура ДокументыПриУстановкеНовогоНомера(Источник, СтандартнаяОбработка, Префикс) Экспорт
// Префикс узла информационной базы или организации
ПрефиксОрганизации = "";
Если ОбщегоНазначения.ЕстьРеквизитИлиСвойствоОбъекта(Источник, "Организация")
И ЗначениеЗаполнено(Источник.Организация) Тогда
ПрефиксОрганизации = СокрЛП(Источник.Организация.Префикс);
КонецЕсли;
СтрокаПериода = Формат(Источник.Дата, "ДФ=yyyyMM");
Префикс = ПрефиксОрганизации + СтрокаПериода;
КонецПроцедуры
В конфигурациях уровня «1С:Управление торговлей 11» действует встроенная подсистема Префиксация объектов Библиотеки Стандартных Подсистем (БСП). В типовой конфигурации на событие ПриУстановкеНовогоНомера уже зарегистрированы стандартные подписки.
При внедрении собственной логики важно учитывать следующие факторы:
ПрефиксацияОбъектовПереопределяемый в предназначенных для этого процедурах (например, ПриУстановкеПрефиксаЕдиницыОрганизации или ПриУстановкеПрефиксаИнформационнойБазы).[ПрефиксИБ][ПрефиксОрганизации]-[Номер].Иногда разработчики пытаются вычислить следующий номер прямым запросом к таблице базы данных:
// ОШИБОЧНЫЙ ПОДХОД: НЕ ИСПОЛЬЗОВАТЬ В РЕАЛЬНЫХ СИСТЕМАХ
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Док.Номер КАК Номер
|ИЗ
| Документ.АвансовыйОтчет КАК Док
|УПОРЯДОЧИТЬ ПО
| Док.Номер УБЫВ";
// Прибавление единицы к строке или числу...
Проанализируем риски такого решения:
"10" будет меньше "9", если отсутствуют лидирующие нули, что приведет к неверному определению максимального значения.УстановитьНовыйНомер работает на уровне внутренних системных таблиц с оптимизированными транзакционными блокировками без выполнения тяжелых запросов по всей таблице документов.При конструировании сложных префиксов следует всегда проверять свойства метаданных документа:
ЧА201604) занимает 8 символов, на порядковую нумерацию останется всего 3 знака (от 001 до 999). После превышения 999 документов в периоде нумерация собьется или вернет ошибку. Всегда закладывайте достаточную длину номера в конфигураторе.