Довелось как-то поучаствовать в одном проекте. Суть участия была настройка синхронизации между мобильным устройством на Android и основной базой. Одним из главных условий было динамическое количество устройств, поэтому планы обмена не подходили. Решено было использовать веб-сервисы.
За время выполнения работы многое было переосмыслено и сейчас понимаю, что некоторые моменты надо было сделать немного иначе, но в целом задача была выполнена и в большинстве своем успешно. Я не буду привязываться к той задаче, поэтому сделаем все на абсолютно чистых базах и конфигурациях. Разберем в качестве примера синхронизацию справочников, как основной вид хранения информации.
Итак, создадим в чистой конфигурации справочники Номенклатура и, например, Категории. В номенклатуру добавим реквизит Категория с типом СправочникСсылка.Категории.
Далее, сделаем аналогичную конфигурацию для мобильного приложения и сразу перейдем к настройке веб-сервиса для синхронизации.
Немножко оговорюсь, мы рассмотрим только механизм обмена. Как фиксировать успешность синхронизации, тут — на что фантазии хватит. Если будет необходимость, расскажу как это было реализовано у меня, и какой, на мой взгляд, способ для этих целей лучше.
Итак, наша задача передать данные обоих справочников на мобильное устройство с учетом того, что реквизит справочника является ссылкой на элемент другого справочника. Введем немножко сокращений: мобильное приложение — МП, главная база — ЦБ(центральная база).
В ЦБ создаем объект конфигурации XDTO-пакет следующего вида
В данном пакете мы описываем структуру передаваемых нами данных. Свойства типов Code и Name у нас имеют тип string и означают Код и Наименование соответственно. Сами типы CategoryString и ProducString соответствуют строке элемента справочника. Типы ProductTable и CategoryTable представляют из себя массивы строк соответствующих справочников. Для того, чтобы тип стал массивом, в свойствах его свойства(ProductStr например) необходимо максимальное значение указать как «-1». Свойства CategoryStr и ProductStr имеют тип CategoryString и ProducString соответственно. И последнее оставшееся свойство это Category, которое имеет тип CategoryStr. Далее нам необходимо создать веб-сервис и операцию с типом возвращаемого объекта ProductTable. почему именно с этим типом, потому что он содержит необходимые нам категории.
Теперь добавим немножко кода, а именно опишем, как мы будем получать данные для выгрузки. Для данной операции нам не нужны никакие входящие параметры, по крайней мере в этом примере мы этого использовать не будем. В коде, мы не будем использовать тип CategoryTable, потому что он может понадобиться, если мы захотим выгрузить весь справочник категорий. В модуль веб-сервиса добавим следующую функцию:
Функция Synchronize()
//получим запросом все элементы справочника Номенклатура, кроме помеченных на удаление
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Номенклатура.Код,
| Номенклатура.Наименование,
| Номенклатура.Категория
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
//получим XDTO типы
ТипСтрокаНоменклатуры = ФабрикаXDTO.Тип("http://synchro.ru","ProductString");
ТипТаблицаНоменклатуры = ФабрикаXDTO.Тип("http://synchro.ru","ProductTable");
ТипСтрокаКатегории = ФабрикаXDTO.Тип("http://synchro.ru","CategoryString");
//далее создадим таблицу номенклатуры
ТаблицаНоменклатуры = ФабрикаXDTO.Создать(ТипТаблицаНоменклатуры);
//начнем теперь эту таблицу заполнять результатом запроса
РезультатЗапроса = Запрос.Выполнить().Выбрать();
Пока РезультатЗапроса.Следующий() Цикл
//создадим строчку номенклатуры
СтрокаНоменклатуры = ФабрикаXDTO.Создать(ТипСтрокаНоменклатуры);
//и заполним свойства
СтрокаНоменклатуры.Code = РезультатЗапроса.Код;
СтрокаНоменклатуры.Name = РезультатЗапроса.Наименование;
//теперь нам надо заполнить свойство Category, но мы помним, что у нас там созданный тип,
//поэтому создадим строчку категории
СтрокаКатегории = ФабрикаXDTO.Создать(ТипСтрокаКатегории);
//и тоже заполним свойства
ТекущаяКатегория = РезультатЗапроса.Категория;
СтрокаКатегории.Code =ТекущаяКатегория.Код;
СтрокаКатегории.Name = ТекущаяКатегория.Наименование;
//ну и добавим нашу категорию в строку номенклатуры
СтрокаНоменклатуры.Category = СтрокаКатегории;
//и в конце всех операций добавим нашу строчку номенклатуры в таблицу в свойство ProductStr
ТаблицаНоменклатуры.ProductStr.Добавить(СтрокаНоменклатуры);
КонецЦикла;
//и после цикла заполнения функция должна вернуть результат, т.е. таблицу номенклатуры
Возврат ТаблицаНоменклатуры;
КонецФункции
Теперь наш веб-сервис готов к публикации и после этого, можно приступать к настройке МП. Напомню, там мы на данный момент имеем только два справочника аналогичных ЦБ. Для простоты, в МП создадим объект обработка из которой и будем вызывать нашу синхронизацию. Добавим на форме обработки всего одну кнопку, которая и будет вызывать процедуру синхронизации, на это подробно останавливаться не буду. Код процедуры ниже:
&НаКлиенте
Процедура Синхронизировать(Команда)
СинхронизироватьНаСервере();
КонецПроцедуры
&НаСервере
Процедура СинхронизироватьНаСервере()
//создаем определение нашего веб-сервиса
Определение = Новый WSОпределения(ЗдесьАдресWSDL);
//по полученному определению создаем прокси
Прокси = Новый WSПрокси(Определение, "http://synchro.ru","Synchronyzer","SynchronyzerSoap",,10);
//теперь вызываем нашу операцию и получаем свойство ProductStr
ТаблицаНоменклатуры = Прокси.Synchronize().ProductStr;
//теперь разберем полученный результат
Для Каждого Номенклатура Из ТаблицаНоменклатуры Цикл
//сначала получим категорию номенклатуры и проверим по коду, есть ли она у нас в базе
ПолученнаяКатегория = Номенклатура.Category;
КатегорияВБазе = Справочники.Категории.НайтиПоКоду(ПолученнаяКатегория.Code);
Если КатегорияВБазе.Пустая() Тогда
//запишем категорию в базу
НоваяКатегория = Справочники.Категории.СоздатьЭлемент();
НоваяКатегория.Код = ПолученнаяКатегория.Code;
НоваяКатегория.Наименование = ПолученнаяКатегория.Name;
НоваяКатегория.Записать();
КатегорияВБазе = НоваяКатегория.Ссылка;
КонецЕсли;
//теперь поищем номенклатуру в справочнике
НоменклатураВБазе = Справочники.Номенклатура.НайтиПоКоду(Номенклатура.Code);
Если НоменклатураВБазе.Пустая() Тогда
//запишем номенклатуру в базу
ТекНоменклатура = Справочники.Номенклатура.СоздатьЭлемент();
Иначе
//или исправим существующую
ТекНоменклатура = НоменклатураВБазе.ПолучитьОбъект();
КонецЕсли;
ТекНоменклатура.Код = Номенклатура.Code;
ТекНоменклатура.Наименование = Номенклатура.Name;
ТекНоменклатура.Категория = КатегорияВБазе;
ТекНоменклатура.Записать();
КонецЦикла;
КонецПроцедуры
Собственно на этом все. Теперь при открытии обработки, нажимая кнопку Синхронизировать, получаем справочники или обновляем из ЦБ. Прошу строго не судить, т.к. это моя первая публикация. На грамотность кода особо внимания не обращайте, т.к. не нагромождал с целью упрощения. К публикации прикладываю обе конфигурации из статьи.
Ну вообще-то можно было просто сериализовать при выдаче и десериализовать при приеме.
и как-то странно это появилось сразу после курса «Мобильное приложение» )))) — там разобрано более всесторонне.
Но все равно молодец.
Да — и скрины можно по-меньше делать, а то много пустого места по центру остается.
(1) wtlz,
не более чем совпадение и с курсами никак не связано, просто действительно стечение обстоятельств )) вообще я подумал о том же и признаюсь честно, курсы еще сам не смотрел ))
(1) wtlz, Всё равно материал редкий. Так что только +
вопрос может быть неправильный… но нет четкого понимания — только мысли…
может быть не нужно создавать свои XDTO для организации обмена?
у нас, в каждой 1С есть пространство имен в котором определены типы всех объектов? его и использовать?
или все-таки нужно создавать свои XDTO?
А можно поподробнее? Какой именно тип нужно указать, непонятно.
АдресWSDL — какой он имеет вид