Меня зовут Максим, я программист 1С в компании Programming Store.
В статье рассмотрим вариант обмена данными через http-сервисы с помощью подсистемы «Домены данных».
Подсистема «Домены данных» представляет собой блок общих модулей и справочника, с помощью которого происходит обмен данными в упрощенном режиме. Благодаря данной подсистеме, можно настраивать поля для выгрузки, их представление, тип и т.д. Также можно настраивать для каждой базы поля, которые необходимо получить, и у каждой базы могут свои нужные им поля.
В данном случае у нас есть мастер-база (далее МБ), которая отдает данные по запросу, и базы-приемники (далее «Приемники»), которые получают и обрабатывают данные.
В каждой базе есть справочник «Домены данных», но в МБ этот справочник отличается по структуре от аналогичного справочника в «Приемниках».
В МБ справочник «Домены данных» выглядит так:
В этом случае запросом выбираются данные из справочника «Физических лиц» и записываются в JSON. Справочник «Домены данных» хранит «Дата контракт полей», которая выгружается. При добавлении нового поля в выгрузку любого домена данных необходимо добавить поле в структуру домена данных в нужную функцию модуля менеджера справочника.
// Дата контракт домена данных физические лица.
//
// Возвращаемое значение:
// Структура - Дата контракт домена данных физические лица:
// * uuid - Строка - глобальный идентификатор физического лица
// * name - Строка - полное наименование
// * deleted - Булево - пометка удаления
// * lastName - Строка - фамилия
// * firstName - Строка - имя
// * patronymic - Строка - отчество
// * birthDate - Строка - дата рождения
// * gender - Строка - пол
// * domainName - Строка - имя доменной учетки AD
// * phone - Строка - Телефон
// * email - Строка - Адрес электронной почты
// * dateOfEmployment - Дата - Дата первичного трудоустройства
Функция ДатаКонтрактДоменаДанныхФизическиеЛица() Экспорт
Результат = Новый Структура;
Результат.Вставить("uuid", "");
Результат.Вставить("name", "");
Результат.Вставить("deleted", Ложь);
Результат.Вставить("lastName", "");
Результат.Вставить("firstName", "");
Результат.Вставить("patronymic", "");
Результат.Вставить("birthDate", "");
Результат.Вставить("gender", "");
Результат.Вставить("domainName", "");
Результат.Вставить("phone", "");
Результат.Вставить("email", "");
Результат.Вставить("dateOfEmployment", "");
Возврат Результат;
КонецФункции
В «Приемниках» есть регламентное задание, которое обращается к МБ и забирает данные. У всех доменов данных одно регламентное задание, в нем параметром является наименование домена данных, по которому необходимо получить данные. Так выглядит запрос изменений в «Приемниках»:
Функция ЗапросИзмененийДоменаДанных(ДоменДанных, ДатаЗапросаИзменений, Метод, Лимит = 0, Курсор = 0) Экспорт
Результат = Новый Структура;
Результат.Вставить("Успешно", Истина);
Результат.Вставить("Ошибки", Новый Массив);
Результат.Вставить("КодСостояния", 0);
Результат.Вставить("МассивИзменений", Новый Массив);
Результат.Вставить("Курсор", 0);
ИмяДомена = НРег(Строка(ДоменДанных));
ДатаВФорматеISO = ЗаписатьДатуJSON(ДатаЗапросаИзменений, ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.УниверсальнаяДата);
СтрокаМетода = СтрШаблон("hs/nsi/%1?domen=%2&date=%3", Метод, ИмяДомена, ДатаВФорматеISO);
Если ЗначениеЗаполнено(Лимит) Тогда
СтрокаМетода = СтрокаМетода + "&limit=" + Лимит;
КонецЕсли;
// TODO переиспользовать соединение, открытое ранее
Соединение = Новый HTTPСоединение(ДоменДанных.АдресСервера, , ДоменДанных.Логин, ДоменДанных.Пароль, , 60);
HTTPЗапрос = Новый HTTPЗапрос;
HTTPЗапрос.АдресРесурса = СтрокаМетода;
Попытка
HTTPОтвет = Соединение.ВызватьHTTPМетод("GET", HTTPЗапрос);
Результат.КодСостояния = HTTPОтвет.КодСостояния;
Если Результат.КодСостояния >= 200
И Результат.КодСостояния < 300 Тогда
Ответ = лпОбщегоНазначения.ПрочитатьТелоJSON(HTTPОтвет); // Структура
Результат.МассивИзменений = Ответ.result; // Массив из Структура
Результат.Курсор = Ответ.cursor; // Число
Иначе
Результат.Успешно = Ложь;
ТекстОшибки = "Сервер вернул код состояния " + HTTPОтвет.КодСостояния;
Результат.Ошибки.Добавить(ТекстОшибки);
КонецЕсли;
Исключение
Результат.Успешно = Ложь;
ТекстОшибки = "Не удалось отправить запрос на сервер: " + ОписаниеОшибки();
Результат.Ошибки.Добавить(ТекстОшибки);
КонецПопытки;
Возврат Результат;
КонецФункции
В данном случае мы передаем в параметре имя домена данных, по которому есть нужные нам данные, также можно указать количество данных для выборки. В результате «Приемники» по http-сервису стучаться к МБ и передают параметры для выборки. В МБ данные параметры обрабатываются и формируется конечный запрос «Домена данных», где указанный запрос выполняется и записывается в массив структур. Далее массив структур записывается в JSON и передается в Приемники, где данные обрабатываются и записываются.
Текст метода http-сервиса в МБ:
Процедура ЗаполнитьОтветНаЗапросПолученияДоменаДанных(Запрос, Ответ, ДоменДанных)
Попытка
Лимит = 100;
СсылкаКурсор = "";
МассивФильтров = Новый Массив; // Массив из Структура
КонвертироватьПараметрыЗапроса(Запрос.ПараметрыЗапроса, ДоменДанных, МассивФильтров, Лимит, СсылкаКурсор);
Исключение
Ответ.КодСостояния = 400;
Ответ.Причина = "Ошибка в параметрах запроса: " + ОписаниеОшибки();
КонецПопытки;
Если Ответ.КодСостояния = 200 Тогда
Попытка
СтруктураВыборки = лпОтправкаДоменовДанных.ВыборкаОбъектовДоменаДанных(ДоменДанных, МассивФильтров, Лимит, СсылкаКурсор);
ДатаКонтракт = Справочники.лпДоменыДанных.ДатаКонтрактДоменаДанных(ДоменДанных);
МассивДанных = Справочники.лпДоменыДанных.ЗаполнитьДатаКонтрактИзСтрокДерева(ДатаКонтракт, СтруктураВыборки.ДеревоОбъектов.Строки);
Результат = Новый Структура;
Результат.Вставить("result", МассивДанных);
Результат.Вставить("uuidcursor", СтруктураВыборки.НовыйСсылкаКурсор);
Результат = лпОбщегоНазначения.ПреобразоватьНедопустимыеТипыJSON(Результат);
лпОбщегоНазначения.ЗаписатьТелоJSON(Ответ, Результат);
Исключение
Ответ.КодСостояния = 500;
Ответ.Причина = "Ошибка при получении данных на сервере: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
КонецПроцедуры
В этой функции происходит обращение к запросу домена данных, далее запрос форматируется и накладываются условия, переданные из «Приемников»:
Функция ВыборкаОбъектовДоменаДанных(ДоменДанных, МассивФильтров, Лимит, СсылкаКурсор = "") Экспорт
Результат = Новый Структура;
Результат.Вставить("ДеревоОбъектов", Новый ДеревоЗначений());
Результат.Вставить("НовыйСсылкаКурсор", "");
ОписаниеДомена = лпДоменыДанныхПовтИсп.ОписаниеДомена(ДоменДанных);
Если НЕ ЗначениеЗаполнено(ОписаниеДомена.ТекстЗапросаТекущихДанных) Тогда
ВызватьИсключение
"Не указан текст запроса текущих данных для этого домена данных";
КонецЕсли;
ТекстЗапроса = ОписаниеДомена.ТекстЗапросаТекущихДанных;
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ВЫБРАТЬ ПЕРВЫЕ 100", "ВЫБРАТЬ ПЕРВЫЕ " + (Лимит + 1));
Запрос = Новый Запрос;
МассивУсловийОтбора = Новый Массив; // Массив из Строка
Для Каждого Фильтр Из МассивФильтров Цикл
ИмяПараметра = СтрЗаменить(Фильтр.ИмяФильтра, ".", "");
Запрос.УстановитьПараметр(ИмяПараметра, Фильтр.ЗначениеФильтра);
УсловиеОтбора = СтрШаблон("%1 = &%2", Фильтр.ИмяФильтра, ИмяПараметра);
МассивУсловийОтбора.Добавить(УсловиеОтбора);
КонецЦикла;
ТекстОтбора = СтрСоединить(МассивУсловийОтбора, " И ");
ТекстОтбора = ?(ЗначениеЗаполнено(ТекстОтбора), ТекстОтбора, "ИСТИНА");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&УсловиеОтбора", ТекстОтбора);
Запрос.Текст = ТекстЗапроса;
ДеревоОбъектов = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
Если ДеревоОбъектов.Строки.Количество() > Лимит Тогда
ПоследняяСтрока = ДеревоОбъектов.Строки[ДеревоОбъектов.Строки.Количество() - 1];
НовыйСсылкаКурсор = ПоследняяСтрока.uuid; // Строка
Результат.НовыйСсылкаКурсор = НовыйСсылкаКурсор;
ДеревоОбъектов.Строки.Удалить(ПоследняяСтрока);
КонецЕсли;
Результат.ДеревоОбъектов = ДеревоОбъектов;
Возврат Результат;
КонецФункции
Пример файла JSON, который передается в «Приемники»:
"result": [
{
"uuid": "51729b0e-4e37-11ef-8db9-000c29e62f1c",
"name": "Лопатнев П С ",
"deleted": false,
"lastName": "Лопатнев",
"firstName": " ",
"patronymic": " ",
"birthDate": " :00:00",
"gender": "Мужской",
"domainName": "",
"phone": " ",
"email": " ",
"dateOfEmployment": "2024-07-30T00:00:00"
},
{
"uuid": "29f59356-4f07-11ef-8db9-000c29e62f1c",
"name": "Горохова К А ",
"deleted": false,
"lastName": "Горохова",
"firstName": " ",
"patronymic": " ",
"birthDate": "1992-07-13T00:00:00",
"gender": "Женский",
"domainName": "",
"phone": " ",
"email": " ",
"dateOfEmployment": "2024-08-01T00:00:00"
},
Итак, в статье был разобран эффективный механизм обмена данными между мастер-базой и базами-приемниками через подсистему «Домены данных», используя HTTP-сервисы. Гибкость настройки полей для выгрузки данных и их представления позволяет адаптировать систему под специфические требования каждой базы. Структура справочника «Домены данных» обеспечивает организованное хранение информации о физических лицах, что способствует упрощению процессов обработки и управления данными.
Вступайте в нашу телеграмм-группу Инфостарт