В процессе разработки конфигураций на платформе 1С часто возникает задача: необходимо сохранить сформированный номер документа в отдельный строковый реквизит. Например, если пользователь не указал входящий номер внешней системы вручную, система должна автоматически продублировать в этот реквизит стандартный номер документа. Однако в событии модуля объекта ПередЗаписью свойство Номер нового документа еще не заполнено, а в событии ПриЗаписи изменить реквизиты объекта без повторного сохранения уже нельзя. Разберем основные способы решения этой задачи и проанализируем их особенности.
Рассмотри наиболее предпочтительный серверный вариант. Чтобы получить номер документа до момента его физического сохранения в базу данных, мы можем принудительно вызвать метод УстановитьНовыйНомер() в обработчике ПередЗаписью модуля объекта.
При вызове метода УстановитьНовыйНомер() платформа автоматически задействует штатные механизмы нумерации и вызовет подписки на событие ПриУстановкеНовогоНомера (включая формирование префиксов организации и подразделения). После этого сформированный номер сразу становится доступен в свойстве Номер, и его можно записать в нужный реквизит.
Проанализируем пример кода для модуля объекта документа:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, является ли документ новым
Если ЭтоНовый() Тогда
// Если отдельный реквизит не заполнен пользователем
Если ПустаяСтрока(РеквизитВнешнийНомер) Тогда
// Принудительно генерируем номер документа
УстановитьНовыйНомер();
// Присваиваем сгенерированный номер реквизиту
РеквизитВнешнийНомер = Номер;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Преимущества этого способа:
Записать(), что исключает лишнюю нагрузку на сервер.Особенности и риски: если запись документа будет отменена (например, из-за ошибки в проверке заполнения реквизитов или сбоя в транзакции), зарезервированный номер может быть пропущен в общей последовательности нумератора.
Если требуется решить задачу на уровне формы документа, можно воспользоваться событием ПослеЗаписи(). На этом этапе документ уже записан в базу данных, и его свойство Номер полностью сформировано.
Разберем алгоритм выполнения: проверяем заполнение целевого реквизита, присваиваем ему значение свойства Номер, выполняем повторную запись объекта и восстанавливаем флаг модифицированности формы, чтобы избежать лишних вопросов пользователю при закрытии.
Посмотрим на пример реализации в модуле формы:
Процедура ПослеЗаписи()
мСтараяМодифицированность = Модифицированность;
Если ПустаяСтрока(plsСистемныйНомер) Тогда
plsСистемныйНомер = ЭтотОбъект.Номер;
ЭтотОбъект.Записать();
Модифицированность = мСтараяМодифицированность;
КонецЕсли;
КонецПроцедуры
Особенности этого способа: повторный вызов метода Записать() порождает дополнительную транзакцию и вызов серверных событий, что может снижать производительность при массовой работе пользователей. По этой причине первый способ с УстановитьНовыйНомер() является более предпочтительным.
Если задача заключается в сохранении истории номеров или первоначального системного номера для дальнейшей перенумерации, хранение данных непосредственно в реквизите документа не всегда оптимально. В таких ситуациях проанализируем использование независимого или подчиненного регистра сведений.
Выясним порядок действий для этого подхода:
ПриЗаписи создаем набор записей регистра сведений.ЭтотОбъект.Ссылка), а в качестве ресурса или реквизита — полученный номер (ЭтотОбъект.Номер).ПриЗаписи выполняется внутри транзакции документа, данные регистра будут сохранены корректно без повторного вызова записи самого документа.Выбор конкретного решения зависит от требований архитектуры: для простой дубликации номера в реквизит объекта идеален вызов УстановитьНовыйНомер() в событии ПередЗаписью.