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