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