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