Знакомство с web-сервисами началось у меня на основе готового примера обмена между двумя разными конфигурациями. В этом примере в базе-источнике заполнялся XDTO-пакет и вызывался web-сервис, в котором осуществлялся поиск объекта по GUID, создание его в случае отсутствия, все реквизиты ссылочного типа заполнялись аналогично (поиск по GUID). В результате в приемнике получалось достаточно много кода, в основном — проверки нашли/не нашли объект и создание объекта во втором случае.
Недавно обнаружил XDTO-пакет http://v8.1c.ru/8.1/data/enterprise/current-config, описывающий каждую конфигурацию в терминах ее объектов метаданных (например, CatalogObject.ФизическиеЛица).
Появилась идея проверить, нельзя ли упростить обмен — и вот что у меня получилось.
Создание и заполнение свойств XDTO-пакета:
Процедура ВыгрузкаФизическихЛиц(Прокси, Узел, Фабрика, ОбъектОтбора)
ФизическоеЛицоТип = Фабрика.Тип("http://v8.1c.ru/8.1/data/enterprise/current-config", "CatalogObject.ФизическиеЛица");
ФизическоеЛицоКИТип = Фабрика.Тип("http://v8.1c.ru/8.1/data/enterprise/current-config", "CatalogTabularSectionRow.ФизическиеЛица.КонтактнаяИнформация");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФизическиеЛица.Ссылка КАК ФизическоеЛицо,
| ФизическиеЛица.Код КАК Code,
| ФизическиеЛица.ПометкаУдаления КАК DeletionMark,
| ФизическиеЛица.Наименование КАК Description,
| ФизическиеЛица.ЭтоГруппа КАК IsFolder,
| ФизическиеЛица.Родитель КАК Parent,
| ВЫБОР
| КОГДА ФизическиеЛица.Предопределенный
| ТОГДА ФизическиеЛица.ИмяПредопределенныхДанных
| ИНАЧЕ """"
| КОНЕЦ КАК PredefinedDataName,
| ФизическиеЛица.ДатаРождения,
| ФизическиеЛица.Пол,
| ФизическиеЛица.ИНН,
| ФизическиеЛица.СтраховойНомерПФР,
| ФизическиеЛица.МестоРождения,
| ФизическиеЛица.ИмеетНаучныеТруды,
| ФизическиеЛица.ИмеетИзобретения,
| ФизическиеЛица.ФИО,
| ФизическиеЛица.УточнениеНаименования,
| ФизическиеЛица.ДатаРегистрации,
| ФизическиеЛица.НаименованиеСлужебное,
| ФизическиеЛица.ЛьготаПриНачисленииПособий,
| ФизическиеЛица.ПостоянноПроживалВКрыму18Марта2014Года,
| ФизическиеЛица.Фамилия,
| ФизическиеЛица.Имя,
| ФизическиеЛица.Отчество,
| ФизическиеЛица.ИнициалыИмени,
| ЗНАЧЕНИЕ(Справочник.ГруппыДоступаФизическихЛиц.ПустаяСсылка) КАК ГруппаДоступа,
| 0 КАК УдалитьПроцентСевернойНадбавкиФизическогоЛица,
| ЛОЖЬ КАК УдалитьПроцентСевернойНадбавкиФизическогоЛицаИзменяется,
| ЗНАЧЕНИЕ(Перечисление.ПорядокНачисленияСеверныхНадбавок.ПустаяСсылка) КАК УдалитьПорядокИсчисленияПроцентаСевернойНадбавки,
| значение(Справочник.ФизическиеЛицаПрисоединенныеФайлы.ПустаяСсылка) КАК УдалитьФотография,
| значение(Справочник.Файлы.ПустаяСсылка) КАК УдалитьФотографияФайлом
|ИЗ
| Справочник.ФизическиеЛица.Изменения КАК ФизическиеЛицаИзменения
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица КАК ФизическиеЛица
| ПО ФизическиеЛицаИзменения.Ссылка = ФизическиеЛица.Ссылка
|ГДЕ
| ФизическиеЛицаИзменения.Узел = &Узел";
Запрос.УстановитьПараметр("Узел", Узел);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ФизЛицо = Выборка.ФизическоеЛицо;
ОбъектXDTO = Фабрика.Создать(ФизическоеЛицоТип);
ЗаполнитьЗначенияСвойств(ОбъектXDTO, Выборка);
ОбъектXDTO.Ref = Строка(ФизЛицо.УникальныйИдентификатор());
Для Каждого СтрокаКИ Из ФизЛицо.КонтактнаяИнформация Цикл
ОбъектXDTOКИ = Фабрика.Создать(ФизическоеЛицоКИТип);
ЗаполнитьЗначенияСвойств(ОбъектXDTOКИ, СтрокаКИ);
ОбъектXDTO.КонтактнаяИнформация.Добавить(ОбъектXDTOКИ);
КонецЦикла;
РезультатОперации = Ложь;
Попытка
РезультатОперации = Прокси.SetObject(ОбъектXDTO);
Исключение
КонецПопытки;
Если РезультатОперации Тогда
ПланыОбмена.УдалитьРегистрациюИзменений(Узел, ФизЛицо);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
А вот метод web-сервиса, который получает данные:
Функция SetObject(Object)
Попытка
Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
Объект = Сериализатор.ПрочитатьXDTO(Object);
Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Объект.Ссылка)) Тогда
Объект.Записать();
Исключение
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
Надеюсь, кому-нибудь будет полезным.
Этот код подходит только для совпадающих структур. Но для них можно использовать прямую сериализацию объекта, без запросов и ручного заполнения свойств.
(1) Fragster,
Это две разных базы с идентичными конфигурациями (задача такая была) с передачей объекта из одной базы в другую. Думается, работать будет и на различающихся конфигурациях — пакет же описывается по конфигурации приемника.
(2) в данном случае — не приемника, а той, в которой код запускается.
соответственно, делать
Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
Объект = Сериализатор.ПрочитатьXDTO(Object);
не надо, достаточно
СериализаторXDTO.ПрочитатьXDTO(Object);
а при выгрузке — убрать запрос и делать
ФизическиеЛицаОбъект = ФизическиеЛицаСсылка.ПолучитьОбъект();
Объект = СериализаторXDTO.ЗаписатьXDTO(Объект);
(3) Fragster,
Спасибо, осмыслю.
(1) Fragster,
Проверил — работает на разных структурах. ЗаписатьXDTO() — только на идентичных.
(5) именно при указании типа в пространстве именhttp://v8.1c.ru/8.1/data/enterprise/current-config ?
(6) Fragster,
Да, в этом пространстве имен. Т.е. при идентичных конфигурациях работает сериализация, а на различающихся — ручное заполнение, как в статье.