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