При разработке правил обмена в конфигурации «Конвертация данных 2.1» (КД 2) нередко возникает задача программного создания документов в базе-приемнике без источника. Документ формируется алгоритмически через вызов ВыгрузитьПоПравилу, и ему требуется присвоить стандартный номер, но с определенным пользовательским префиксом. На практике разработчики сталкиваются с тем, что стандартный вызов метода Объект.УстановитьНовыйНомер("К") в обработчике «После загрузки» не дает желаемого результата: номер либо формируется без префикса, либо перезаписывается типовыми механизмами, либо вовсе остается пустым.
Разберем детально, почему так происходит, как на поведение нумератора влияют типовые конфигурации (Библиотека стандартных подсистем), и рассмотрим правильные варианты решения этой задачи.
Проанализируем типовую ситуацию: в правиле конвертации объектов (ПКО) в обработчике «После загрузки» пишется следующий код:
Объект.УстановитьНовыйНомер("К");
Объект.Записать();
При отладке выясняется, что номер либо сбрасывается, либо префикс игнорируется. Основные причины такого поведения кроются в архитектуре платформы 1С:Предприятие и типовых подсистемах:
ПриУстановкеНовогоНомера (или ПередЗаписьюДляУстановкиНовогоНомера). Когда вызывается метод Объект.УстановитьНовыйНомер() или происходит штатная запись нового объекта, подписка перехватывает процедуру и формирует префикс по системным правилам: объединяет префикс информационной базы и префикс организации. Любой префикс, переданный в метод вручную, заменяется типовым.Дата документа не заполнен или не указана Организация, платформа не может корректно определить диапазон номеров.Номер, механизм загрузки сам инициирует генерацию номера без параметров, перезатирая результаты ручной работы.Рассмотрим решение, к которому часто приходят на практике методом отладки. Чтобы обойти типовые подписки на событие автонумерации, объект записывают дважды:
// Предварительная запись: объект перестает быть новым
Объект.Записать();
// Повторная установка номера с нужным префиксом
Объект.УстановитьНовыйНомер("К");
Объект.Записать();
Выясним причину, почему эта конструкция срабатывает: при первом вызове Объект.Записать() документ сохраняется в информационную базу. После этого системная проверка ЭтоНовый() начинает возвращать Ложь. Типовые подписки БСП настроены на модификацию префикса только для новых объектов. Соответственно, при последующем вызове метода Объект.УстановитьНовыйНомер("К") подписка уже не вмешивается в формирование строки, и префикс успешно фиксируется.
Обратите внимание на ограничения этого способа: вызов Объект.Записать() внутри обработчика КД 2 создает избыточную нагрузку на базу данных. Обработка загрузки данных штатно сама вызывает запись объекта после выполнения кода «После загрузки». В результате документ записывается в базу трижды, что провоцирует лишние транзакции, замедляет обмен и трижды запускает все движения и подписки.
Наиболее надежным и производительным решением в обмене является отказ от вызова платформенного метода УстановитьНовыйНомер() в пользу явного расчета или прямого присвоения строки номера. В таком случае подписки на автонумерацию просто не срабатывают.
Разберем по шагам, как настроить этот вариант:
Номер, оставив поле Источник пустым.Если номер требуется рассчитать динамически в базе-приемнике, пропишем формирование в обработчике ПКО «После загрузки»:
// Убедимся, что дата документа заполнена
Если Не ЗначениеЗаполнено(Объект.Дата) Тогда
Объект.Дата = ТекущаяДата();
КонецЕсли;
// Формируем уникальный номер вручную или получаем следующий по порядку
ПрефиксДокумента = "К";
// При прямом присвоении подписки не затирают префикс:
// Допустимо получить следующий свободный номер запросом или сформировать по шаблону
Объект.Номер = ПрефиксДокумента + "000000001";
// Запись вызывать не нужно: КД выполнит Объект.Записать() штатно
Если префикс «К» должен сопровождать все документы, созданные в результате загрузки из конкретного источника или в конкретной базе, правильнее использовать штатные механизмы платформы, а не жестко прописывать код в правилах обмена:
Такой подход исключает необходимость переопределения логики нумерации в КД и сохраняет целостность последовательности номеров в информационной базе.