Продолжим цикл статей про обмены с помощью встроенных механизмов 1С -Web-Сервисы.
Рассмотрим простой пример самописного обмена с мобильным приложением.
Для начала создаем Web-Сервис (С наименованием "ObmenMobil").
-URl пространство имен - вводим ip адресс для удобства (пример: 127.1.1.1)
-Пакеты XDTO , до сих пор до конца не разобрался )), поэтому выбираю стандартный (http://v8.1c.ru/8.1/data/core).
-Имя файла публикации - Любое значение с форматом *.1cws(Пример: ObmenMobil.1cws)
Далее, добавляем новую "Операцию" в наш Web-Сервис. (Наименование: "ПолучитьСписокНоменклатуры").
Тип возвращаемого значения укажем: ValueStorage (http://v8.1c.ru/8.1/data/core).
(PS. Выбранный тип содержится в Пакете XDTO (http://v8.1c.ru/8.1/data/core), указанной ранее в Web-сервисе).
(PS. ValueStorage - Это "Хранилище значений", удобен тем что его можно сжать, если объем данных будет большим, но так же можно использовать строковый тип (Например стандартный тип: "string (http://www.w3.org/2001/XMLSchema)")).
И добавим ему параметры. (В данном примере я добавлю только 1 универсальный параметр).
Наименование: "Параметры" - Тип значения: "string (http://www.w3.org/2001/XMLSchema)"
Процедура модуля:
///Параметры - Тип: "строка"
Функция ПолучитьСписокНоменклатуры(Параметры)
///Параметры - Это будет Структура, сериализованная в строку XML.
///поэтому конвертируем его обратно в структуру.
ЧтениеXMLДанных = Новый ЧтениеXML;
ЧтениеXMLДанных.УстановитьСтроку(Параметры);
СтруктураПараметров = СериализаторXDTO.ПрочитатьXML(ЧтениеXMLДанных);
ЧтениеXMLДанных.Закрыть();
/// Основная процедура вынесена в общие модуле, так как Синтаксис ошибкок в этом модуле не работает
Возврат ОбменДанными.ПолучитьСписокНоменклатурыXML(СтруктураПараметров);
КонецФункции
//// Общий модуль: ОбменДанными
Функция ПолучитьСписокНоменклатурыXML(СтруктураПараметров) Экспорт
ДобавлятьШтрихКод = Ложь;
/// если в параметрах указано свойство "Штрихкод" - используем его значение
СтруктураПараметров.Свойство("ШтрихКод",ДобавлятьШтрихКод);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.ЕдиницаДляОтчетов.Наименование КАК ЕдиницаДляОтчетовНаименование,
| Номенклатура.ЕдиницаДляОтчетов.Вес КАК ЕдиницаДляОтчетовВес,
| Номенклатура.ЕдиницаДляОтчетов.Объем КАК ЕдиницаДляОтчетовОбъем,
| Номенклатура.ЕдиницаДляОтчетов.Коэффициент КАК ЕдиницаДляОтчетовКоэффициент,
| Номенклатура.ЭтоГруппа КАК ЭтоГруппа,
| Номенклатура.ПометкаУдаления КАК ПометкаУдаления,
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.ЕдиницаДляОтчетов.Ссылка КАК ЕдиницаДляОтчетовСсылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка В ИЕРАРХИИ(&Родитель)
| И Номенклатура.ПометкаУдаления = ЛОЖЬ";
Запрос.УстановитьПараметр("Родитель", Родитель);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
//Весь список номенклатуры буден помещен в массив
ОбъектСписок = новый Массив;
Пока Выборка.Следующий() Цикл
//Каждую номенклатуру помещаем в струткуру
ДанныеНоменклатуры = новый Структура("Код, Наименование, Ссылка, ЭтоГруппа, Родитель, ЕдиницаИзмерения, ШтрихКоды",
Выборка.Код, Выборка.Наименование,XMLСтрока(Выборка.Ссылка),Выборка.Ссылка.ЭтоГруппа,,,);
//Если есть родитель, то создаем рекурсивно родителя
Если НЕ Выборка.Ссылка.Родитель.Пустая() Тогда
ДанныеНоменклатуры.Родитель = ДобавитьРодителей(Выборка.Ссылка.Родитель);
КонецЕсли;
//Создаем Единицу измерения в виде структуры
Если НЕ Выборка.Ссылка.ЭтоГруппа Тогда
Если НЕ Выборка.Ссылка.ЕдиницаДляОтчетов.Пустая() Тогда
ДанныеЕдиницыИзмерения = новый Структура("Код, Наименование, Ссылка, Вес, Объем, Коэффициент",
Выборка.ЕдиницаДляОтчетовСсылка.Код,Выборка.ЕдиницаДляОтчетовСсылка.Наименование,XMLСтрока(Выборка.ЕдиницаДляОтчетовСсылка),
Выборка.ЕдиницаДляОтчетовСсылка.Вес,Выборка.ЕдиницаДляОтчетовСсылка.Объем,Выборка.ЕдиницаДляОтчетовСсылка.Коэффициент);
ДанныеНоменклатуры.ЕдиницаИзмерения = ДанныеЕдиницыИзмерения;
КонецЕсли;
Если ДобавлятьШтрихКод Тогда
///Штрихкодов может быть несколько, поэтому отдельно рисуем запрос на получения и добавляем в массив
ДанныеНоменклатуры.ШтрихКоды = ПолучитьШтрихКоды(Выборка.Ссылка);
КонецЕсли;
КонецЕсли;
ОбъектСписок.Добавить(ДанныеНоменклатуры);
КонецЦикла;
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
//Преобразуем массив в объект XDTO
МассивВОбъектеXDTO = СериализаторXDTO.ЗаписатьXDTO(ОбъектСписок);
//Записываем объект XDTO в XML строку
ФабрикаXDTO.ЗаписатьXML(Запись, МассивВОбъектеXDTO);
ДанныеXML = Запись.Закрыть(); // документ готов!
///Поместим данные в хранилище значений в сжатом виде
ХранилищеЗнч = новый ХранилищеЗначения(ДанныеXML,новый СжатиеДанных(9))
Возврат ХранилищеЗнч;
КонецФункции
Функция ДобавитьРодителей(Родитель)
ДанныеРодителя = новый Структура("Код, Наименование, Ссылка, ЭтоГруппа, Родитель",
Родитель.Код, Родитель.Наименование,XMLСтрока(Родитель.Ссылка),Родитель.ЭтоГруппа,);
Если НЕ Родитель.Родитель.Пустая() Тогда
ДанныеРодителя.Родитель = ДобавитьРодителей(Родитель.Родитель);
КонецЕсли;
Возврат ДанныеРодителя;
КонецФункции
Функция ПолучитьШтрихКоды(Владелец)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Штрихкоды.Штрихкод КАК Штрихкод,
| Штрихкоды.Владелец КАК Владелец
|ИЗ
| РегистрСведений.Штрихкоды КАК Штрихкоды
|ГДЕ
| Штрихкоды.Владелец = &Владелец";
Запрос.УстановитьПараметр("Владелец", Владелец);
ТЧ = Запрос.Выполнить().Выгрузить();
Если ТЧ.Количество() = 0 Тогда
возврат новый Массив;
КонецЕсли;
Возврат ТЧ.ВыгрузитьКолонку("Штрихкод");
КонецФункции
Всё. Публикуем базу и можно подключаться)
БАЗА 2. Подключение и загрузка данных:
Процедура ЗагрузитьНоменклатуру() экспорт
///----------данный кусок перенесен в справочник "ПодключениеКWS", чтобы не держать данные в модуле---<
ВСОпределение = Новый WSОпределения("127.1.1.1/Obmen/ws/Obmen.1cws?wsdl", "admin", "pass");
//127.1.1.1 - ВашИПАдресГдеОпубликованWebСервис
//admin - пользователь информационной базы с полными правами и пароль -pass
ВСПрокси = Новый WSПрокси(ВСОпределение, "127.1.1.1", "Obmen", "ObmenSoap");
//127.1.1.1 - URl пространство имен Веб сервиса первой базы, Obmen -наименование
// расширения ,
//ObmenSoap тоже самое Но добавляем Soap к названии ))
Склад= Элементы.Склад.Значение; //Элемент формы, выбранное поле - склад
Время=ТекущаяДата();
ВСПрокси.Пользователь = "admin";
ВСПрокси.Пароль = "pass";
/// Добавим параметр: Штрихкод
ПараметрЗапроса = новый Структура;
ПараметрЗапроса.Вставить("Штрихкод",Истина);
/// Сериализуем структуру в строку.
ДокументВОбъектеXDTO = СериализаторXDTO.ЗаписатьXDTO(ПараметрЗапроса);
МойXML = Новый ЗаписьXML;
МойXML.УстановитьСтроку();
ФабрикаXDTO.ЗаписатьXML(МойXML, ДокументВОбъектеXDTO);
ПараметрЗапроса = МойXML.Закрыть();
ХранилищеЗначений = ВСПрокси.ПолучитьСписокНоменклатуры(ПараметрЗапроса); // подключаемся и получаем данные xml
////--------------------------------------->
/// ! для удобства добавил справочник "ПодключениеКWS" для заполнения настроек Веб сервисов, и получаю данные оттуда (Процедура ниже)
//Подключение = ПодключениеКWS();
//ХранилищеЗначений = Подключение.ПолучитьСписокНоменклатуры(ПараметрЗапроса);
ТекстXML = ХранилищеЗначений.Получить();
ЧтениеXML = новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекстXML);
/// Отключимся от БАЗЫ 1, так как данные уже получены.
//Подключение = Неопределено;
ВСПрокси = Неопределено;
МассивНоменклатуры = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Для каждого Стр из МассивНоменклатуры Цикл
Номенклатура = СоздатьНоменклатуру(Стр);
КонецЦикла;
КонецПроцедуры
/// ОбъектНастроек = Справочник объект "ПодключениеКWS", используется для тетирования нового подключения до записи.
Функция ПодключениеКWS(ОбъектНастроек = Неопределено) Экспорт
Настройки = Константы.НастройкиПодключения.Получить();
Если ОбъектНастроек = Неопределено И Настройки.Пустая() Тогда
ВызватьИсключение("Не заполнены настройки подключения к веб сервисам!");
КонецЕсли;
Если ОбъектНастроек <> Неопределено Тогда ///Для тестов
Настройки = ОбъектНастроек;
КонецЕсли;
МестоположениеWSDL = Настройки.IPАдрес +"/"+ Настройки.МестоположениеWSDL;
ИмяПользователя = Настройки.ИмяПользователя;
Пароль = Настройки.Пароль;
URIПространстваИменСервиса = Настройки.URIПространстваИмен;
ИмяСервиса = Настройки.ИмяСервиса;
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL;
ВСОпределение = Новый WSОпределения(МестоположениеWSDL, ИмяПользователя, Пароль,,,ЗащищенноеСоединение);
ВСПрокси = Новый WSПрокси(ВСОпределение,URIПространстваИменСервиса , ИмяСервиса,ИмяСервиса+"Soap" );
ВСПрокси.Пользователь = ИмяПользователя;
ВСПрокси.Пароль = Пароль;
Возврат ВСПрокси;
КонецФункции
Функция СоздатьНоменклатуру(ДанныеНоменклатуры)
///Проверка на существование ссылки. Если ссылка найдена, пропускаем.
СсылкаНоменклатуры = XMLЗначение(Тип("СправочникСсылка.Номенклатура"),ДанныеНоменклатуры.Ссылка);
///Ссылка будет отображаться как битая, проверяем по реквизиту "ВерсияДанных"
Если НЕ ЗначениеЗаполнено(СсылкаНоменклатуры.ВерсияДанных) Тогда
Если ДанныеНоменклатуры.ЭтоГруппа Тогда
СПР = Справочники.Номенклатура.СоздатьГруппу();
Иначе
СПР = Справочники.Номенклатура.СоздатьЭлемент();
КонецЕсли;
СПР.УстановитьСсылкуНового(СсылкаНоменклатуры);
Иначе
СПР = СсылкаНоменклатуры.ПолучитьОбъект();
КонецЕсли;
СПР.Код = ДанныеНоменклатуры.Код;
СПР.Наименование = ДанныеНоменклатуры.Наименование;
///Если есть родитель, сначала нужно создать родителя, и так до самого корня начала
Если ДанныеНоменклатуры.Родитель <> Неопределено Тогда
СПР.Родитель = СоздатьНоменклатуру(ДанныеНоменклатуры.Родитель);
КонецЕсли;
СПР.Записать();
Если НЕ СПР.ЭтоГруппа Тогда
Если ДанныеНоменклатуры.ЕдиницаИзмерения <> Неопределено Тогда
НоваяЕД = СоздатьЕдиницуИзмерения(ДанныеНоменклатуры.ЕдиницаИзмерения,СПР.Ссылка);
СПР.БазоваяЕдиницаИзмерения = НоваяЕД.Наименование;
СПР.ЕдиницаИзмерения = НоваяЕД.Ссылка;
СПР.Записать();
КонецЕсли;
Для каждого ст из ДанныеНоменклатуры.ШтрихКоды цикл
ЗаписатьШтрихКод(СПР.Ссылка,ст);
КонецЦикла;
КонецЕсли;
Возврат СПР.Ссылка;
КонецФункции
Процедура ЗаписатьШтрихКод(Владелец,ШтрихКод)
МенеджерЗаписи = РегистрыСведений.Штрихкоды.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Владелец = Владелец;
МенеджерЗаписи.ШтрихКод = ШтрихКод;
МенеджерЗаписи.Записать();
КонецПроцедуры
Функция СоздатьЕдиницуИзмерения(СтрокаДанных,Владелец)
СсылкаЕД = XMLЗначение(Тип("СправочникСсылка.ЕдиницаИзмерения"),СтрокаДанных.Ссылка);
Если НЕ ЗначениеЗаполнено(СсылкаЕД.ВерсияДанных) Тогда
НоваяЕД = Справочники.ЕдиницаИзмерения.СоздатьЭлемент();
НоваяЕД.УстановитьСсылкуНового(СсылкаЕД);
Иначе
НоваяЕД = СсылкаЕД.ПолучитьОбъект();
КонецЕсли;
НоваяЕД.Код = СтрокаДанных.Код;
НоваяЕД.Наименование = СтрокаДанных.Наименование;
НоваяЕД.Вес = СтрокаДанных.Вес;
НоваяЕД.Объем = СтрокаДанных.Объем;
НоваяЕД.Коэффициент = СтрокаДанных.Коэффициент;
НоваяЕД.Владелец = Владелец;
НоваяЕД.Записать();
Возврат НоваяЕД.Ссылка;
КонецФункции
Обмен через ВЕБ Сервисы 2 часть
Обмен через ВЕБ Сервисы 1 часть
ИнициализироватьПараметрыWebСервиса (БСП)
ОбработатьИнформациюОбОшибкеWebСервиса (БСП)
ПолучитьОписаниеОшибкиWebСервиса (БСП)
СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису (БСП)
#1, 31 января 2023 19:32
что за ужасный код выложили...