Главная Новости

Универсальный обмен между идентичными конфигурациями через REST интерфейс OData. Часть Регистры сведений


Опубликовано: 23.08.2018

 

ПРЕДЫДУЩАЯ ЧАСТЬ. ЧАСТЬ ІІ. ДОКУМЕНТЫ

 

Если Вы уже знакомы с сериями об обмене справочниками и обмене документами , то уже догадываетесь/знаете, как мы “будем строить” наш обмен.

Перечислим процедуры и функции, которыми мы воспользуемся из предыдущих частей :

Функция ПолучитьКаналСвязиССерверомСбораДаних() // не изменится в этой статье, см. Часть І. Справочники Функция НормализироватьКОбмену(ЭтотРеквизит) // не изменится в этой статье, , см. Часть І. Справочники Функция СоединенияССерверомСбораДанныхУстановлено() Экспорт // не изменится в этой статье, , см. Часть І. Справочники Процедура ОтправитьНаСерверСбораДанных(СсылкаИсточник, DELETE = Ложь, ТипОбъекта = 0, // не изменится в этой статье, см. Часть ІІ. Документы БезКопии = Ложь, ОписаниеРеквизитовОтправки = Неопределено) Экспорт

 

Итак, для начала, в модуль набора записей регистра сведений в процедуру ПриЗаписи мы вставим следующее:

Если ОбменССерверомСбораДанных.СоединенияССерверомСбораДанныхУстановлено() Тогда // если база "подключена" к серверу Если ЭтотОбъект.Количество() Тогда // и если есть что передавать (ЭтотОбъект - это набор записей регистра) ОбменССерверомСбораДанных.ОтправитьНаСерверСбораДанных(ЭтотОбъект,, 3); // 3 - значит это регистр сведений КонецЕсли; КонецЕсли;

 

Далле через процедуру ОтправитьНаСерверСбораДанных мы попадем соответственно в такую функцию “доставки” записей регистра на сервер сбора данных (главную в этой статье):

 

 Функция РегистрСведенийДоставленоУспешно(НаборЗаписей, DELETE, Тень = Ложь)

 

