Как присвоить реквизиту документа его номер при записи в 1С

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

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

Способ 1. Вызов метода УстановитьНовыйНомер() в обработчике ПередЗаписью модуля объекта

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

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

Проанализируем пример кода для модуля объекта документа:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Проверяем, является ли документ новым
    Если ЭтоНовый() Тогда
        // Если отдельный реквизит не заполнен пользователем
        Если ПустаяСтрока(РеквизитВнешнийНомер) Тогда
            // Принудительно генерируем номер документа
            УстановитьНовыйНомер();
            // Присваиваем сгенерированный номер реквизиту
            РеквизитВнешнийНомер = Номер;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Преимущества этого способа:

  1. Код выполняется полностью на стороне сервера в рамках единой транзакции записи.
  2. Не требуется повторный вызов метода Записать(), что исключает лишнюю нагрузку на сервер.
  3. Срабатывают все подписки на события по установке префиксов.

Особенности и риски: если запись документа будет отменена (например, из-за ошибки в проверке заполнения реквизитов или сбоя в транзакции), зарезервированный номер может быть пропущен в общей последовательности нумератора.

Способ 2. Обработка записи на форме в событии ПослеЗаписи

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

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

Посмотрим на пример реализации в модуле формы:


Процедура ПослеЗаписи()
    
    мСтараяМодифицированность = Модифицированность;
    
    Если ПустаяСтрока(plsСистемныйНомер) Тогда
        plsСистемныйНомер = ЭтотОбъект.Номер;
        ЭтотОбъект.Записать();
        Модифицированность = мСтараяМодифицированность;
    КонецЕсли;
    
КонецПроцедуры

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

Способ 3. Использование регистра сведений

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

Выясним порядок действий для этого подхода:

  1. В событии модуля объекта ПриЗаписи создаем набор записей регистра сведений.
  2. Указываем в качестве измерения ссылку на документ (ЭтотОбъект.Ссылка), а в качестве ресурса или реквизита — полученный номер (ЭтотОбъект.Номер).
  3. Записываем набор записей. Так как событие ПриЗаписи выполняется внутри транзакции документа, данные регистра будут сохранены корректно без повторного вызова записи самого документа.

Выбор конкретного решения зависит от требований архитектуры: для простой дубликации номера в реквизит объекта идеален вызов УстановитьНовыйНомер() в событии ПередЗаписью.

← На главную