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