Как лучше сделать синхронизацию между базами 1С без использования файлов выгрузок?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Синхронизация данных между информационными базами 1С — классическая задача, с которой сталкивается любой разработчик. Традиционный обмен через файлы выгрузки (XML, ZIP) на диске или FTP-сервере постепенно уходит в прошлое. Такие процессы часто страдают из-за монопольного доступа к файлам, обрывов сетевого соединения при передаче и задержек в актуализации данных.

В этой статье мы подробно разберем, как организовать надежный двусторонний бесфайловый обмен данными между доработанными конфигурациями (например, 1С:Бухгалтерия предприятия 3.0 и 1С:Зарплата и управление персоналом 3.1) для нетиповых документов. Мы детально проанализируем различные архитектурные подходы, разберем конкретные примеры реализации и выясним причины, по которым те или иные методы подходят под конкретные объемы данных.

Постановка задачи и анализ условий

Рассмотрим следующую рабочую ситуацию: требуется настроить двусторонний обмен нетиповыми документами между двумя доработанными базами 1С. Объем передаваемых данных невелик — всего 1 документ в месяц, содержащий табличную часть на 50–100 строк. Ключевое требование пользователя — синхронизация должна запускаться «по кнопке» прямо из формы документа.

Для реализации такой задачи существует несколько ключевых технологий:

  1. Прямое подключение через COM-соединение.
  2. Разработка собственных HTTP-сервисов или Web-сервисов.
  3. Использование стандартного интерфейса OData (REST API).
  4. Синхронизация через планы обмена с использованием формата EnterpriseData напрямую через веб-сервисы (без записи файлов на диск).

Выясним плюсы и минусы каждого подхода, а также пошагово разберем их программную реализацию.

---

Вариант 1. Использование HTTP-сервисов (REST API + JSON) — Рекомендуемый метод

Для небольшого объема данных (один или несколько документов по требованию) создание собственного HTTP-сервиса является наиболее гибким, быстрым и стабильным решением. При нажатии кнопки на форме документа база-источник сериализует данные в формат JSON и отправляет прямой POST-запрос в базу-приемник. База-приемник мгновенно обрабатывает запрос, записывает документ и сразу возвращает результат.

Преимущества метода:

Шаг 1. Создание HTTP-сервиса в базе-приемнике

В конфигураторе базы-приемника добавим новый объект метаданных 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;
    КонецПопытки;
    
    Возврат Ответ;
    
КонецФункции

Шаг 2. Написание кода отправки на форме документа в базе-источнике

Рассмотрим, как реализовать отправку данных по кнопке на форме документа в базе-источнике. Нам потребуется преобразовать документ в структуру, сериализовать в 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 Тогда
            Сообщить("Синхронизация успешно выполнена!");
        Иначе
            ВызватьИсключение "Ошибка сервера: " + Ответ.ПолучитьТелоКакСтроку();
        КонецЕсли;
    Исключение
        ЗаписьЖурналаРегистрации("СинхронизацияДанных", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
        ВызватьИсключение "Не удалось выполнить синхронизацию: " + ОписаниеОшибки();
    КонецПопытки;
    
КонецПроцедуры

---

Вариант 2. Стандартный интерфейс OData (REST-интерфейс 1С)

Если нет желания программировать HTTP-сервисы в базе-приемнике вручную, проанализируем встроенную альтернативу — OData. Платформа 1С умеет автоматически генерировать REST-интерфейс ко всем объектам метаданных при публикации базы на веб-сервере.

Особенности использования OData:

Посмотрим на пример отправки POST-запроса через OData для создания элемента справочника или документа:


// Пример URL-адреса OData для добавления нового нетипового документа:
// http://server/base_receiver/odata/standard.odata/Document_НашНетиповойДокумент

---

Вариант 3. Интеграция через планы обмена БСП напрямую (без файлов)

Если в базах внедрена Библиотека стандартных подсистем (БСП), мы можем использовать типовую синхронизацию, но настроить ее так, чтобы обмен происходил напрямую через Web-сервис или напрямую в память (по протоколам HTTP/HTTPS), полностью минуя физические файлы.

Разберем по шагам, как настроить и вызвать такой обмен по кнопке из формы документа:

  1. Создание правил обмена: В специализированной конфигурации «Конвертация данных 2.0» (или 3.0 для формата EnterpriseData) создаем правила конвертации для нашего нетипового документа.
  2. Загрузка правил в План обмена: В обеих базах настраиваем узел плана обмена и загружаем туда подготовленные правила обмена.
  3. Регистрация изменений: При изменении документа платформа автоматически (или программно) регистрирует изменения на узле плана обмена.
  4. Программный вызов синхронизации: При нажатии кнопки на форме документа мы регистрируем именно этот документ и принудительно запускаем процедуру обмена БСП.

Проанализируем пример программного запуска синхронизации для конкретного документа через встроенные механизмы БСП:


&НаСервере
Процедура СинхронизироватьДокументЧерезБСП(ВыбранныйДокумент)
    
    // Находим узел плана обмена для базы-приемника
    СсылкаНаУзел = ПланыОбмена.НашПланОбмена.НайтиПоКоду("ЗУП");
    
    Если СсылкаНаУзел.Пустая() Тогда
        ВызватьИсключение "Не найден узел плана обмена для интеграции!";
    КонецЕсли;
    
    // Регистрируем к обмену только текущий документ
    ПланыОбмена.ЗарегистрироватьИзменения(СсылкаНаУзел, ВыбранныйДокумент);
    
    // Задаем параметры обмена для БСП
    ПараметрыОбмена = Новый Структура;
    ПараметрыОбмена.Вставить("ВыполнитьВыгрузку", Истина);
    ПараметрыОбмена.Вставить("ВыполнитьЗагрузку", Истина);
    
    // Вызов стандартного метода БСП для прямого обмена по веб-сервису
    Попытка
        ОбменДаннымиСервер.ВыполнитьОбменДаннымиДляУзлаИнформационнойБазы(СсылкаНаУзел, ПараметрыОбмена);
        Сообщить("Синхронизация БСП успешно завершена.");
    Исключение
        Сообщить("Ошибка обмена БСП: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

---

Почему не рекомендуется использовать COM-соединение?

В процессе обсуждения часто всплывает идея использовать прямое COMСоединение (через V83.COMConnector). Настоятельно рекомендуем отказаться от этой технологии по следующим причинам:

---

Современная альтернатива: Сервисы интеграции (1С:Шина)

Если в будущем планируется масштабировать систему интеграции и связывать множество различных баз данных без использования файлов, рекомендуем обратить внимание на новые механизмы платформы, начиная с версии 8.3.18 — Сервисы интеграции.

Этот механизм обеспечивает асинхронную гарантированную доставку сообщений с использованием внешних брокеров (например, 1С:Шина или систем класса RabbitMQ). Платформа сама следит за тем, доставлено ли сообщение. Если база-приемник временно недоступна, пакет данных не пропадет, а останется в очереди и применится автоматически сразу после восстановления связи, полностью избавляя разработчика от необходимости писать код повторных попыток отправки.

Выводы и рекомендации

Резюмируя проведенный анализ, выделим оптимальные решения:

← На главную