При разработке и адаптации конфигурации «1С:Управление производственным предприятием» (УПП) программисты часто сталкиваются с задачей реализации уникальной, отличной от типовой, нумерации документов. Например, для документа Заказ на производство может потребоваться сложная структура номера, включающая дату, код подразделения или специфический префикс.
Однако при попытке внедрить собственный алгоритм разработчики нередко попадают в ситуацию, когда в отладчике кастомный номер успешно присваивается, но после окончательной записи документа в базу данных система «сбрасывает» его и возвращает стандартный порядковый номер. Разберем по шагам, почему так происходит, как устроен жизненный цикл генерации номера в платформе «1С:Предприятие 8» и как правильно реализовать свою нумерацию без ущерба для типовых механизмов.
Для начала проанализируем ситуацию, когда в событии ПередЗаписью формы документа реквизит Номер оказывается пустым, хотя до этого успешно отрабатывала подписка на событие ПриУстановкеНовогоНомера. Такое поведение абсолютно нормально и заложено в архитектуру платформы. Рассмотрим последовательность событий, происходящих при создании и записи нового документа из формы:
ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения). На этом этапе номер нового документа всегда пустой, так как транзакция записи еще не началась и платформа не инициировала создание номера.ПередЗаписью(Отказ). Здесь номер также остается пустым.ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс). Именно здесь срабатывают подписки на это событие и внутренние обработчики модуля объекта. Физически номер генерируется и устанавливается именно в этот момент.ПриЗаписи(Отказ). На этом шаге номер уже заполнен и доступен для чтения или анализа.ПриЗаписи() и ПослеЗаписи(). Здесь мы уже видим сохраненный в базе номер.Пытаться перехватить или изменить сформированный номер в процедуре ПередЗаписью формы или объекта бессмысленно — физически платформа его еще не сгенерировала.
Если в процессе отладки внутри вашей подписки номер устанавливается корректно, но в итоге в базу записывается стандартный порядковый номер, проанализируем три основные технические причины:
В обработчике события ПриУстановкеНовогоНомера передается важнейший параметр — СтандартнаяОбработка (тип Булево). По умолчанию он равен Истина. Если в коде вашей подписки вы присвоили реквизиту новое значение, например: Источник.Номер = СформированныйНомер, но при этом оставили параметр СтандартнаяОбработка в значении Истина, платформа после выполнения вашего алгоритма запустит штатный механизм автонумерации. Он проигнорирует ваше присвоение и перезапишет номер стандартным по порядку.
Решение: В коде обработчика обязательно нужно явно отключать стандартную генерацию:
Процедура ИмяПроцедуры(Источник, СтандартнаяОбработка, Префикс) Экспорт
СтандартнаяОбработка = Ложь; // Отключаем автонумерацию платформы
Источник.Номер = "ПРЕФИКС-" + НашАлгоритмПолученияНомера();
КонецПроцедуры
В конфигурации УПП на событие ПриУстановкеНовогоНомера может быть назначено несколько подписок (например, для обменов данными в распределенных информационных базах или для префиксации документов по организациям). Порядок выполнения подписок на одно и то же событие платформой не гарантируется.
Если ваша кастомная подписка отработала первой и установила номер, а следом за ней запустилась типовая подписка, она вполне может перезаписать ваш уникальный номер стандартным. Рекомендуется проверить список всех подписок на данное событие и исключить из них ваш документ, если вы планируете полностью контролировать нумерацию.
В типовых конфигурациях 1С разработчики часто вызывают метод ЭтотОбъект.УстановитьНовыйНомер() принудительно внутри модуля объекта (например, при изменении организации или даты документа в процедуре ПередЗаписью). Если такой вызов происходит в кодовой цепочке после того, как ваша подписка уже отработала, то установленный вами номер сотрется.
Для поиска таких вызовов рекомендуем использовать глобальный поиск по конфигурации или пройтись отладчиком (по клавише F11) от момента записи в форме до фактической записи в базу данных. Обратите внимание на вызовы функций общего модуля, таких как ОбщегоНазначения.ПриУстановкеНовогоНомераДляДокументов.
В зависимости от бизнес-требований, рассмотрим два основных сценария настройки нумерации.
Если ваша задача — просто добавить к стандартному номеру уникальный буквенный префикс (например, привязать нумерацию к подразделению или виду операции), полностью отключать стандартную автонумерацию не стоит. Это может нарушить сквозную нумерацию и уникальность номеров в распределенных базах.
Посмотрим на пример переопределения префикса в общем модуле. Как правило, в УПП для этого используется подписка ПриУстановкеНовогоНомераДокумента, которая обращается к общему модулю. Добавим туда проверку нашего документа:
// Вставляем условие в процедуру установки префиксов общего модуля
Если Источник.Метаданные().Имя = "ЗаказНаПроизводство" Тогда
// Добавляем к текущему префиксу организации наш кастомный префикс
Префикс = Префикс + "ЗП";
КонецЕсли;
При таком подходе платформа сама сгенерирует уникальную числовую часть, сохранив при этом ваш префикс (например, "ОПЗП0000001", где "ОП" — префикс организации, а "ЗП" — ваш префикс документа).
Если формат номера должен быть абсолютно уникальным (например, содержать дату в формате "ГГММДД" и порядковый номер в рамках дня), выполним следующие действия:
ЗаказНаПроизводство. На вкладке "Нумерация" свойство Автонумерация должно быть включено (значение "Автоматически"). Это необходимо для того, чтобы платформа вообще генерировала событие ПриУстановкеНовогоНомера.ПриУстановкеНовогоНомера для вашего документа и пропишите следующий код:
Процедура ПриУстановкеНовогоНомераЗаказаНаПроизводство(Источник, СтандартнаяОбработка, Префикс) Экспорт
// Блокируем стандартный механизм платформы
СтандартнаяОбработка = Ложь;
// Формируем дату для номера
ТекДата = Формат(Источник.Дата, "ДФ=yyMMdd");
// Получаем очередную свободную числовую последовательность
// (функцию ПолучитьСвободныйНомерПоДате необходимо реализовать самостоятельно)
ПорядковыйНомер = ПолучитьСвободныйНомерПоДате(Источник.Дата);
// Собираем итоговый номер
Источник.Номер = "ЗП-" + ТекДата + "-" + ПорядковыйНомер;
КонецПроцедуры
Используя данные рекомендации, вы сможете гибко настроить логику нумерации документов в 1С:УПП, избежав конфликтов со стандартными механизмами платформы и обеспечив корректную запись данных в базу.