Синхронизация данных между информационными базами 1С — классическая задача, с которой сталкивается любой разработчик. Традиционный обмен через файлы выгрузки (XML, ZIP) на диске или FTP-сервере постепенно уходит в прошлое. Такие процессы часто страдают из-за монопольного доступа к файлам, обрывов сетевого соединения при передаче и задержек в актуализации данных.
В этой статье мы подробно разберем, как организовать надежный двусторонний бесфайловый обмен данными между доработанными конфигурациями (например, 1С:Бухгалтерия предприятия 3.0 и 1С:Зарплата и управление персоналом 3.1) для нетиповых документов. Мы детально проанализируем различные архитектурные подходы, разберем конкретные примеры реализации и выясним причины, по которым те или иные методы подходят под конкретные объемы данных.
Рассмотрим следующую рабочую ситуацию: требуется настроить двусторонний обмен нетиповыми документами между двумя доработанными базами 1С. Объем передаваемых данных невелик — всего 1 документ в месяц, содержащий табличную часть на 50–100 строк. Ключевое требование пользователя — синхронизация должна запускаться «по кнопке» прямо из формы документа.
Для реализации такой задачи существует несколько ключевых технологий:
COM-соединение.HTTP-сервисов или Web-сервисов.OData (REST API).EnterpriseData напрямую через веб-сервисы (без записи файлов на диск).Выясним плюсы и минусы каждого подхода, а также пошагово разберем их программную реализацию.
---
Для небольшого объема данных (один или несколько документов по требованию) создание собственного HTTP-сервиса является наиболее гибким, быстрым и стабильным решением. При нажатии кнопки на форме документа база-источник сериализует данные в формат JSON и отправляет прямой POST-запрос в базу-приемник. База-приемник мгновенно обрабатывает запрос, записывает документ и сразу возвращает результат.
Преимущества метода:
В конфигураторе базы-приемника добавим новый объект метаданных HTTP-сервисы. Назовем его ОбменДокументами, укажем корневой URL: exchange.
Добавим шаблон URL: /v1/document и для этого шаблона определим метод POST с обработчиком в модуле сервиса.
Разберем пример кода серверного метода HTTP-сервиса в базе-приемнике для создания документа:
Функция ДокументыPOST(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
// Чтение входящего JSON
СтрокаJSON = Запрос.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
ДанныеДокумента = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// Начинаем транзакцию для безопасной записи
НачатьТранзакцию();
Попытка
НовыйДок = Документы.НашНетиповойДокумент.СоздатьДокумент();
НовыйДок.Дата = ТекущаяДата();
НовыйДок.Комментарий = "Создан автоматически через HTTP-сервис. Оригинальный номер: " + ДанныеДокумента.Номер;
// Заполнение табличной части
Для Каждого СтрокаДанных Из ДанныеДокумента.Товары Цикл
НоваяСтрока = НовыйДок.Товары.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию(СтрокаДанных.Номенклатура);
НоваяСтрока.Количество = СтрокаДанных.Количество;
НоваяСтрока.Цена = СтрокаДанных.Цена;
КонецЦикла;
НовыйДок.Записать(РежимЗаписиДокумента.Проведение);
ЗафиксироватьТранзакцию();
// Формируем успешный ответ
Результат = Новый Структура("Success, DocumentRef", Истина, Строка(НовыйДок.Ссылка));
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, Результат);
Ответ.УстановитьТелоИзСтроки(Запись.Закрыть(), КодировкаТекста.UTF8);
Исключение
ОтменитьТранзакцию();
Результат = Новый Структура("Success, ErrorDescription", Ложь, ОписаниеОшибки());
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, Результат);
Ответ.УстановитьТелоИзСтроки(Запись.Закрыть(), КодировкаТекста.UTF8);
Ответ.КодСостояния = 500;
КонецПопытки;
Возврат Ответ;
КонецФункции
Рассмотрим, как реализовать отправку данных по кнопке на форме документа в базе-источнике. Нам потребуется преобразовать документ в структуру, сериализовать в JSON и отправить с помощью объекта платформы HTTPСоединение.
&НаСервере
Процедура ОтправитьДокументНаСервер(ДокументСсылка)
// Формируем структуру для отправки
СтруктураДокумента = Новый Структура;
СтруктураДокумента.Вставить("Номер", ДокументСсылка.Номер);
СтруктураДокумента.Вставить("Дата", ДокументСсылка.Дата);
МассивТоваров = Новый Массив;
Для Каждого СтрокаТЧ Из ДокументСсылка.Товары Цикл
СтрокаТовара = Новый Структура("Номенклатура, Количество, Цена",
СтрокаТЧ.Номенклатура.Наименование,
СтрокаТЧ.Количество,
СтрокаТЧ.Цена
);
МассивТоваров.Добавить(СтрокаТовара);
КонецЦикла;
СтруктураДокумента.Вставить("Товары", МассивТоваров);
// Сериализация в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураДокумента);
ТелоЗапроса = ЗаписьJSON.Закрыть();
// Настройка соединения
Сервер = "192.168.1.100"; // IP-адрес или имя веб-сервера базы-приемника
Порт = 80;
Пользователь = "ExchangeUser";
Пароль = "StrongPassword123";
НТТРСоединение = Новый HTTPСоединение(Сервер, Порт, Пользователь, Пароль);
HTTPЗапрос = Новый HTTPЗапрос("/base_receiver/hs/exchange/v1/document");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Попытка
Ответ = НТТРСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если Ответ.КодСостояния = 200 Тогда
Сообщить("Синхронизация успешно выполнена!");
Иначе
ВызватьИсключение "Ошибка сервера: " + Ответ.ПолучитьТелоКакСтроку();
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации("СинхронизацияДанных", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
ВызватьИсключение "Не удалось выполнить синхронизацию: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
---
Если нет желания программировать HTTP-сервисы в базе-приемнике вручную, проанализируем встроенную альтернативу — OData. Платформа 1С умеет автоматически генерировать REST-интерфейс ко всем объектам метаданных при публикации базы на веб-сервере.
Особенности использования OData:
УстановитьСоставСтандартногоИнтерфейсаOData(), чтобы не открывать доступ ко всем конфиденциальным таблицам./Post().Посмотрим на пример отправки POST-запроса через OData для создания элемента справочника или документа:
// Пример URL-адреса OData для добавления нового нетипового документа:
// http://server/base_receiver/odata/standard.odata/Document_НашНетиповойДокумент
---
Если в базах внедрена Библиотека стандартных подсистем (БСП), мы можем использовать типовую синхронизацию, но настроить ее так, чтобы обмен происходил напрямую через Web-сервис или напрямую в память (по протоколам HTTP/HTTPS), полностью минуя физические файлы.
Разберем по шагам, как настроить и вызвать такой обмен по кнопке из формы документа:
EnterpriseData) создаем правила конвертации для нашего нетипового документа.Проанализируем пример программного запуска синхронизации для конкретного документа через встроенные механизмы БСП:
&НаСервере
Процедура СинхронизироватьДокументЧерезБСП(ВыбранныйДокумент)
// Находим узел плана обмена для базы-приемника
СсылкаНаУзел = ПланыОбмена.НашПланОбмена.НайтиПоКоду("ЗУП");
Если СсылкаНаУзел.Пустая() Тогда
ВызватьИсключение "Не найден узел плана обмена для интеграции!";
КонецЕсли;
// Регистрируем к обмену только текущий документ
ПланыОбмена.ЗарегистрироватьИзменения(СсылкаНаУзел, ВыбранныйДокумент);
// Задаем параметры обмена для БСП
ПараметрыОбмена = Новый Структура;
ПараметрыОбмена.Вставить("ВыполнитьВыгрузку", Истина);
ПараметрыОбмена.Вставить("ВыполнитьЗагрузку", Истина);
// Вызов стандартного метода БСП для прямого обмена по веб-сервису
Попытка
ОбменДаннымиСервер.ВыполнитьОбменДаннымиДляУзлаИнформационнойБазы(СсылкаНаУзел, ПараметрыОбмена);
Сообщить("Синхронизация БСП успешно завершена.");
Исключение
Сообщить("Ошибка обмена БСП: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
---
В процессе обсуждения часто всплывает идея использовать прямое COMСоединение (через V83.COMConnector). Настоятельно рекомендуем отказаться от этой технологии по следующим причинам:
---
Если в будущем планируется масштабировать систему интеграции и связывать множество различных баз данных без использования файлов, рекомендуем обратить внимание на новые механизмы платформы, начиная с версии 8.3.18 — Сервисы интеграции.
Этот механизм обеспечивает асинхронную гарантированную доставку сообщений с использованием внешних брокеров (например, 1С:Шина или систем класса RabbitMQ). Платформа сама следит за тем, доставлено ли сообщение. Если база-приемник временно недоступна, пакет данных не пропадет, а останется в очереди и применится автоматически сразу после восстановления связи, полностью избавляя разработчика от необходимости писать код повторных попыток отправки.
Резюмируя проведенный анализ, выделим оптимальные решения: