Модификация XDTO-пакета EnterpriseData в расширении . Методика и нюансы.
Во второй части статьи (первая часть опубликована //infostart.ru/1c/articles/2632740/)хочу рассказать о работе с составными типами в формате и про Объект «УдалениеОбъекта».
Работа с составными типами
В нашем примере, подробно описанном в первой статье, с передачей документа «Встреча» в ТЧ «Участники» есть реквизит «Контакт» опеределяемого типа с множеством возможных типов значений: СправочникСсылка.СтроковыеКонтактыВзаимодействий, СправочникСсылка.Пользователи, СправочникСсылка.Партнеры, СправочникСсылка.КонтактныеЛицаПартнеров, СправочникСсылка.ФизическиеЛица
На стороне приемника определяемый тип отличается от Источника: СправочникСсылка.СтроковыеКонтактыВзаимодействий, СправочникСсылка.КонтактныеЛица, СправочникСсылка.Контрагенты
Для Справочника СтроковыеКонтактыВзаимодействий правил в типовом модуле не предусмотрено, поэтому не будем тратить на его передачу время (ведь это можно реализовать аналогично самому документу «Встреча»)
А справочника «Физические лица» вообще нет такого типа в Приемнике. Но передадим его на всякий случай, может на стороне Приемника обработаем как-то.
Получается, что можем без лишних усилий передать Контрагента (из Партнера) и «Контактное Лицо»
В XDTO Пакете нам понадобится еще один Объект (назовем его «СоставнойКонтакт»), в который мы добавим Свойства с типами допустимых типов определяемого типа. И сам реквизит Контакт должен быть этого типа

В данном случае добавим Свойства Физлицо (с типом КлючевыеСвойстваФизическоеЛицо), КонтактноеЛицо (КлючевыеСвойстваКонтактныеЛица) и Контрагент(КлючевыеСвойстваКонтрагент).

Также в коде нужно прописать Инструкцию при конвертации, к какому типу приводить «Контакт» в каждом конкретном случае (в обработчике ПриОтправкеДанных на этапе формирования XDTO-Структуры данных). EDПКО_Документ_Встреча_Отправка_ПриОтправкеДанных) Данные в отладке+ Код под Спойлером

Процедура EDПКО_Документ_Встреча_Отправка_ПриОтправкеДанных(ДанныеИБ, ДанныеXDTO, КомпонентыОбмена, СтекВыгрузки)
Если СтекВыгрузки.Количество() > 1 Тогда
Возврат;
КонецЕсли;
ТЗУчастники = ДанныеИБ.Участники.Выгрузить();
ТЗУчастники.Колонки.Добавить("Инструкция");
Для каждого Строка Из ТЗУчастники Цикл
Инструкция = Новый Структура("ИмяПКО,Значение","", Строка.Контакт);
Если ТипЗнч(Строка.Контакт) = Тип("СправочникСсылка.ФизическиеЛица") Тогда
Инструкция.ИмяПКО = "Справочник_ФизическиеЛица_Отправка";
Строка.Инструкция = Инструкция;
ИначеЕсли ТипЗнч(Строка.Контакт) = Тип("СправочникСсылка.КонтактныеЛицаПартнеров") Тогда
Инструкция.ИмяПКО = "Справочник_КонтактныеЛицаПартнеров_Отправка";
Строка.Инструкция = Инструкция;
Если не ДанныеXDTO.Свойство("КонтактноеЛицо") Тогда
ДанныеXDTO.Вставить("КонтактноеЛицо", Строка.Контакт);
КонецЕсли;
ИначеЕсли ТипЗнч(Строка.Контакт) = Тип("СправочникСсылка.Партнеры") Тогда
КонтрагентВладелец = ПартнерыИКонтрагенты.ПолучитьКонтрагентаПартнераПоУмолчанию(Строка.Контакт);
Инструкция.ИмяПКО = "Справочник_Контрагенты";
Инструкция.Значение = КонтрагентВладелец;
Строка.Инструкция = Инструкция;
Если не ДанныеXDTO.Свойство("Партнер") и ЗначениеЗаполнено(КонтрагентВладелец) Тогда
//Если уже заполняли Контрагента в Шапке- второй раз не будем
ДанныеXDTO.Вставить("Контрагент", КонтрагентВладелец);
КонецЕсли;
КонецЕсли;
КонецЦикла;
ТЗУчастники.Колонки.Удалить("Контакт");
ТЗУчастники.Колонки["Инструкция"].Имя = "Контакт";
ДанныеXDTO.Вставить("Участники", ТЗУчастники);
КонецПроцедуры
То есть для каждой строки нам надо добавлять в инструкцию к значению контакта – ПКО, по которому значение будет сконвертировано.
Аналогично в коде необходимо прописать и инструкцию (ПКО ) на стороне Приемника (в обработчике ПриКонвертацииДанныхXDTO) . Спойлер
После получения получаем нужный нам результат. При этом код получается вполне компактным

Работа с Объектом «УдалениеОбъекта» Расширения
В процессе настройки обменов обнаружилось, что новые, созданные через расширения объекты формата не выгружаются как «УдалениеОбъекта». Пришлось покопаться в отладчике и разобраться с данным вопросом.
Сразу приведу решение.
- Добавить в расширение типовую подписку на событие СинхронизацияДанныхЧерезУниверсальныйФорматРегистрацияУдаления