Функция РегистрСведенийДоставленоУспешно(НаборЗаписей, DELETE, Тень = Ложь) Связь = ПолучитьКаналСвязиССерверомСбораДаних(); // служебное - см. Часть І. Справочники ИмяРегистра = НаборЗаписей.Метаданные().Имя; Если Тень Тогда ИмяРегистра = СтрЗаменить(ИмяРегистра,"_с_",""); КонецЕсли; АдресРесурса = "/" + Связь.Порт + "/odata/standard.odata/InformationRegister_" + ИмяРегистра; Соединение = Новый HTTPСоединение(Связь.Сервер); ЗаголовокHTTP = Новый Соответствие(); ТекстШапкиЗапроса = "<?xml version=""1.0"" encoding=""UTF-8""?> |<entry xmlns=""http://www.w3.org/2005/Atom"" | xmlns:d=""http://schemas.microsoft.com/ado/2007/08/dataservices"" | xmlns:m=""http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"" | xmlns:georss=""http://www.georss.org/georss"" | xmlns:gml=""http://www.opengis.net/gml""> |<category term=""StandardODATA.InformationRegister_" + ИмяРегистра + """ scheme=""http://schemas.microsoft.com/ado/2007/08/dataservices/scheme""/> |<title type=""text""/> |<content type=""application/xml""> |<m:properties xmlns:d=""http://schemas.microsoft.com/ado/2007/08/dataservices"" xmlns:m=""http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"">"; // каждая запись будет доставляться отдельно Для Каждого кЗапись Из НаборЗаписей Цикл Если Константы.СерверСбораДанныхОфлайн.Получить() И (НЕ Тень) Тогда //СоздатьТеневуюКопиюРегистраСведенийДляОтложеннойОправки(НаборЗаписей, кЗапись); // отложенная отправка Продолжить; КонецЕсли; // чтобы успешно доставить запись сначала очистим данные по ключевым полям хАдресРесурса = АдресРесурса; хСписокСтандартов = СоздатьОписанияОбязательнихРеквизитовРегистраСведений(НаборЗаписей, кЗапись); // новое служебное - смотри далее хСписокИзмерений = СоздатьОписанияЗаписиРегистра(НаборЗаписей, кЗапись, "Измерения"); // новое служебное - смотри далее Если хСписокСтандартов.Количество() ИЛИ хСписокИзмерений.Количество() Тогда хАдресРесурса = хАдресРесурса + "("; Итератор = 1; Для Каждого хОписаниеРеквизита ИЗ хСписокСтандартов Цикл хАдресРесурса = хАдресРесурса + хОписаниеРеквизита.Ключ + "='" + хОписаниеРеквизита.Значение + "'" + ?(Итератор = хСписокСтандартов.Количество() + хСписокИзмерений.Количество(),"",","); Итератор = Итератор + 1; КонецЦикла; Для Каждого хОписаниеИземерения ИЗ хСписокИзмерений Цикл хАдресРесурса = хАдресРесурса + хОписаниеИземерения.Ключ + "='" + хОписаниеИземерения.Значение + "'" + ?(Итератор = хСписокСтандартов.Количество() + хСписокИзмерений.Количество(),"",","); Итератор = Итератор + 1; КонецЦикла; хАдресРесурса = хАдресРесурса + ")"; КонецЕсли; Попытка хСоединение = Новый HTTPСоединение(Связь.Сервер); хЗапрос = Новый HTTPЗапрос(хАдресРесурса); хОтвет = хСоединение.ВызватьHTTPМетод("DELETE", хЗапрос); Исключение КонецПопытки; // следовательно, "предыдущая" запись удалена, если она была // создаем новую ТекстЗапроса = ТекстШапкиЗапроса; // соответствие стандартных реквизитов Для Каждого ОписаниеРеквизита ИЗ хСписокСтандартов Цикл // были описаны выше ТекстЗапроса = ТекстЗапроса + " | <d:" + ОписаниеРеквизита.Ключ + ">" + СокрЛП(ОписаниеРеквизита.Значение) + "</d:" + ОписаниеРеквизита.Ключ + ">"; КонецЦикла; // соответствие Измерений Для Каждого ОписаниеИзмерения ИЗ хСписокИзмерений Цикл // были описаны выше ТекстЗапроса = ТекстЗапроса + " | <d:" + ОписаниеИзмерения.Ключ + ">" + СокрЛП(ОписаниеИзмерения.Значение) + "</d:" + ОписаниеИзмерения.Ключ + ">"; КонецЦикла; // соответствие Ресурсов ОписаниеРесурсов = СоздатьОписанияЗаписиРегистра(НаборЗаписей, кЗапись, "Ресурсы"); Для Каждого ОписаниеРесурса ИЗ ОписаниеРесурсов Цикл ТекстЗапроса = ТекстЗапроса + " | <d:" + ОписаниеРесурса.Ключ + ">" + СокрЛП(ОписаниеРесурса.Значение) + "</d:" + ОписаниеРесурса.Ключ + ">"; КонецЦикла; // соответствие Реквизитов ОписаниеРеквизитов = СоздатьОписанияЗаписиРегистра(НаборЗаписей, кЗапись, "Реквизиты"); Для Каждого ОписаниеРеквизита ИЗ ОписаниеРеквизитов Цикл ТекстЗапроса = ТекстЗапроса + " | <d:" + ОписаниеРеквизита.Ключ + ">" + СокрЛП(ОписаниеРеквизита.Значение) + "</d:" + ОписаниеРеквизита.Ключ + ">"; КонецЦикла; ТекстЗапроса = ТекстЗапроса + " | </m:properties> | </content> |</entry>"; Попытка Запрос = Новый HTTPЗапрос(АдресРесурса, ЗаголовокHTTP); Запрос.УстановитьТелоИзСтроки(ТекстЗапроса); Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос); Исключение КонецПопытки; Если Ответ.КодСостояния <> 200 Тогда Если НЕ Тень Тогда //СоздатьТеневуюКопиюРегистраСведенийДляОтложеннойОправки(НаборЗаписей, кЗапись); // отложенная отправка КонецЕсли; Иначе Если Тень Тогда // если это отложена доставка НаборЗаписей.Очистить(); НаборЗаписей.Записать(Истина); КонецЕсли; КонецЕсли; КонецЦикла; КонецФункции

 

 

