Как получить и программно изменить номер документа в событии ПередЗаписью в 1С

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

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

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

Чтобы понять, почему номер недоступен в ПередЗаписью, проанализируем последовательность событий, которые генерирует платформа при вызове метода Записать():

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

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

Решение 1: Использование метода УстановитьНовыйНомер()

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Проверяем, что это новый документ и номер еще не заполнен
    Если ЗначениеЗаполнено(ЭтотОбъект.Номер) Тогда
        Возврат;
    КонецЕсли;

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

КонецПроцедуры

Важно: При использовании этого метода нужно быть осторожным. Если после вызова УстановитьНовыйНомер() запись документа будет отменена (например, Отказ = Истина), в нумерации может возникнуть "дырка", так как номер уже был задействован в счетчике системы.

Решение 2: Перенос логики в событие ПриУстановкеНовогоНомера

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


Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
    
    // Добавляем свой префикс к стандартному
    Префикс = Префикс + "ОТД_";
    
    // Если нужно полностью заменить алгоритм, можно установить СтандартнаяОбработка = Ложь
    // и присвоить номер вручную, но это не рекомендуется для автоматической нумерации
КонецПроцедуры

В этом событии параметр Префикс позволяет гибко управлять тем, как платформа сформирует итоговую строку номера, сохраняя при этом контроль за уникальностью и последовательностью.

Решение 3: Использование события ПриЗаписи

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

Рассмотрим, как передать данные из ПередЗаписью в ПриЗаписи, если в первом событии мы определили необходимость каких-то действий:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    // Используем ДополнительныеСвойства для передачи флага
    ЭтотОбъект.ДополнительныеСвойства.Вставить("НужноОбновитьСвязи", Истина);
КонецПроцедуры

Процедура ПриЗаписи(Отказ)
    Если ЭтотОбъект.ДополнительныеСвойства.Свойство("НужноОбновитьСвязи") Тогда
        // Здесь номер уже точно есть!
        ТекущийНомер = ЭтотОбъект.Номер;
        // Выполняем логику по обновлению связанных данных
        ОбновитьСвязанныеДанные(ТекущийНомер);
    КонецЕсли;
КонецПроцедуры

Проблема дублирования номеров и транзакционные блокировки

Выясним причину возможных ошибок при программной установке номера. Когда мы вызываем УстановитьНовыйНомер() вручную, платформа обращается к таблице регистрации номеров. В высоконагруженных системах, если несколько пользователей одновременно создают документы, может возникнуть конфликт блокировок или "перескоки" через номер — для выявления причин подойдёт мониторинг производительности и транзакционных блокировок 1С.

Рекомендации для стабильной работы:

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

Заключение

Мы проанализировали три основных подхода к получению номера документа. Выбор метода зависит от вашей конечной цели:

Для обеспечения качества кода и минимизации рисков перед внедрением изменений рекомендуется проводить анализ конфигураций и расширений на наличие ошибок. Помните, что корректная работа с номерами — залог отсутствия проблем при сдаче отчетности и синхронизации данных между базами.

← На главную