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

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

При разработке правил обмена в конфигурации «Конвертация данных 2.1» (КД 2) нередко возникает задача программного создания документов в базе-приемнике без источника. Документ формируется алгоритмически через вызов ВыгрузитьПоПравилу, и ему требуется присвоить стандартный номер, но с определенным пользовательским префиксом. На практике разработчики сталкиваются с тем, что стандартный вызов метода Объект.УстановитьНовыйНомер("К") в обработчике «После загрузки» не дает желаемого результата: номер либо формируется без префикса, либо перезаписывается типовыми механизмами, либо вовсе остается пустым.

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

Почему метод УстановитьНовыйНомер не срабатывает ожидаемым образом

Проанализируем типовую ситуацию: в правиле конвертации объектов (ПКО) в обработчике «После загрузки» пишется следующий код:


Объект.УстановитьНовыйНомер("К");
Объект.Записать();

При отладке выясняется, что номер либо сбрасывается, либо префикс игнорируется. Основные причины такого поведения кроются в архитектуре платформы 1С:Предприятие и типовых подсистемах:

  1. Переопределение префикса подписками на события. В большинстве конфигураций, использующих БСП, зарегистрирована подписка на событие ПриУстановкеНовогоНомера (или ПередЗаписьюДляУстановкиНовогоНомера). Когда вызывается метод Объект.УстановитьНовыйНомер() или происходит штатная запись нового объекта, подписка перехватывает процедуру и формирует префикс по системным правилам: объединяет префикс информационной базы и префикс организации. Любой префикс, переданный в метод вручную, заменяется типовым.
  2. Отсутствие даты или организации на момент вызова метода. Автонумерация в 1С строго привязана к периодичности (обычно в пределах года) и реквизиту принадлежности (например, организации). Если на момент вызова метода реквизит Дата документа не заполнен или не указана Организация, платформа не может корректно определить диапазон номеров.
  3. Штатный механизм автогенерации в КД 2. Если в настройках ПКО включен флаг «Автоматически генерировать код или номер, если он не задан», либо создано ПКС для свойства Номер, механизм загрузки сам инициирует генерацию номера без параметров, перезатирая результаты ручной работы.

Вариант 1. Обходной путь через предварительную запись объекта

Рассмотрим решение, к которому часто приходят на практике методом отладки. Чтобы обойти типовые подписки на событие автонумерации, объект записывают дважды:


// Предварительная запись: объект перестает быть новым
Объект.Записать();

// Повторная установка номера с нужным префиксом
Объект.УстановитьНовыйНомер("К");
Объект.Записать();

Выясним причину, почему эта конструкция срабатывает: при первом вызове Объект.Записать() документ сохраняется в информационную базу. После этого системная проверка ЭтоНовый() начинает возвращать Ложь. Типовые подписки БСП настроены на модификацию префикса только для новых объектов. Соответственно, при последующем вызове метода Объект.УстановитьНовыйНомер("К") подписка уже не вмешивается в формирование строки, и префикс успешно фиксируется.

Обратите внимание на ограничения этого способа: вызов Объект.Записать() внутри обработчика КД 2 создает избыточную нагрузку на базу данных. Обработка загрузки данных штатно сама вызывает запись объекта после выполнения кода «После загрузки». В результате документ записывается в базу трижды, что провоцирует лишние транзакции, замедляет обмен и трижды запускает все движения и подписки.

Вариант 2. Прямое формирование номера без вызова автонумератора (Рекомендуемый)

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

Разберем по шагам, как настроить этот вариант:

  1. В ПКО документа снимите флаг «Автоматически генерировать код или номер, если он не задан».
  2. В таблице свойств (ПКС) добавьте строку для реквизита Номер, оставив поле Источник пустым.
  3. В обработчике ПКС «Перед выгрузкой» или «При загрузке» вычислите и задайте итоговую строку номера.

Если номер требуется рассчитать динамически в базе-приемнике, пропишем формирование в обработчике ПКО «После загрузки»:


// Убедимся, что дата документа заполнена
Если Не ЗначениеЗаполнено(Объект.Дата) Тогда
    Объект.Дата = ТекущаяДата();
КонецЕсли;

// Формируем уникальный номер вручную или получаем следующий по порядку
ПрефиксДокумента = "К";
// При прямом присвоении подписки не затирают префикс:
// Допустимо получить следующий свободный номер запросом или сформировать по шаблону
Объект.Номер = ПрефиксДокумента + "000000001"; 

// Запись вызывать не нужно: КД выполнит Объект.Записать() штатно

Вариант 3. Использование типового механизма префиксации базы или узла

Если префикс «К» должен сопровождать все документы, созданные в результате загрузки из конкретного источника или в конкретной базе, правильнее использовать штатные механизмы платформы, а не жестко прописывать код в правилах обмена:

  1. Префикс информационной базы. В настройках параметров учета или общих настройках программы базы-приемника установите значение префикса «К». В этом случае все новые документы, создаваемые штатными подписками БСП, будут автоматически получать этот префикс без вмешательства в код обмена.
  2. Префикс узла плана обмена. Если загрузка выполняется в рамках распределенной информационной базы (РИБ) или регулярного обмена между конфигурациями, префикс «К» настраивается в реквизитах соответствующего узла плана обмена в базе-приемнике.

Такой подход исключает необходимость переопределения логики нумерации в КД и сохраняет целостность последовательности номеров в информационной базе.

← На главную