При необходимости настроить регулярный обмен данными между двумя базами 1С, находящимися на одном сервере, разработчики часто сталкиваются с выбором технологии. Если одна из баз не содержит БСП (Библиотеку стандартных подсистем), а вторая — на ней основана, стандартные механизмы обмена могут быть недоступны. В такой ситуации использование HTTP-сервисов в сочетании с форматом JSON является наиболее современным, быстрым и гибким решением. Рассмотрим подробно, как реализовать этот процесс, избегая использования устаревшего COM-соединения, которое может быть недоступно в среде Linux или при различии версий платформы.
Проанализируем основные варианты. Web-сервисы (SOAP) жестко типизированы и используют XML через пакеты XDTO. Это надежно, но избыточно для простых обменов. COM-соединение крайне чувствительно к разрядности систем и версиям платформы. Оптимальным решением для современных систем 1С v8.3 являются HTTP-сервисы. Они работают напрямую по протоколу HTTP, позволяют передавать данные в «легком» формате JSON и нативно поддерживаются платформой 1С.
Разберем, как выгрузить данные из регистра сведений. Основная идея заключается в том, чтобы выбрать нужные записи запросом, поместить их в структуру или массив, а затем сериализовать в JSON. Посмотрим на пример кода, который выполняет эту задачу:
// Создаем массив для хранения структур записей
МассивДанных = Новый Массив;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РегистрСведений.Период КАК Период,
| РегистрСведений.Контрагент.Наименование КАК КонтрагентНаименование,
| РегистрСведений.Контрагент.ИНН КАК КонтрагентИНН,
| РегистрСведений.Сумма КАК Сумма
|ИЗ
| РегистрСведений.ДанныеДляОбмена КАК РегистрСведений";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Каждую строку превращаем в структуру
СтрокаДанных = Новый Структура;
СтрокаДанных.Вставить("Period", Выборка.Период);
СтрокаДанных.Вставить("CounterpartyName", Выборка.КонтрагентНаименование);
СтрокаДанных.Вставить("CounterpartyINN", Выборка.КонтрагентИНН);
СтрокаДанных.Вставить("Amount", Выборка.Сумма);
МассивДанных.Добавить(СтрокаДанных);
КонецЦикла;
// Сериализация в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, МассивДанных);
СтрокаJSON = ЗаписьJSON.Закрыть();
Важно помнить, что 1С автоматически сериализует даты в формат ISO 8601. Это удобно, так как база-приемник сможет корректно распознать их при чтении.
Если структура данных сложная, можно использовать возможности платформенного XDTO для генерации JSON. Выясним, как это упрощает работу. Вместо ручного создания структур мы можем использовать СериализаторXDTO. Рассмотрим пример выгрузки таблицы значений:
Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
// Предположим, ТЗ - это результат выгрузки запроса
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
Сериализатор.ЗаписатьJSON(ЗаписьJSON, ТаблицаДанных);
СтрокаJSON = ЗаписьJSON.Закрыть();
Этот метод хорош тем, что платформа сама заботится о соответствии типов, однако на стороне приемника потребуется аналогичная ФабрикаXDTO или ручной парсинг.
В базе с БСП необходимо создать новый объект метаданных HTTP-сервис. Укажите имя (например, ExchangeService) и корневой URL (/exchange). Создайте шаблон URL и метод POST для приема данных. Проанализируем пример функции-обработчика запроса:
Функция PostData(Запрос)
// Читаем тело JSON из HTTP-запроса
СтрокаJSON = Запрос.ПолучитьТелоКакСтроку();
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
// Десериализуем данные обратно в массив структур
Данные = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
// Начинаем транзакцию для записи данных
НачатьТранзакцию();
Попытка
Для Каждого СтрокаИзДанных Из Данные Цикл
// Логика поиска и создания контрагента
КонтрагентСсылка = НайтиИлиСоздатьКонтрагента(СтрокаИзДанных.CounterpartyINN, СтрокаИзДанных.CounterpartyName);
// Заполнение документа или регистра в базе-приемнике
// ...
КонецЦикла;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Возврат Новый HTTPСервисОтвет(500); // Ошибка сервера
КонецПопытки;
Возврат Новый HTTPСервисОтвет(200); // Успех
КонецФункции
Одной из самых сложных задач является сопоставление объектов. Если базы ранее не были синхронизированы, идентификаторы GUID (Уникальный идентификатор ссылки) у одинаковых контрагентов будут разными. Разберем стратегии решения этой проблемы:
ИНН + КПП. Для партнеров — наименование или номер телефона.УникальныйИдентификатор из первой базы и сохранять его в базе-приемнике в дополнительном реквизите или регистре сведений «Соответствие объектов». Это позволит при следующих обменах однозначно находить нужный элемент.Справочники.Контрагенты.СоздатьЭлемент(), заполняем обязательные реквизиты и записываем.Поскольку обмен должен работать ежедневно, в базе-источнике (без БСП) следует создать Регламентное задание. Оно будет запускать процедуру, которая собирает данные и отправляет HTTP-запрос к базе-приемнику. Для отправки используйте объект HTTPСоединение:
Соединение = Новый HTTPСоединение("server_address", , "user", "password");
ЗапросHTTP = Новый HTTPЗапрос("/BaseName/hs/exchange/data");
ЗапросHTTP.УстановитьТелоИзСтроки(СтрокаJSON);
Ответ = Соединение.ОтправитьДляОбработки(ЗапросHTTP);
Если Ответ.КодСостояния <> 200 Тогда
ЗаписьЖурналаРегистрации("Обмен", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка обмена: " + Ответ.КодСостояния);
КонецЕсли;
Проанализируем важные моменты, которые часто упускают при разработке обмена:
Basic-авторизацию. Создайте в базе-приемнике специального пользователя с ограниченными правами, достаточными только для работы HTTP-сервиса и записи нужных объектов.Журнал регистрации. В случае ошибки в JSON-структуре или недоступности сервера вы сможете быстро локализовать проблему.Таким образом, мы рассмотрели полный цикл создания обмена. Использование HTTP-сервисов и JSON делает вашу систему масштабируемой и независимой от специфических настроек операционной системы или версий COM-компонент.