Список необходимых функций обозначенных комментарием “новое служебное”:

 

 Функция СоздатьОписанияОбязательнихРеквизитовРегистраСведений(НаборЗаписей, этаЗапись)

 

Функция СоздатьОписанияОбязательнихРеквизитовРегистраСведений(НаборЗаписей, этаЗапись); МетаданныеРегистра = НаборЗаписей.Метаданные(); ОписаниеСтандарныхРеквизитов = Новый Соответствие(); Для Каждого СтандартныйРеквизит ИЗ МетаданныеРегистра.СтандартныеРеквизиты Цикл Если СтандартныйРеквизит.Имя = "Период" И ЗначениеЗаполнено(этаЗапись.Период) Тогда ОписаниеСтандарныхРеквизитов.Вставить("Period", НормализироватьКОбмену(этаЗапись.Период)); ИначеЕсли СтандартныйРеквизит.Имя = "НомерСтроки" И ЗначениеЗаполнено(этаЗапись.НомерСтроки) Тогда ОписаниеСтандарныхРеквизитов.Вставить("НомерРядка", НормализироватьКОбмену(этаЗапись.НомерСтроки)); ИначеЕсли СтандартныйРеквизит.Имя = "Регистратор" И ЗначениеЗаполнено(этаЗапись.Регистратор) Тогда ОписаниеСтандарныхРеквизитов.Вставить("GUID_регистратора", Строка(этаЗапись.Регистратор.УникальныйИдентификатор())); // ручное измерение - регистратор не передаем (документа нету) КонецЕсли; КонецЦикла; Возврат ОписаниеСтандарныхРеквизитов КонецФункции

 

 

 Функция СоздатьОписанияЗаписиРегистра(НаборЗаписей, ЭтаЗапись, КоллекцияМетаданныхКОписанию)

 

Функция СоздатьОписанияЗаписиРегистра(НаборЗаписей, ЭтаЗапись, КоллекцияМетаданныхКОписанию) МетаданныеРегистра = НаборЗаписей.Метаданные(); ОписаниеКоллекции = Новый Соответствие(); Для Каждого ЕлКоллекции ИЗ МетаданныеРегистра[КоллекцияМетаданныхКОписанию] Цикл Если Строка(ЕлКоллекции.Тип) = "Число" ИЛИ Строка(ЕлКоллекции.Тип) = "Строка" ИЛИ Строка(ЕлКоллекции.Тип) = "Булево" ИЛИ Строка(ЕлКоллекции.Тип) = "Дата" Тогда ОписаниеКоллекции.Вставить(ЕлКоллекции.Имя, НормализироватьКОбмену(ЭтаЗапись[ЕлКоллекции.Имя])); Иначе Попытка ОписаниеКоллекции.Вставить(ЕлКоллекции.Имя + "_Key", Строка(ЭтаЗапись[ЕлКоллекции.Имя].УникальныйИдентификатор())); Исключение Попытка ОписаниеКоллекции.Вставить(ЕлКоллекции.Имя, Строка(ЭтаЗапись[ЕлКоллекции.Имя])); Исключение ОписаниеКоллекции.Вставить(ЕлКоллекции.Имя, ""); КонецПопытки; КонецПопытки; КонецЕсли; КонецЦикла; Возврат ОписаниеКоллекции КонецФункции

 

Вот и все – единственный нюанс передачи регистров, перед тем как передать запись надо подготовить под нее место – удалить уже существующую на сервере (если она есть).

 

<<< В части IV (последней)  опишем конвертацию “на ходу” по протоколу OData >>>

 

Спасибо, что дочитали до конца! ????

rss