Как разделить префиксы документов при ручном и программном создании в 1С?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

Нередко на реальных внедрениях возникает задача визуального и аналитического разделения документов, созданных пользователями вручную, и документов, загруженных из внешних систем (сайтов, маркетплейсов, внешних учетных баз). Традиционным решением является назначение различных префиксов номеров. Однако разработчики часто сталкиваются с тем, что стандартный вызов метода УстановитьНовыйНомер() перестает выдавать ожидаемый результат, а номер переписывается типовыми механизмами конфигурации. Разберем, почему это происходит и как правильно реализовать раздельную нумерацию.

Выясним причину: почему типовая подписка перебивает переданный префикс

Проанализируем механику работы платформы «1С:Предприятие» и подсистемы «Библиотека стандартных подсистем» (БСП). Существует принципиальная разница между непосредственной записью значения в реквизит и вызовом платформенного метода:

  1. Прямое присвоение номера: если в коде написать Док.Номер = "123123";, платформа не инициирует событие автонумерации. Заданный номер напрямую запишется в объект.
  2. Вызов метода генерации: метод Док.УстановитьНовыйНомер("Z"); принудительно вызывает платформенное событие ПриУстановкеНовогоНомера, на которое в типовых конфигурациях (таких как «1С:Бухгалтерия предприятия») назначена подписка.

В типовой подписке вызывается общий модуль префиксации (например, процедура УстановитьПрефиксИнформационнойБазыОрганизацииПодразделения). Стандартный алгоритм БСП жестко конкатенирует префикс информационной базы и префикс организации. В зависимости от релиза конфигурации переданный в метод строковый параметр либо полностью игнорируется, либо перетирается правилами подсистемы, из-за чего номер формируется по единому общему правилу.

Разберем по шагам решение через механизм ДополнительныеСвойства

Чтобы управлять логикой автонумерации из внешнего обработчика загрузки и при этом не отключать стандартные механизмы нумератора, оптимально использовать коллекцию ДополнительныеСвойства объекта. Этот контекст существует в оперативной памяти до момента окончания транзакции записи и доступен во всех подписках на события объекта.

Рассмотрим алгоритм реализации разделения префиксов:

  1. В обработке программной загрузки перед вызовом генерации номера или перед записью объекта добавляем специальный признак в структуру дополнительных свойств.
  2. В процедуре общего модуля, обрабатывающей событие ПриУстановкеНовогоНомера, проверяем наличие этого признака у переданного источника.
  3. В зависимости от наличия признака задаем требуемый префикс для программного создания либо типовой (или модифицированный) префикс для ручного ввода.

Посмотрим на пример кода в программном загрузчике документов:


// Создаем новый документ
Док = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
Док.Дата = ТекущаяДата();
Док.Организация = ВыбраннаяОрганизация;

// Передаем признак программного создания через ДополнительныеСвойства
Док.ДополнительныеСвойства.Вставить("ЭтоПрограммноеСоздание", Истина);

// Вызываем установку номера с нужным пользовательским префиксом
Док.УстановитьНовыйНомер("Z");

Теперь проанализируем реализацию в общем модуле, обрабатывающем событие префиксации (процедуру можно переопределить непосредственно или доработать через расширение конфигурации с аннотацией &Вместо или &ИзменениеИКонтроль):


Процедура УстановитьПрефиксИнформационнойБазыОрганизацииПодразделения(Источник, СтандартнаяОбработка, Префикс) Экспорт
    
    ИмяОрганизации   = ПрефиксацияОбъектовСобытия.ИмяРеквизитаОрганизация(Источник.Метаданные());
    ИмяПодразделения = ИмяРеквизитаПодразделение(Источник.Ссылка);
    
    // Проверяем тип документа, для которого требуется разделение нумерации
    Если ТипЗнч(Источник) = Тип("ДокументОбъект.РеализацияТоваровУслуг") Тогда
        
        // Безопасно проверяем наличие свойства программного создания
        Если Источник.ДополнительныеСвойства.Свойство("ЭтоПрограммноеСоздание") Тогда
            // Для программной загрузки используем логику с учетом переданного префикса
            Префикс = ПрефиксИнформационнойБазыОрганизацииПодразделения(Источник[ИмяОрганизации], Источник[ИмяПодразделения], Префикс);
        Иначе
            // Для ручного ввода пользователем жестко задаем отдельный префикс
            Префикс = "Т000-";
        КонецЕсли;
        
    Иначе
        // Для остальных документов сохраняем типовую логику конфигурации
        Префикс = ПрефиксИнформационнойБазыОрганизацииПодразделения(Источник[ИмяОрганизации], Источник[ИмяПодразделения], Префикс);
    КонецЕсли;

КонецПроцедуры

Обратим внимание на метод Свойство() структуры: использование синтаксиса Источник.ДополнительныеСвойства.Свойство("ЭтоПрограммноеСоздание") предпочтительнее конструкции Попытка ... Исключение, так как оно работает быстрее и не вызывает скрытых исключений при отсутствии ключа в коллекции.

Особенности и архитектурные ограничения автонумерации

При внедрении нестандартных префиксов важно учитывать требования типовых механизмов БСП и платформы:

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