При разработке и кастомизации документов в системе «1С:Предприятие» разработчики часто сталкиваются с поведением, когда новому, еще не записанному документу автоматически присваивается номер прямо в момент открытия его формы. Пользователь еще не успел заполнить ни одного реквизита, а номер уже занят. Если после этого пользователь закроет форму без сохранения, этот номер будет безвозвратно утерян. Это приводит к так называемым «дырам» в нумерации, за которые бухгалтеры и аудиторы часто критикуют ИТ-специалистов.
В этой статье мы подробно разберем, почему платформа ведет себя именно так, что происходит во внутреннем жизненном цикле формы между событиями открытия и как настроить систему так, чтобы номер присваивался строго в момент записи документа в базу данных.
Проанализируем ситуацию, с которой столкнулся автор темы. Он заметил, что в самом конце процедуры ПередОткрытием номер документа все еще остается пустым, но уже в первой строчке процедуры ПриОткрытии номер загадочным образом появляется. Чтобы понять эту механику, нам нужно обратиться к внутренним процессам работы обычных форм (характерных для толстого клиента «1С:Предприятие 8.2» и режимов совместимости в 8.3).
Между обработчиками событий ПередОткрытием и ПриОткрытии платформа выполняет скрытые системные действия по подготовке интерфейса и связыванию данных:
Автонумерация установлено в значение Авто или Использовать, то именно в этот микроинтервал времени платформа генерирует и резервирует новый номер. В этот момент также вызывается обработчик события объекта ПриУстановкеНовогоНомера.Поскольку генерация номера происходит на шаге 2, разработчик физически не может «поймать» пустой номер внутри процедуры ПриОткрытии — там он уже заполнен платформой.
Поведение автонумерации существенно отличается в зависимости от версии платформы и режима совместимости конфигурации:
Автонумерация было упразднено. На уровне платформы генерация перенесена на момент записи. Для управления этим процессом в свойствах всей конфигурации появилось системное свойство «Режим автонумерации объектов»:
ОсвобождатьАвтоматически — старый режим (выделение при открытии, освобождение при отмене).НеОсвобождатьАвтоматически — современный стандарт (номер выделяется строго в транзакции записи, минимизируя блокировки и пропуски).Как справедливо заметил один из участников обсуждения, если в свойствах формы установить Автонумерация в значение Не использовать, то документ при записи вообще перестает получать номер. Он остается пустым.
Выясним причину этого поведения. Когда мы отключаем автонумерацию на уровне формы, мы запрещаем платформе автоматически запрашивать новый номер при инициализации интерфейса. Но если при этом в модуле объекта или в подписках на события не прописан альтернативный механизм генерации, платформа «считает», что разработчик решил управлять номерами вручную, и при записи оставляет поле номера пустым.
Кроме того, на этот процесс могут влиять три важных фактора:
Автонумерация должно быть включено. Если оно выключено там — автоматического номера не будет ни при каких условиях без явного программного вызова.ПриУстановкеНовогоНомераДокумента). Они вызывают общие модули нумерации. Если эти модули ожидают, что платформа уже выполнила базовые действия, они могут отработать некорректно при отключенной автонумерации формы.ОбменДанными.Загрузка = Истина), платформа полностью отключает генерацию новых номеров, так как номера должны приходить из базы-источника.Разберем детально, как решить задачу и заставить документ получать номер только при его сохранении (записи) в базу данных, избегая захвата номеров при открытии новых форм.
Откроем конфигуратор, найдем нужный документ и перейдем к его форме (обычно это ФормаДокумента). В палитре свойств формы найдем свойство Автонумерация и принудительно установим для него значение Не использовать.
Убедимся, что на уровне метаданных документа автонумерация разрешена. Откроем окно свойств документа, перейдем на вкладку Нумерация. Убедимся, что:
Год или В пределах квартала).Строка (рекомендуется для корректной работы префиксов).Поскольку платформа больше не нумерует документ при открытии формы, мы должны самостоятельно инициировать получение номера непосредственно перед записью объекта в базу данных. Для этого перейдем в Модуль объекта документа и пропишем обработчик события ПередЗаписью.
Рассмотрим два варианта программного кода в зависимости от того, разрабатываете ли вы документ «с нуля» в самописной конфигурации или работаете в типовой базе.
Вариант А. Для самописных конфигураций (чистый метод платформы):
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, что документ является новым и номер еще не был присвоен
Если ЭтоНовый() И ПустаяСтрока(ЭтотОбъект.Номер) Тогда
// Принудительно вызываем генератор номеров платформы
ЭтотОбъект.УстановитьНовыйНомер();
КонецЕсли;
КонецПроцедуры
Вариант Б. Для типовых конфигураций (с учетом префиксов организаций):
В типовых решениях (УПП, Комплексная автоматизация, ERP) простой вызов УстановитьНовыйНомер() может проигнорировать префикс организации или префикс узла распределенной информационной базы (РИБ). Поэтому следует использовать стандартные функции общих модулей конфигурации:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем необходимость установки номера
Если ЭтоНовый() И ПустаяСтрока(ЭтотОбъект.Номер) Тогда
// Используем типовой механизм подсистемы автонумерации
// Например, для конфигураций на базе УПП / КА 1.1:
ОбщегоНазначения.УстановитьНомерДокумента(ЭтотОбъект);
КонецЕсли;
КонецПроцедуры
Использование этого кода гарантирует, что номер будет назначен строго в транзакции записи. Если пользователь передумает записывать документ и закроет форму, номер физически не успеет создаться в базе данных и не будет «потерян».
Помимо устранения пропусков в нумерации, перенос генерации номера на момент записи решает еще одну классическую проблему — **неправильный префикс организации**.
Представим ситуацию: пользователь открывает новый документ, платформа автоматически генерирует номер с префиксом организации «А», которая установлена в настройках пользователя по умолчанию. В процессе заполнения документа пользователь меняет организацию на «Б». Если автонумерация сработала при открытии, номер останется с префиксом организации «А», что нарушит сквозную нумерацию по организациям. При переносе автонумерации на момент записи система сгенерирует номер с актуальным префиксом организации «Б», которая выбрана в документе на момент сохранения.