Обмен данными 1С — передача справочников, документов и остатков из одной программы 1С в другую или во внешнюю систему: из торговли в бухгалтерию, из магазинов в центральный офис, из 1С на сайт. Способов несколько, и они сильно различаются по цене настройки, надёжности и затратам на поддержку. Первая половина статьи — для владельца и бухгалтера: какие бывают способы и как выбрать. Вторая — для программиста: план обмена, код выгрузки и загрузки, типичные ошибки.
Когда говорят «обмен базами данных 1С», обычно имеют в виду один из вариантов ниже. Их можно комбинировать в одной базе.
В типовых конфигурациях на БСП есть готовый механизм «Синхронизация данных». Он настраивается без программирования: программа-партнёр, способ связи (прямое подключение, сетевой каталог, FTP, электронная почта), дата начала, отбор по организациям. Правила конвертации 1С поставляет вместе с релизом; в актуальных версиях обмены вроде УТ 11 — БП 3.0 идут через формат EnterpriseData. Лучший выбор для типовых программ с типовыми данными. Слабое место — доработки: свой реквизит синхронизация не передаст, пока его не добавят в правила.
КД2 — отдельная конфигурация, в которой программист сопоставляет метаданные двух баз и описывает, что во что превращается. Результат — XML-файл правил для обработки «Универсальный обмен данными в формате XML». Правила однонаправленные: для двустороннего обмена нужны два комплекта. КД2 живёт в обменах со старыми конфигурациями (УТ 10.3, БП 2.0, УПП) и при разовых переносах. Минусы — неудобная отладка обработчиков внутри правил и сверка правил после каждого обновления любой из сторон.
В КД3 между базами стоит общий формат EnterpriseData (XDTO-пакет). Каждая сторона отвечает только за свою половину: выгрузить свои объекты в формат и загрузить из формата. Правила превращаются в код общего модуля — менеджера обмена, их можно отлаживать обычным отладчиком. Так обмениваются БП 3.0, УТ 11, КА 2, ERP 2, УНФ. Нетиповой реквизит обычно передают, дописав правила в расширении; если подходящего поля в формате нет, приходится расширять сам формат, а это заметно дороже.
РИБ — копии одной конфигурации: главный узел и подчинённые. Главный передаёт данные и изменения конфигурации, подчинённые возвращают свои данные; отбором можно отдавать филиалу только его склад или организацию. Ограничения жёсткие: конфигурацию меняют только в главном узле, а подчинённый, не принявший обновление, перестаёт обмениваться. При одновременном изменении объекта в двух узлах по умолчанию остаётся версия главного.
Для сайта, CRM и приложений данные отдают по HTTP. HTTP-сервис (платформа 8.3.5+) — свой REST API внутри 1С. OData открывает объекты базы без кода, выбором состава. SOAP-веб-сервисы — старый вариант, который до сих пор требуют некоторые корпоративные системы. Всем нужна публикация на веб-сервере. Подробнее — в статьях про API 1С и про HTTP-сервис; для типовых сценариев есть услуги обмен 1С с сайтом и выгрузка на маркетплейсы.
Одна база открывает другую через V83.COMConnector и работает с её объектами почти как со своими. Только Windows; версия компоненты должна подходить к платформе базы-приёмника, разрядность — к вызывающему процессу. Годится для разовых переносов и мелких операций «здесь и сейчас», для регулярных больших объёмов медленно.
Одна база выгружает файл, другая загружает его обработкой. Связь между базами не нужна, файл видно глазами. Зато учёт того, что уже выгружено и что изменилось, поиск соответствий и обработка ошибок — целиком на вас. JSON встроен в платформу с 8.3.6.
| Способ | Когда подходит | Плюсы | Риски | Трудоёмкость доработки |
|---|---|---|---|---|
| Типовая синхронизация | Типовые программы, типовые данные | Без кода, обновляется с релизом | Не видит доработки, нужны совместимые релизы | Низкая |
| КД2 | Старые и нетиповые конфигурации, разовый перенос | Связывает почти любые конфигурации | Правила ломаются после обновлений | Средняя или высокая |
| КД3, EnterpriseData | Современные типовые с доработками | Правила — обычный код, стороны независимы | Нужно знать формат и механизм БСП | Средняя |
| РИБ | Филиалы на одной конфигурации | Передаёт всё, включая конфигурацию | Обновление только из центра | Низкая |
| HTTP, OData, SOAP | Сайт, CRM, внешние сервисы | Реальное время, стандартные протоколы | Веб-сервер, права, защита | Средняя |
| COM | Разовые операции в одной сети | Прямой доступ к объектам | Только Windows, версии, скорость | Низкая |
| Файлы | Программы не на 1С, нет связи | Просто и наглядно | Контроль изменений вручную | Растёт с объёмом |
Схема выбора короткая:
В 1С:Бухгалтерии обмен данными находится в разделе «Администрирование» → «Синхронизация данных», в УТ 11 и КА 2 — «НСИ и администрирование» → «Администрирование» → «Синхронизация данных». Порядок настройки обменов данными одинаковый:
Настройка для конкретных программ — в статье о синхронизации данных 1С, выбор между КД2 и КД3 — в статье о конвертации данных.
Типовая синхронизация, РИБ и обмены на КД стоят на одном объекте — плане обмена. Его узлы соответствуют базам-участникам, среди них есть предопределённый «ЭтотУзел». При включённой авторегистрации платформа сама отмечает изменение каждого объекта из состава плана для всех узлов, кроме текущего. Остаётся выгрузить отмеченное и снять отметку, когда вторая сторона подтвердит получение.
Ниже — минимальный обмен между двумя базами с одинаково устроенными переносимыми объектами. Коды узлов должны совпадать крест-накрест: «ЭтотУзел» филиала имеет тот же код, что узел филиала в центральной базе, и наоборот.
// Общий модуль ОбменСФилиаломСервер (флажок «Сервер»). Платформа 8.3.
// План обмена ОбменСФилиалом: в составе — переносимые справочники, документы
// и регистры, авторегистрация «Разрешить». Добавьте реквизит Главный (Булево):
// Истина у узла центральной базы в обеих базах. В обеих базах эти объекты
// должны быть одинаковыми: ЗаписатьXML и ПрочитатьXML переносят их «как есть».
//
// Пример вызова из регламентного задания:
// Узел = ПланыОбмена.ОбменСФилиалом.НайтиПоКоду("F01");
// ОбменСФилиаломСервер.ВыгрузитьИзменения(Узел, "\\srv\exchange\to_F01.xml");
// Выгружает в файл всё, что зарегистрировано к отправке в узел.
Процедура ВыгрузитьИзменения(УзелПолучатель, ИмяФайла) Экспорт
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайла, "UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
ЗаписьСообщения.НачатьЗапись(ЗаписьXML, УзелПолучатель);
Попытка
Выборка = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель,
ЗаписьСообщения.НомерСообщения);
Пока Выборка.Следующий() Цикл
ЗаписатьXML(ЗаписьXML, Выборка.Получить());
КонецЦикла;
ЗаписьСообщения.ЗакончитьЗапись();
Исключение
ЗаписьСообщения.ПрерватьЗапись();
ЗаписьXML.Закрыть();
ВызватьИсключение;
КонецПопытки;
ЗаписьXML.Закрыть();
КонецПроцедуры
// Загружает файл, полученный от другого узла.
Процедура ЗагрузитьИзменения(ИмяФайла) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяФайла);
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
Попытка
ЧтениеСообщения.НачатьЧтение(ЧтениеXML);
Исключение
ЧтениеXML.Закрыть();
ВызватьИсключение;
КонецПопытки;
// Квитанция: отправитель уже получил наши сообщения
// с номерами до НомерПринятого включительно.
ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель,
ЧтениеСообщения.НомерПринятого);
НачатьТранзакцию();
Попытка
Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл
Данные = ПрочитатьXML(ЧтениеXML);
// Коллизия: объект изменён и здесь, и у отправителя.
// Версию неглавного узла отвергаем: наша останется зарегистрированной
// и уйдёт отправителю при следующей выгрузке.
Если Не ЧтениеСообщения.Отправитель.Главный
И ПланыОбмена.ИзменениеЗарегистрировано(ЧтениеСообщения.Отправитель, Данные) Тогда
Продолжить;
КонецЕсли;
// Не регистрировать принятое обратно для отправителя.
Данные.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель;
Данные.ОбменДанными.Загрузка = Истина;
Данные.Записать();
КонецЦикла;
ЧтениеСообщения.ЗакончитьЧтение();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЧтениеСообщения.ПрерватьЧтение();
ЧтениеXML.Закрыть();
ВызватьИсключение;
КонецПопытки;
ЧтениеXML.Закрыть();
КонецПроцедуры
// Первичная регистрация: авторегистрация ловит только изменения,
// сделанные после создания узла. Старые данные отмечают вручную.
Процедура ЗарегистрироватьНоменклатуру(УзелПолучатель) Экспорт
ПланыОбмена.ЗарегистрироватьИзменения(УзелПолучатель,
Метаданные.Справочники.Номенклатура);
КонецПроцедуры
НачатьЗапись(ЗаписьXML, УзелПолучатель) пишет заголовок: коды узлов, номер сообщения и номер последнего сообщения, принятого от получателя, — квитанцию для второй стороны.ВыбратьИзменения(…, НомерСообщения) берёт всё зарегистрированное для узла и проставляет записям номер текущего сообщения. Регистрация не удаляется.ЗаписатьXML сериализует объект, набор записей или УдалениеОбъекта. Формат привязан к метаданным, поэтому для разных конфигураций он не годится.ИзменениеЗарегистрировано() ловит коллизию: объект изменили в обеих базах между сеансами. Без этой проверки версии могут меняться местами при каждом обмене, поэтому центральный узел помечают реквизитом Главный и делают приоритетным.УдалитьРегистрациюИзменений(Отправитель, НомерПринятого) снимает регистрацию только по подтверждённым сообщениям. Потерянный файл не страшен: изменения уйдут в следующем.ОбменДанными.Отправитель не даёт принятому объекту зарегистрироваться обратно для базы-источника.ОбменДанными.Загрузка = Истина — запись без бизнес-логики: типовой код в ПередЗаписью и ПриЗаписи проверяет флаг и выходит. Документы не проводятся: движения передают отдельно (регистры в составе плана) или перепроводят документы после загрузки.При строго одностороннем обмене ответных квитанций не будет, и регистрацию удаляют сразу после формирования файла. Так проще, но потерянный файл тогда означает потерянные данные.
Таблицу регистрации изменений можно прочитать запросом. Номер сообщения NULL — изменение ещё не выгружалось.
// Серверный код: какая номенклатура ещё ждёт отправки в узел F01.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТаблицаИзменений.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура.Изменения КАК ТаблицаИзменений
|ГДЕ
| ТаблицаИзменений.Узел = &Узел
| И ТаблицаИзменений.НомерСообщения ЕСТЬ NULL";
Запрос.УстановитьПараметр("Узел", ПланыОбмена.ОбменСФилиалом.НайтиПоКоду("F01"));
НеОтправлено = Запрос.Выполнить().Выгрузить();
ОбменДанными.Отправитель объекты гоняются между базами по кругу.ПланыОбмена.ИзменениеЗарегистрировано() до записи.ПрочитатьXML падает с ошибкой преобразования данных XDTO. Для разных конфигураций нужны правила конвертации.НачатьЧтение сверяет номер сообщения с последним принятым и старое сообщение повторно не примет. Нужен свежий файл от отправителя.comcntr.dll нужной версии не зарегистрирована или не совпадает разрядность. Регистрируют её через regsvr32 от администратора.«Синхронизация данных» — название готового механизма БСП в типовых конфигурациях. Обмен данными шире: сюда входят РИБ, HTTP-интеграции и выгрузка в файлы.
Да, если обе программы типовые, без доработок и обновлены до совместимых релизов. Программист нужен при своих реквизитах и документах, массовых дублях или ошибках, которые не объясняет журнал.
Типовые правила обновляются вместе с релизом, но обе программы должны поддерживать общую версию формата — обновляйте их согласованно. Свои правила КД2 и доработки в расширениях после обновления проверяйте.
Одна конфигурация у всех и обновление из центра — РИБ. У филиала своя программа, например Розница в магазине и УТ в офисе, — типовая синхронизация или правила конвертации.
Если обмен нужен между доработанными базами, синхронизация теряет данные или плодит дубли, либо 1С надо связать с сайтом и маркетплейсами, быстрее отдать задачу программисту, который уже делал такие обмены. Опишите программы и данные на странице размещения задачи: оценка бесплатная, ответ в течение рабочего дня. Все направления — на странице услуг по доработке 1С.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.