По пакетам XDTO уже существует достаточно много статей, прочитав которые я потратил еще достаточно много времени чтобы разобраться как написать обмен, используя эту технологию. Сейчас я уверенно могу сказать, что все достаточно просто и покажу это на примере.
В примере мы выгрузим из демо базы БП 3 документ «Реализация (акты, накладные)» в самописную конфигурацию.
Конфигурация, в которую будем загружать данные будет состоять из следующих объектов:
Справочники: Номенклатура, Контрагенты. Перечисления: СтавкиНДС. Документы: РеализацияТоваровУслуг.
Оказывается, в демо базе БП 3 есть расширение «ФормированиеТестовыхДанных», значит им и воспользуемся, не будем создавать собственное.
Добавим пакет XDTO. Имя: ВыгрузкаРеализаций. URI пространство имен: infostart.
В пакете добавим тип объекта «ДокументРеализация».
В объект добавим свойства: Ссылка, Дата, Номер, Контрагент.
Создадим обработку «Выгрузка реализаций»
Код команды выгрузки:
&НаСервере
Функция КомандаВыгрузитьНаСервере()
// Вставить содержимое обработчика.
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.УстановитьСтроку();
РеализацияXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("infostart", "ДокументРеализация"));
РеализацияXDTO.Ссылка = СериализаторXDTO.XMLСтрока(выбРеализация.Ссылка);
РеализацияXDTO.Дата = выбРеализация.Дата;
РеализацияXDTO.Номер = выбРеализация.Номер;
РеализацияXDTO.Контрагент = выбРеализация.Контрагент.Наименование;
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, РеализацияXDTO);
Возврат ЗаписьXML.Закрыть();
КонецФункции
&НаКлиенте
Процедура КомандаВыгрузить(Команда)
ОбъектXDTO = КомандаВыгрузитьНаСервере();
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.ОткрытьФайл(выбФайл);
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьБезОбработки(ОбъектXDTO);
ЗаписьXML.Закрыть();
КонецПроцедуры
Результат
<?xml version="1.0" encoding="UTF-8"?>
<ДокументРеализация xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="infostart">
<Ссылка xsi:type="xs:string">63d07913-1e98-11e6-a31d-14dae9b19a48</Ссылка>
<Дата xsi:type="xs:dateTime">2016-12-29T12:00:00</Дата>
<Номер xsi:type="xs:string">0000-000603</Номер>
<Контрагент xsi:type="xs:string">Внуковский комбинат бортового питания</Контрагент>
</ДокументРеализация>
Изменим форму представления для свойств объекта XDTO
Результат
<?xml version="1.0" encoding="UTF-8"?>
<ДокументРеализация Контрагент="Внуковский комбинат бортового питания" Номер="0000-000603" Дата="2016-12-29T12:00:00" Ссылка="63d07913-1e98-11e6-a31d-14dae9b19a48" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="infostart"/>
Переходим к загрузке данных. Создадим обработку загрузки.
Код
&НаСервереБезКонтекста
Функция ПолучитьСсылкуПоУИ(УникальныйИдентификатор, МенеджерОбъекта)
УИДСсылки = СериализаторXDTO.XMLЗначение(Тип("УникальныйИдентификатор"), УникальныйИдентификатор);
Возврат МенеджерОбъекта.ПолучитьСсылку(УИДСсылки);
КонецФункции
&НаСервереБезКонтекста
Процедура ЗагрузитьРеализации(ТекстФайла)
ЧтениеXML = Новый ЧтениеXML();
ЧтениеXML.УстановитьСтроку(ТекстФайла);
РеализацияXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ФабрикаXDTO.Тип("infostart", "ДокументРеализация"));
сРеализацияТоваров = ПолучитьСсылкуПоУИ(РеализацияXDTO.Ссылка, Документы.РеализацияТоваровУслуг);
оРеализацияТоваров = сРеализацияТоваров.ПолучитьОбъект();
Если оРеализацияТоваров = Неопределено Тогда
оРеализацияТоваров = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
оРеализацияТоваров.УстановитьСсылкуНового(сРеализацияТоваров);
КонецЕсли;
оРеализацияТоваров.Дата = РеализацияXDTO.Дата;
оРеализацияТоваров.Номер = РеализацияXDTO.Номер;
оРеализацияТоваров.Записать(РежимЗаписиДокумента.Запись);
КонецПроцедуры
&НаКлиенте
Процедура КомандаЗагрузить(Команда)
// Вставить содержимое обработчика.
ЧтениеТекста = Новый ЧтениеТекста(выбФайл);
ТекстФайла = ЧтениеТекста.Прочитать();
ЗагрузитьРеализации(ТекстФайла);
КонецПроцедуры
Проверяем загрузку. Выполнение прерывается ошибкой. Через отладку можно увидеть, что значения свойств объекта РеализацияXDTO имеют строковый тип, конкретно дата в таком виде преобразуется к пустому значению.
В пакете XDTO укажем свойству "Дата" тип
Проверим еще раз загрузку, все должно было пройти успешно.
Отдельно обращу внимание на эту строчку кода
РеализацияXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ФабрикаXDTO.Тип("infostart", "ДокументРеализация"));
При чтение объекта XDTO я принудительно указал его тип, хотя параметр не является обязательным. И сделал я это не просто так, для корневого элемента тип объекта не выгружается, это хорошо видно в xml файле, где все свойства выгружали в форме элементов. Для объекта ДокументРеализация не указан атрибут xsi:type.
<?xml version="1.0" encoding="UTF-8"?>
<ДокументРеализация xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="infostart">
<Ссылка xsi:type="xs:string">63d07913-1e98-11e6-a31d-14dae9b19a48</Ссылка>
<Дата xsi:type="xs:dateTime">2016-12-29T12:00:00</Дата>
<Номер xsi:type="xs:string">0000-000603</Номер>
<Контрагент xsi:type="xs:string">Внуковский комбинат бортового питания</Контрагент>
</ДокументРеализация>
В свойство "контрагент" мы помещали наименование контрагента. Добавим новый тип объекта в пакет XDTO "СправочникКонтрагенты" со свойствами: Ссылка, Код, Наименование, НаименованиеПолное. Для свойства "Контрагент" в типе объекта "ДокументРеализация" укажем форму хранения в виде элемента. Внесем изменения в код выгрузки.
&НаСервере
Функция КомандаВыгрузитьНаСервере()
// Вставить содержимое обработчика.
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.УстановитьСтроку();
КонтрагентXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("infostart", "СправочникКонтрагенты"));
КонтрагентXDTO.Ссылка = СериализаторXDTO.XMLСтрока(выбРеализация.Контрагент.Ссылка);
КонтрагентXDTO.Код = выбРеализация.Контрагент.Код;
КонтрагентXDTO.Наименование = выбРеализация.Контрагент.Наименование;
КонтрагентXDTO.НаименованиеПолное = выбРеализация.Контрагент.НаименованиеПолное;
РеализацияXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("infostart", "ДокументРеализация"));
РеализацияXDTO.Ссылка = СериализаторXDTO.XMLСтрока(выбРеализация.Ссылка);
РеализацияXDTO.Дата = выбРеализация.Дата;
РеализацияXDTO.Номер = выбРеализация.Номер;
РеализацияXDTO.Контрагент = КонтрагентXDTO;
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, РеализацияXDTO);
Возврат ЗаписьXML.Закрыть();
КонецФункции
Думаю, здесь все понятно.
Дольше всего я не мог разобраться, как выгружать табличные части.
Создадим тип объекта "ТабличнаяЧасть" со свойством "Строки".
Максимальное количество -1, означает неограниченное количество элементов.
Создадим объект.
ТоварыXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("infostart", "ТабличнаяЧасть"));
И посмотрим его свойства в отладчике.
Дальше, думаю, уже все понятно. Изменения в коде обработки выгрузки.
&НаСервере
Функция КомандаВыгрузитьНаСервере()
// Вставить содержимое обработчика.
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.УстановитьСтроку();
КонтрагентXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("infostart", "СправочникКонтрагенты"));
КонтрагентXDTO.Ссылка = СериализаторXDTO.XMLСтрока(выбРеализация.Контрагент.Ссылка);
КонтрагентXDTO.Код = выбРеализация.Контрагент.Код;
КонтрагентXDTO.Наименование = выбРеализация.Контрагент.Наименование;
КонтрагентXDTO.НаименованиеПолное = выбРеализация.Контрагент.НаименованиеПолное;
РеализацияXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("infostart", "ДокументРеализация"));
РеализацияXDTO.Ссылка = СериализаторXDTO.XMLСтрока(выбРеализация.Ссылка);
РеализацияXDTO.Дата = выбРеализация.Дата;
РеализацияXDTO.Номер = выбРеализация.Номер;
РеализацияXDTO.Контрагент = КонтрагентXDTO;
ТоварыXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("infostart", "ТабличнаяЧасть"));
Для Каждого сТовары Из выбРеализация.Товары Цикл
НоменклатураXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("infostart", "СправочникНоменклатура"));
НоменклатураXDTO.Ссылка = СериализаторXDTO.XMLСтрока(сТовары.Номенклатура);
НоменклатураXDTO.Код = сТовары.Номенклатура.Код;
НоменклатураXDTO.Наименование = сТовары.Номенклатура.Наименование;
НоменклатураXDTO.НаименованиеПолное = сТовары.Номенклатура.НаименованиеПолное;
сТоварыXDTO = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("infostart", "ДокументРеализацияТовары"));
сТоварыXDTO.Номенклатура = НоменклатураXDTO;
сТоварыXDTO.Количество = сТовары.Количество;
сТоварыXDTO.Цена = сТовары.Цена;
сТоварыXDTO.Сумма = сТовары.Сумма;
сТоварыXDTO.СтавкаНДС = XMLСтрока(сТовары.СтавкаНДС);
сТоварыXDTO.СуммаНДС = сТовары.СуммаНДС;
ТоварыXDTO.Строки.Добавить(сТоварыXDTO);
КонецЦикла;
РеализацияXDTO.тчТовары = ТоварыXDTO;
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, РеализацияXDTO);
Возврат ЗаписьXML.Закрыть();
КонецФункции
Код загрузки
&НаСервереБезКонтекста
Процедура ЗагрузитьРеализации(ТекстФайла)
ЧтениеXML = Новый ЧтениеXML();
ЧтениеXML.УстановитьСтроку(ТекстФайла);
РеализацияXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ФабрикаXDTO.Тип("infostart", "ДокументРеализация"));
сРеализацияТоваров = ПолучитьСсылкуПоУИ(РеализацияXDTO.Ссылка, Документы.РеализацияТоваровУслуг);
оРеализацияТоваров = сРеализацияТоваров.ПолучитьОбъект();
Если оРеализацияТоваров = Неопределено Тогда
оРеализацияТоваров = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
оРеализацияТоваров.УстановитьСсылкуНового(сРеализацияТоваров);
КонецЕсли;
оРеализацияТоваров.Дата = РеализацияXDTO.Дата;
оРеализацияТоваров.Номер = РеализацияXDTO.Номер;
КонтрагентXDTO = РеализацияXDTO.Контрагент;
сКонтрагент = ПолучитьСсылкуПоУИ(КонтрагентXDTO.Ссылка, Справочники.Контрагенты);
оКонтрагент = сКонтрагент.ПолучитьОбъект();
Если оКонтрагент = Неопределено Тогда
оКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
оКонтрагент.УстановитьСсылкуНового(сКонтрагент);
КонецЕсли;
оКонтрагент.Код = КонтрагентXDTO.Код;
оКонтрагент.Наименование = КонтрагентXDTO.Наименование;
оКонтрагент.НаименованиеПолное = КонтрагентXDTO.НаименованиеПолное;
оКонтрагент.Записать();
оРеализацияТоваров.Контрагент = оКонтрагент.Ссылка;
оРеализацияТоваров.Товары.Очистить();
Для Каждого сТоварыXDTO Из РеализацияXDTO.тчТовары.Строки Цикл
сТовары = оРеализацияТоваров.Товары.Добавить();
ЗаполнитьЗначенияСвойств(сТовары, сТоварыXDTO,,"СтавкаНДС,Номенклатура");
сТовары.СтавкаНДС = Перечисления.СтавкиНДС[сТоварыXDTO.СтавкаНДС];
НоменклатураXDTO = сТоварыXDTO.Номенклатура;
сНоменклатура = ПолучитьСсылкуПоУИ(НоменклатураXDTO.Ссылка, Справочники.Номенклатура);
оНоменклатура = сНоменклатура.ПолучитьОбъект();
Если оНоменклатура = Неопределено Тогда
оНоменклатура = Справочники.Номенклатура.СоздатьЭлемент();
оНоменклатура.УстановитьСсылкуНового(сНоменклатура);
КонецЕсли;
оНоменклатура.Код = НоменклатураXDTO.Код;
оНоменклатура.Наименование = НоменклатураXDTO.Наименование;
оНоменклатура.НаименованиеПолное = НоменклатураXDTO.НаименованиеПолное;
оНоменклатура.Записать();
сТовары.Номенклатура = оНоменклатура.Ссылка;
КонецЦикла;
оРеализацияТоваров.Записать(РежимЗаписиДокумента.Запись);
КонецПроцедуры
Для создания примера использовались программные файлы 1С:Предприятие 8.3 (8.3.14.1694).