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