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