Почему сбрасывается собственный номер документа в 1С:УПП и как правильно настроить свою нумерацию?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке и адаптации конфигурации «1С:Управление производственным предприятием» (УПП) программисты часто сталкиваются с задачей реализации уникальной, отличной от типовой, нумерации документов. Например, для документа Заказ на производство может потребоваться сложная структура номера, включающая дату, код подразделения или специфический префикс.

Однако при попытке внедрить собственный алгоритм разработчики нередко попадают в ситуацию, когда в отладчике кастомный номер успешно присваивается, но после окончательной записи документа в базу данных система «сбрасывает» его и возвращает стандартный порядковый номер. Разберем по шагам, почему так происходит, как устроен жизненный цикл генерации номера в платформе «1С:Предприятие 8» и как правильно реализовать свою нумерацию без ущерба для типовых механизмов.

Разберем жизненный цикл записи документа и генерации номера

Для начала проанализируем ситуацию, когда в событии ПередЗаписью формы документа реквизит Номер оказывается пустым, хотя до этого успешно отрабатывала подписка на событие ПриУстановкеНовогоНомера. Такое поведение абсолютно нормально и заложено в архитектуру платформы. Рассмотрим последовательность событий, происходящих при создании и записи нового документа из формы:

  1. Форма документа: Вызывается процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения). На этом этапе номер нового документа всегда пустой, так как транзакция записи еще не началась и платформа не инициировала создание номера.
  2. Модуль объекта документа: Вызывается событие ПередЗаписью(Отказ). Здесь номер также остается пустым.
  3. Начало транзакции базы данных.
  4. Генерация номера: Платформа инициирует событие ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс). Именно здесь срабатывают подписки на это событие и внутренние обработчики модуля объекта. Физически номер генерируется и устанавливается именно в этот момент.
  5. Модуль объекта документа: Вызывается процедура ПриЗаписи(Отказ). На этом шаге номер уже заполнен и доступен для чтения или анализа.
  6. Завершение транзакции и запись данных в СУБД.
  7. Форма документа: Последовательно вызываются события ПриЗаписи() и ПослеЗаписи(). Здесь мы уже видим сохраненный в базе номер.

Пытаться перехватить или изменить сформированный номер в процедуре ПередЗаписью формы или объекта бессмысленно — физически платформа его еще не сгенерировала.

Выясним причины, по которым кастомный номер сбрасывается на типовой

Если в процессе отладки внутри вашей подписки номер устанавливается корректно, но в итоге в базу записывается стандартный порядковый номер, проанализируем три основные технические причины:

Причина 1. Не отключена стандартная обработка события

В обработчике события ПриУстановкеНовогоНомера передается важнейший параметр — СтандартнаяОбработка (тип Булево). По умолчанию он равен Истина. Если в коде вашей подписки вы присвоили реквизиту новое значение, например: Источник.Номер = СформированныйНомер, но при этом оставили параметр СтандартнаяОбработка в значении Истина, платформа после выполнения вашего алгоритма запустит штатный механизм автонумерации. Он проигнорирует ваше присвоение и перезапишет номер стандартным по порядку.

Решение: В коде обработчика обязательно нужно явно отключать стандартную генерацию:


Процедура ИмяПроцедуры(Источник, СтандартнаяОбработка, Префикс) Экспорт
    СтандартнаяОбработка = Ложь; // Отключаем автонумерацию платформы
    Источник.Номер = "ПРЕФИКС-" + НашАлгоритмПолученияНомера();
КонецПроцедуры

Причина 2. Конфликт подписок и порядок их выполнения

В конфигурации УПП на событие ПриУстановкеНовогоНомера может быть назначено несколько подписок (например, для обменов данными в распределенных информационных базах или для префиксации документов по организациям). Порядок выполнения подписок на одно и то же событие платформой не гарантируется.

