Исходная задача
Возникла необходимость настроить обмен между базами 1С центрального компании и торговых филиалов. РИБ не подошел, из-за чувствительности к изменениям конфигурации, особенно к динамическим обновлениям. А также из-за того, что требуется обмен по определенным правилам: вся информация должна идти в одну сторону - из центра в филиал. Т.е. если кто-то изменит в базе филиала справочник номенклатуры случайно, это не должно попадать в центральную базу.
Из центральной базы в филиал выгружаются:
- каталог товаров,
- цены только по некоторым видам цен,
- заказы из интернет-магазина.
В центральной базе и в филиале торговля ведется от разных юр. лиц, управление филиалом осуществляется независимо.
Клиентская база в центре и в филиале ведется независимо, общими являются только те клиенты, которые прошли через интернет-магазин. Т.е. клиенты центральной базы не должны попадать в филиал, а также клиенты филиала не должны попадать в центральную базу. Но часть клиентов, проходящих через интернет-магазин, должна проходить через центральную базу. Проблема возникает, если клиент зарегистрировался в базе филиала, а затем решил что-то заказать через интернет-магазин. В этом случае при выгрузке из центра в филиал он не должен задублироваться, а должен подцепиться существующий клиент.
На основе этих требований было решено попробовать обмен через формат EnterpriseData.
Краткая справка по обмену в формате EnterpriseData
- Список объектов (справочники, документы и т.д.) к выгрузке ведется с помощью плана обмена. Создание плана обмена
- Автоматическая регистрация объектов в плане обмена отключается, регистрация производится в подписках на события записи в соответствии с логикой, заложенной программистом (следующий пункт). За эту функциональность отвечает модуль ОбменДаннымиСобытия.
- В план обмена добавляется макет в виде XML-файла с так называемыми правилами регистрации, которые определяют логику выгрузки и фильтрации объектов при выгрузке на узел. К сожалению, для всех узлов плана обмена используются одни и те же правила регистрации, даже их грузить из внешнего файла (такая возможность есть). Поэтому нельзя реализовать разную логику регистрации объектов для обмена с филиалом и Бухгалтерией, именно поэтому мы вынуждены создавать отдельный план обмена. Создание правил регистрации
- Выгрузка осуществляется типовым модулем ОбменДаннымиXDTOСервер, который формирует XML-файлик выгрузки. Для формирования файлика нужно иметь:
- Правила конвертации в виде программного модуля специальной структуры. Например, типовой модуль МенеджерОбменаЧерезУниверсальныйФормат (лучше туда не смотреть, там больше 50000 строк). Создание правил конвертации
- XTDO-пакет. Создание таких пакетов - это вообще что-то очень сложное, и нас сейчас не нужно, мы будем пользоваться типовым пакетом EnterpriseData_1_3_8
- Полученный XML-файлик превращается в данные в базе-приемнике с помощью этих же модулей.
- Настройки синхронизации хранятся в регистрах. Настройка синхронизации
Полный код описанных доработок можно скачать тут.
Модуль менеджера обмена - это модуль конфигурации 1С, который собственно реализует правила конвертации для обмена. Будет располагаться во внешней обработке, которую мы будем подключать к узлу плана обмена.
ПКС - правила конвертации свойств
Создание плана обмена
Для удобства создадим подсистему "ECom_ОбменСФилиалами". Все новые объекты будем добавлять в эту подсистему. Изменения в типовые модули будем выносить в расширение (при подключении расширения надо будет снять галочки "безопасный режим", т.к. будут затрагиваться серверные модули).
Копируем план обмена "СинхронизацияДанныхЧерезУниверсальныйФормат", называем новый план обмена "ECom_ОбменСФилиалами".
В настройках состава плана обмена делаем Действия - Выключить все, а потом добавляем справочники:
- ВидыЦен
- Номенклатура
и документы:
- ЗаказКлиента
- УстановкаЦенНоменклатуры
Авторегистрацию отключаем.
Заходим в модуль менеджера. В процедуре ДоступныеВерсииФорматаОбмена необходимо изменить название плана обмена в запросе.
Также удобно добавить возможность отладки модуля менеджера обмена (внешней обработки), как это сделать, описано тут:
https://forum.infostart.ru/forum15/topic165732/
Процедура ПриПолученииОписанияВариантаНастройки определяет, как наш план обмена обмена будет появляться в меню настройки синхронизации.
Процедура ПриПолученииОписанияВариантаНастройки(Настройки, ИдентификаторНастройки = "") Экспорт
Настройки.ПредупреждатьОНесоответствииВерсийПравилОбмена = Истина;
Настройки.ПутьКФайлуКомплектаПравилНаПользовательскомСайте = "https://users.v8.1c.ru/distribution/project/Trade110";
Настройки.ПутьКФайлуКомплектаПравилВКаталогеШаблонов = "\1c\trade";
Настройки.Вставить("ЗаголовокКомандыДляСозданияНовогоОбменаДанными", НСтр("ru = 'Обмен с филиалами'"));
Настройки.Вставить("ЗаголовокПомощникаСозданияОбмена", НСтр("ru = 'Обмен с филиалами'"));
Настройки.Вставить("ЗаголовокУзлаПланаОбмена", НСтр("ru = 'Обмен с филиалами'"));
Настройки.Вставить("ЭтоПланОбменаXDTO", Истина);
КонецПроцедуры
А также необходимо в общем модуле ОбменДаннымиУТУП в процедуре СписокПлановОбмена добавить наш план обмена
ПланыОбменаПодсистемы.Добавить(Метаданные.ПланыОбмена.ECom_ОбменСФилиалами);
Перед непосредственной настройкой обмена необходимо создать правила регистрации (см. далее), и загруизть их в макет "ПравилаРегистрации", иначе при создании узла УТ-шка будет ругаться на несоответствие имени плана обмена в правилах регистрации.
В результате появится возможность настраивать обмен по нашему плану обмена:
Чтобы запускать обмен типовыми средствами необходимо еще в общих командах
- НастройкиПодключения
- Синхронизировать
- СоставОтправляемыхДанных
В свойстве "Тип параметра" отметить наш план обмена
После создания настройки - до конца ее не всегда получается сделать. В регистре сведение "Общие настройки узлов информационных баз" указываем, что настройка была завершена.
Копируем типовые подписки на события:
- СинхронизацияДанныхЧерезУниверсальныйФорматРегистрация
- СинхронизацияДанныхЧерезУниверсальныйФорматРегистрацияДокумента
Указываем наши объекты, входящие в состав нашего плана обмена.
Копируем типовой модуль ОбменДаннымиСобытияУТ, в полученном модуле в процедурах меняем имя плана обмена с СинхронизацияДанныхЧерезУниверсальныйФормат на наш ECom_ОбменСФилиалами.
В созданных подписках указываем обработчики - процедуры из нашего нового модуля.
Также добавим в этот модуль функцию ЭтоЦентральнаяБаза(), которая нам потребуется в дальнейшем. Признаком центральной базы будем считать код узла, соответствующего текущей базе ("этот узел"), равным "ЦБ".
Т.к. эта функция будет вызываться постоянно, необходимо ее закэшировать с помощью модуля повторного использования.
Создание правил регистрации
Для создания правил регистрации нам потребуется конфигурация Конвертация Данных v2.
Я для изучения вопроса использовал вот эту статью:
http://helpme1c.ru/uchebnik-po-1s-konvertacii-dannyx-redakciya-2-pravila-registracii-obektov
С помощью обработки MD83Exp.epf, входящей в состав поставки Конвертации 2, необходимо выгрузить структуру нашей конфигурации в файл.
Затем необходимо загрузить полученную структуру конфигурации в Конвертацию 2.
Создаем правила регистрации.
Выбираем нашу конфигурацию и наш план обмена.
И заходим в настройку правил регистрации.
Создаем правила регистрации для наших объектов:
Т.к. мы хотим, чтобы у нас был односторонний обмен (только из центра в филил), в настройку правил по каждому объекту надо добавить в обработчик "Перед обработкой" наш фильтр:
Отказ = Не ECom_ОбменДаннымиПовтИсп.ЭтоЦентральнаяБаза();
На "Заказ клиента" накладываем дополнительный фильтр по организации и по дате начала выгрузки:
Для документа "Установка цен номенклатуры" так же добавляем отбор по дате. Плюс к этому в обработчик "При обработке" добавляем фильтр по виду цен.
ИспользоватьКэш = Ложь;
ВидыЦен = Объект.ВидыЦен.ВыгрузитьКолонку("ВидЦены");
ПараметрыЗапроса.Вставить("ВидыЦен", ВидыЦен);
ТекстЗапроса =
"ВЫБРАТЬ
| ECom_ОбменСФилиалами.Ссылка КАК Ссылка
|ИЗ
| ПланОбмена.ECom_ОбменСФилиалами.ВидыЦенНоменклатуры КАК ECom_ОбменСФилиаламиВидыЦенНоменклатуры
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПланОбмена.ECom_ОбменСФилиалами КАК ECom_ОбменСФилиалами
| ПО ECom_ОбменСФилиаламиВидыЦенНоменклатуры.Ссылка = ECom_ОбменСФилиалами.Ссылка
| И (ECom_ОбменСФилиаламиВидыЦенНоменклатуры.ВидЦенНоменклатуры В (&СвойствоОбъекта_ВидыЦен))
| И (ECom_ОбменСФилиалами.ЭтотУзел = ЛОЖЬ)"
;
Этот обработчик с помощью запроса позволяет определить список узлов, в которых будет произведена регистрация объекта. Почему-то хотя наш параметр запроса называется "ВидыЦен", в запросе мы должны писать "СвойствоОбъекта_ВидыЦен".
На справочник "Виды цен" также накладываем фильтр:
Сохраняем правила регистрации во внешний файл:
Полученный XML-файл необходимо загрузить в макет "Правила регистрации" нашего плана обмена:
Отметим, что при работе конфигурации правила регистрации берутся вовсе не из этого макета, а из правил, хранящихся в регистре сведений "ПравилаДляОбменаДанными". А в этот регистр правила загружаются как раз из макета, зашитого в конфигурацию - при создании настройки синхронизации. Это приводит к тому, если у нас уже создана настройка синхронизации, а нам по каким-то причинам потребовалось поменять правила регистрации - после изменения правил в макете конфигурации нужно обновить их также в этом регистре:
Правила конвертации
Для создания правил конвертации нам потребуется конфигурация Конвертация Данных v3. Лучше пользоваться чистой базой. Например, разрабатывая конвертацию для формата данных EnterpriseData 1.3, для некоторых объектов почему-то требовалось задавать реквизиты (ПКС), не являющиеся казалось бы обязательными. Оказалось, что они обязательны в версии 1.2, и простое наличие в базе Конвертации загруженного описания этого формата уже сбивало логику работы программы. Поэтому берем чистую базу, и грузим в нее все "с нуля".
Очень здорово работа с конвертацией 3.0 описана тут:
Загружаем структуру конфигурации из файла, выгруженного ранее (в Конвертации 2).
Выгружаем из УТ 11 XDTO-пакет EnterpriseData_1_3_8 в файл
Загружаем полученный файл в Конвертацию 3
Создаем конвертацию
Версия формата менеджера обмена указывается в зависимости от конфигурации. Например для УТ 11.3 это "1", для УТ 11.4 - "2".
Что такое конвертация? Для выгрузки и загрузки объекта нам нужно:
- Правило отправки данных - тут мы можем накладывать фильтр на объекты и применять разные правила конвертации (например, для папок номенклатуры и элементов указываются разные правила конвертации из-за разного набора реквизитов)
- Правило конвертации "из 1С в XML" - тут данные 1С преобразуются в данные формата EnterpriseData (например, можно документ "Реализация" сконвертировать в документ "Поступление")
- Правило конвертации "из XML в 1С"
- Правило получения данных
Если объект участвует в плане обмена - для него обязательно необходимо создать правило отправки данных. В нашем случае это:
- Виды цен
- Номенклатура
- Заказ клиента
- Установка цен номенклатуры
Как себя будут вести реквизиты этих объектов ссылочного типа? Например, реквизит "Организация". У каждого "объектных" типов в формате EnterpriseData (например, Справочник.Контрагенты) есть так называемые ключевые свойства. Так вот, когда мы выгружаем заказ, в правилах конвертации мы указываем реквизит "Организация". При выгрузке этого реквизита выгружаются и его ключевые свойства. Мы не будем создаваться создавать правила отправки для справочника "Организации", потому что эти данные в работающей системе меняются крайне редко, мы просто пропишем алгоритм, который при получении заказа правильно подставит уже существующую в базе филиала организацию.
Итак, правила отправки мы пишем для часто меняющихся объектов, "статичные" же объекты мы лучше однократно (и повторно при необходимости) выгрузим через универсальную выгрузку-загрузку.
Создаем правило конвертации для отправки номенклатуры.
Настраиваем "правила конвертации свойств". Суть в чем. EnterpriseData - это структура данных, по сути та же конфигурация 1С. Только скажем так чуть более упрощенная и универсальная. Она должна подходить для разных конфигураций 1С, поэтому состав и название объектов отличается от УТ 11. Поэтому нам нужно прописать соответствие - как реквизиты называются в УТ11, и как в EnterpriseData. Есть так называемые "ключевые свойства" - это обязательные реквизиты для данной версии формата. Их можно посмотреть в "Дереве объектов формата":
Итак, указываем правила конвертации свойство для номенклатуры:
Как видим, у нас появилось несколько реквизитов "сложного" типа, для них также необходимо создать "Правила конвертации объектов", иначе в при выгрузке будет выходить такое сообщение в ошибках: "Структура объекта '/ЕдиницаИзмерения' не соответствует типу".
Правила конвертации для перечислений, и прочих предопределенных (в конфигураторе) данных создаются на вкладке:
Для этих (и некоторых других) данных удобно, чтобы правило работало сразу и отправку, и на получение.
Указываем созданные правила в ПКС для номенклатуры:
Теперь создадим правило конвертации для "Заказа клиента".
Добавим правила конвертации для табличной части "Товары". Для начала укажем соответствие реквизитов в ПКС. Необходимо проставить галочку "Используется алгоритм", т.к. значения табличной части будут формироваться не "сами", нужно еще написать небольшой алгоритм. При использовании алгоритма нам не обязательно указывать реквизиты объекта из 1С, т.к. значения для выгрузки в файл XML все равно будут формироваться алгоритмом. Необходимо также указывать правило конвертации свойства для "сложных" типов.
Теперь нужно добавить алгоритм заполнения табличной части в обработчик "При отправке".
В правилах конвертации при получении заказа нужно прописать алгоритм, который выполняет обратную операцию
Алгоритм заполняет ПолученныеДанные.ДополнительныеСвойства.Товары, которые потом автоматически записываются в табличную часть "Товары" загружаемого объекта.
Теперь реализуем такой механизм обмена контрагентами (покупателями): при загрузке заказа в базу филиала ищем существующего клиента по телефону (например, клиент что-то купил в филиале, зарегистрировался, а потом решил приобрести что-то в интернет-магазине, и заказ попал в центральную базу). Если клиент по телефону найден, то подставляем в заказ его, если же нет - создаем нового. Для этого нам необходимо будет вмести с заказом передавать номер телефона клиента. В типовые поля заказа в формате EnterpriseData телефон не входит, чтобы его передать, можно воспользоваться полем AdditionalInfo, куда можно записывать дополнительную информацию. Мы будем передавать дополнительную информацию в виде структуры с необходимыми полями. Через AdditionalInfo можно передавать и структуры, и таблицы значений. В обработчик "При отправке" в правила конвертации заказа при отправке
добавляем код:
Соответственно, в обработчик "При конвертации данных XDTO" в найстройку конвертации при получении
Добавляем код:
В выгрузке цен номенклатуры есть несколько интересных моментов:
- документ установки цен может содержать несколько видов цен, а нам нужно выгружать только те, которые подпадают под фильтр.
- В формате EnterpriseData документ "Установка цен номенклатуры" имеет только один тип цен. Т.е. один документ в 1С должен выгружаться как несколько объектов EnterpriseData.
Для реализации фильтра нам потребуется где-то хранить выгружаемые виды цен, установленные в настройках узла обмена. Для этого нам потребуются "Параметры конвертации":
А также обработка события "Перед конвертацией":
В правилах обработки данных для документа "Установка цен номенклатуры" нам необходимо отключить использование конвертации "в типовом" варианте, а вместо этого генерировать объект XDTO "на ходу":
Для этого мы обратимся напрямую к методу ОбменДаннымиXDTOСервер.ВыгрузкаОбъектаВыборки. Преобразуем документ в массив необходимых нам структур с одним типом цен, и уже каждую эту структуру отдельно выгрузим через правила конвертации. Выглядит, конечно, запутанно.
В правило конвертации в ПКС необходимо добавить свойство "ТипЦен". При этом надо выбирать способ выбора свойств "Вручную".
Настройка синхронизации
Необходимо задать значение константы "Префикс информационной базы" - "ЦБ":
Создаем новую настройку синхронизации
Зададим в настройках фильтр по дате документов, организации, виду цен:
Чтобы подключить нашу внешнюю обработку, содержащую модуль менеджера обмена, необходимо в настройках формы указать отображение вкладки "служебная информация":
Создадим вторую чистую базу (для филиала) из cf-ника центральной базы. Также не забываем подключить наше расширение. При создании базы автоматически создаются справочники "Валюта" и "Единицы измерения". Чтобы при загрузке данных из центральной базы не произошло задвоение этих данных, необходимо в конвертации по этим справочникам идентификацию сделать не по UID, а по коду.
Префикс информационной базы задаем "ФЛ" и настраиваем синхронизацию, аналогично центральной базе.
Дополнительные файлы со сквозным примером.
Состав файлов, приложенных к данной статье:
- cf-файл "Доп. объекты конфигурации.cf" для объединения с основной конфигурацией УТ 11, содержащий разработанный план обмена
- cfe-файл с расширением конфигурации, для корректировки модулей конфигурации
- xml-файл "Правила регистрации.xml"
- epf-файл "МенеджерДемо.epf"
Порядок установки плана обмена. В конфигураторе запускаем операцию сравнения и объединения с "Доп. объекты конфигурации.cf". Снимаем галочки со всех объектов:
Выбираем "Действия - отметить по подсистемам файла", отмечаем только "ECom_ОбменСФилиалами"
На предупреждение про неразрешимые ссылки отвечаем "Продолжить".
Добавляем расширение из файла "ECom_ОбменДаннымиСФилиалами.cfe", снимаем галочки про безопасность:
Для корректировки правил регистрации вложенный файл "Правила регистрации.xml" можно загрузить в Конвертацию 2. Предварительно необходимо загрузить структуру конфигурации, как описано выше.
Для корректировки правил конвертации вложенный файл "МенеджерДемо.epf" можно загрузить в Конвертацию 3. Предварительно необходимо создать описание конвертации, как описано тут.
Дополнение 25.06.2020.
В версии УТ 11.4.11 необходимо добавить запись в регистр сведений "Общие настройки узлов информационных баз".