- Необходимо в расширении создать специальный объект с Именем «УдалениеОбъекта» и свойством «СсылкаНаОбъект», которое должно быть составного типа со ссылкой(!а не Объекта) на наш документ «Встреча», (и на остальные расширяемые документы и справочники нашего расширения при их появлении). Стоит придерживаться правила наименования аналогично как в типовых («ВстречаСсылка»).

- Тут небольшая недоработочка 1С. Исправляем. В Модуле ОбменДаннымиXDTOСервер необходимо расширить метод &После("ЗаписатьУдалениеОбъектаXDTO"). Нем прописать для нашего пространства имен запись нашей ссылки, в случае ее наличия в Удаляемых объектах. Спойлер
&После("ЗаписатьУдалениеОбъектаXDTO") Процедура EDЗаписатьУдалениеОбъектаXDTO(КомпонентыОбмена, Ссылка, ТипСсылкиXDTO) УИДОбъектаXDTO = РегистрыСведений.ПубличныеИдентификаторыСинхронизируемыхОбъектов.ПубличныйИдентификаторПоСсылкеОбъекта( КомпонентыОбмена.УзелКорреспондента, Ссылка); Если Не ЗначениеЗаполнено(УИДОбъектаXDTO) Тогда Возврат; КонецЕсли; XMLСхема = МенеджерОбменаЧерезУниверсальныйФормат.EDПространствоИмен(); //это наше выдуманное простанство имен ТипXDTO = ФабрикаXDTO.Тип(XMLСхема, "УдалениеОбъекта"); Для Каждого Свойство Из ТипXDTO.Свойства[0].Тип.Свойства[0].Тип.Свойства Цикл Если Свойство.Тип = ТипСсылкиXDTO Тогда ЗначениеXDTOЛюбаяСсылка = ФабрикаXDTO.Создать(Свойство.Тип, УИДОбъектаXDTO); СсылкаНаОбъект = ФабрикаXDTO.Создать(ТипXDTO.Свойства[0].Тип.Свойства[0].Тип); // ОбъектXDTO СсылкаНаОбъект.Установить(Свойство, ЗначениеXDTOЛюбаяСсылка); ЛюбаяСсылкаОбъект = ФабрикаXDTO.Создать(ТипXDTO.Свойства[0].Тип); ЛюбаяСсылкаОбъект.СсылкаНаОбъект = СсылкаНаОбъект; ДанныеXDTO = ФабрикаXDTO.Создать(ТипXDTO); // ОбъектXDTO ДанныеXDTO.СсылкаНаОбъект = ФабрикаXDTO.Создать(ТипXDTO.Свойства[0].Тип); ДанныеXDTO.Установить(ТипXDTO.Свойства[0], ЛюбаяСсылкаОбъект); ФабрикаXDTO.ЗаписатьXML(КомпонентыОбмена.ФайлОбмена, ДанныеXDTO); Прервать; КонецЕсли; КонецЦикла; КонецПроцедуры - Далее наблюдаем типовое поведение системы, как нам и нужно: Если ссылка есть в регистрации к обмену, но не проходит фильтр к выгружаемых объектов – передается объект «УдалениеОбъекта» со ссылкой (ext1:ВстречаСсылка>7a158ac3-1a2d-11f1-8ff3-6cf6da2b0d80</ext1:ВстречаСсылка).Спойлер
<Body xmlns="http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.20" xmlns:ext1="http://sstud.ru/EnterpriseData/1.20">
<ext1:УдалениеОбъекта>
<ext1:СсылкаНаОбъект>
<ext1:СсылкаНаОбъект>
<ext1:ВстречаСсылка>7a158ac3-1a2d-11f1-8ff3-6cf6da2b0d80</ext1:ВстречаСсылка>
</ext1:СсылкаНаОбъект>
</ext1:СсылкаНаОбъект>
</ext1:УдалениеОбъекта>
</Body>
</Message>
- На стороне Приемника дорабатывать ничего не пришлось - видим ожидаемое – типовая обработка «УдалениеОбъекта). Полученный ранее объект стал "помеченным на удаление"

Выводы
- Собственно, задачи решены:
- передали значение составного типа,корректно приняли его
- Передали объект «УдалениеОбъекта» для Объектов, определенных только в XDTO расширения
- вся доработка в расширении(кроме модификации в плане обмена Источника для целей регистрации)
- Можете скачать архив с расширениями для УТ11(11.5.22.149), БП3.0.191.41 и использовать его как шаблон. Там все полностью рабочее.
- передали значение составного типа,корректно приняли его
- Передали объект «УдалениеОбъекта» для Объектов, определенных только в XDTO расширения
- вся доработка в расширении(кроме модификации в плане обмена Источника для целей регистрации)
Проверено на следующих конфигурациях и релизах:
- Управление торговлей, редакция 11, релизы 11.5.22.149
- Бухгалтерия предприятия, редакция 3.0, релизы 3.0.191.41
Вступайте в нашу телеграмм-группу Инфостарт