Если ваша кастомная подписка отработала первой и установила номер, а следом за ней запустилась типовая подписка, она вполне может перезаписать ваш уникальный номер стандартным. Рекомендуется проверить список всех подписок на данное событие и исключить из них ваш документ, если вы планируете полностью контролировать нумерацию.

Причина 3. Принудительный вызов метода УстановитьНовыйНомер()

В типовых конфигурациях 1С разработчики часто вызывают метод ЭтотОбъект.УстановитьНовыйНомер() принудительно внутри модуля объекта (например, при изменении организации или даты документа в процедуре ПередЗаписью). Если такой вызов происходит в кодовой цепочке после того, как ваша подписка уже отработала, то установленный вами номер сотрется.

Для поиска таких вызовов рекомендуем использовать глобальный поиск по конфигурации или пройтись отладчиком (по клавише F11) от момента записи в форме до фактической записи в базу данных. Обратите внимание на вызовы функций общего модуля, таких как ОбщегоНазначения.ПриУстановкеНовогоНомераДляДокументов.

Реализуем собственную нумерацию: пошаговые сценарии

В зависимости от бизнес-требований, рассмотрим два основных сценария настройки нумерации.

Сценарий 1. Использование штатного механизма префиксов (Рекомендуемый)

Если ваша задача — просто добавить к стандартному номеру уникальный буквенный префикс (например, привязать нумерацию к подразделению или виду операции), полностью отключать стандартную автонумерацию не стоит. Это может нарушить сквозную нумерацию и уникальность номеров в распределенных базах.

Посмотрим на пример переопределения префикса в общем модуле. Как правило, в УПП для этого используется подписка ПриУстановкеНовогоНомераДокумента, которая обращается к общему модулю. Добавим туда проверку нашего документа:


// Вставляем условие в процедуру установки префиксов общего модуля
Если Источник.Метаданные().Имя = "ЗаказНаПроизводство" Тогда
    // Добавляем к текущему префиксу организации наш кастомный префикс
    Префикс = Префикс + "ЗП"; 
КонецЕсли;

При таком подходе платформа сама сгенерирует уникальную числовую часть, сохранив при этом ваш префикс (например, "ОПЗП0000001", где "ОП" — префикс организации, а "ЗП" — ваш префикс документа).

Сценарий 2. Полностью кастомная структура номера

Если формат номера должен быть абсолютно уникальным (например, содержать дату в формате "ГГММДД" и порядковый номер в рамках дня), выполним следующие действия:

  1. В конфигураторе откройте свойства документа ЗаказНаПроизводство. На вкладке "Нумерация" свойство Автонумерация должно быть включено (значение "Автоматически"). Это необходимо для того, чтобы платформа вообще генерировала событие ПриУстановкеНовогоНомера.
  2. Откройте форму документа и найдите в свойствах формы пункт Автонумерация. Установите его в значение Не использовать. Это предотвратит преждевременное резервирование номера платформой при простом открытии формы нового документа пользователем.
  3. Создайте подписку на событие ПриУстановкеНовогоНомера для вашего документа и пропишите следующий код:

Процедура ПриУстановкеНовогоНомераЗаказаНаПроизводство(Источник, СтандартнаяОбработка, Префикс) Экспорт
    
    // Блокируем стандартный механизм платформы
    СтандартнаяОбработка = Ложь;
    
    // Формируем дату для номера
    ТекДата = Формат(Источник.Дата, "ДФ=yyMMdd");
    
    // Получаем очередную свободную числовую последовательность
    // (функцию ПолучитьСвободныйНомерПоДате необходимо реализовать самостоятельно)
    ПорядковыйНомер = ПолучитьСвободныйНомерПоДате(Источник.Дата);
    
    // Собираем итоговый номер
    Источник.Номер = "ЗП-" + ТекДата + "-" + ПорядковыйНомер;
    
КонецПроцедуры

Используя данные рекомендации, вы сможете гибко настроить логику нумерации документов в 1С:УПП, избежав конфликтов со стандартными механизмами платформы и обеспечив корректную запись данных в базу.

← На главную