gifts2017

Используем механизмы обмена данными БСП для произвольного обмена

Опубликовал Александр Полтава (Патриот) в раздел Обмен - Обмен с другими системами

Механизм БСП заточен на обмен XML по правилам обмена. Чтобы использовать его для любого другого обмена, коих в мире немало, требуются доработки. В статье описан вариант, как из положения выйти.

    Столкнулся давеча с проблемой: необходимо реализовать обмен данными через ftp. Причём хотелось использовать механизм БСП, чтобы не городить свои велосипеды. Казалось бы, для этого стоит только почитать документацию с ИТС, но не всё так просто. Механизм БСП заточен на обмен XML по правилам обмена. Чтобы использовать его для любого другого обмена, коих в мире не мало, требуются доработки. В статье описан вариант, как из положения выйти (так сказать, и рыбку съесть и косточкой не подавиться и формат обмена использовать произвольный и стандартным механизмом нагло воспользоваться).

    Ещё раз уточню. Здесь по сути нет инфы с ИТС, т.к. статья описывает использование механизмов БСП для произвольного обмена. Для обмена в формате XML по правилам обмена надо читать ИТС.

Какие возможности обмена БСП мы можем использовать:

Для начала стоит отметить, какие же такие типовые возможности я позарился использовать. Речь идёт о справочнике СценарииОбменовДанными.

Где можно прописать параметры обмена данными:

  • действие - выгрузка или загрузка
  • подключение - каталог или FTP или EMAIL или веб сервис или COM подключение (хранится это в РС "НастройкиТранспортаОбмена", значит нам не надо думать, где хранить эти данные)
  • расписание - расписание РЗ (значит не надо добавлять своё)

Вдобавок нам не надо создавать форму, на которой можно задавать все эти настройки и  имеются доп. возможности:

  • выполнить сценарий обмена прямо сейчас
  • Открыть журнал регистрации с отбором по событию обмена

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

Какие требуются доработки:

1. Добавить План обмена. Даже если он не нужен. Ибо без него ничего не взлетит. Это требование БСП. В модуль менеджера добавить следующий код, скопировав из типовых или взяв с ИТС. Естественно добавив только те виды транспорта, которые могут использоваться в вашем обмене. На всякий случай укажу, что вид "FILE" - это обмен через каталог.

Функция ИспользуемыеТранспортыСообщенийОбмена() Экспорт
	Результат = Новый Массив;
	Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.FILE);
	Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.FTP);
	Возврат Результат;      
КонецФункции  

2. Переопределить механизм обмена БСП. Для этого нам любезно предназначен специальный ОМ ОбменДаннымиПереопределяемый. В зависимости от задачи, нам нужна одна из двух (или сразу обе) процедур этого ОМ - ПриЗагрузкеДанных или ПриВыгрузкеДанных. Для нового обмена в означенные процедуры необходимо добавить следующий текст:

в ПриЗагрузкеДанных

Если ТипЗнч(Отправитель) = Тип("ПланОбменаСсылка._УТ_ДО_Пользователи") Тогда
	ПриЗагрузке(СтандартнаяОбработка, Отправитель, ИмяФайлаСообщения, ДанныеСообщения,
		КоличествоЭлементовВТранзакции, ИмяСобытияЖурналаРегистрации, КоличествоПолученныхОбъектов)
КонецЕсли;

в ПриВыгрузкеДанных

Если ТипЗнч(Получатель) = Тип("ПланОбменаСсылка._УТ_ДО_Пользователи") Тогда
	ПриВыгрузке(СтандартнаяОбработка, Получатель, ИмяФайлаСообщения, ДанныеСообщения,
		КоличествоЭлементовВТранзакции, ИмяСобытияЖурналаРегистрации, КоличествоОтправленныхОбъектов)
КонецЕсли;

Также в модуль добавляем блок методов УниверсальныйОбменДаннымиСПомощьюБСП

#Область УниверсальныйОбменДаннымиСПомощьюБСП

//Если обмен инициализирован справочником СценарииОбменовДанными
//
Процедура ПриВыгрузке(СтандартнаяОбработка, Получатель, ИмяФайлаСообщения, ДанныеСообщения,
		КоличествоЭлементовВТранзакции, ИмяСобытияЖурналаРегистрации, КоличествоОтправленныхОбъектов) Экспорт
	//КоличествоОтправленныхОбъектов - сюда можно присвоить количество выгруженного, которое потом запишется в ЖР
	//ИмяСобытияЖурналаРегистрации - его использует БСП при записи в ЖР,
	//нам надо делать также, чтобы удобно смотреть ЖР из сценария тестирования 
	
	//Планы обмена фиктивные, поэтому СтандартнаяОбработка не требуется
	СтандартнаяОбработка = Ложь;
	
	//Типовой механизм сам задаёт имя файла выгрузки и формат у него может быть только XML (так выглядит имя - Message_1_2.xml),
	//поэтому,если мы хотим это переопределить, надо получить настройки обмена (такие, как каталог обмена или ftp)
	НастройкиТранспорта = НастройкиТранспортаУзла(Получатель, Перечисления.ДействияПриОбмене.ВыгрузкаДанных);
	//в структуре НастройкиТранспорта лежат настройки из РС НастройкиТранспортаОбмена. Присутствуют не все поля РС, а только те,
	//которые соответствуют выбранному в сценарии обмена виду транспорта обмена (см. Перечисления.ДействияПриОбмене)
	
	//ТЕЛО ВЫГРУЗКИ
	//здесь мы знаем куда выгружать и описываем код выгрузки
	ОбщегоНазначения.МенеджерОбъектаПоСсылке(Получатель).ПриВыгрузке(НастройкиТранспорта, ИмяСобытияЖурналаРегистрации, КоличествоОтправленныхОбъектов);
	
	//эта строка выполняется в самом конце, если выгрузка прошла успешно
	СоздатьФайлВыгрузкиЗаглушкуДляОбменаНаБСП(ИмяФайлаСообщения);
КонецПроцедуры

//Если обмен инициализирован справочником СценарииОбменовДанными
//
Процедура ПриЗагрузке(СтандартнаяОбработка, Отправитель, ИмяФайлаСообщения, ДанныеСообщения,
		КоличествоЭлементовВТранзакции, ИмяСобытияЖурналаРегистрации, КоличествоПолученныхОбъектов) Экспорт
	СтандартнаяОбработка = Ложь;
	НастройкиТранспорта = НастройкиТранспортаУзла(Отправитель, Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
	
	//ТЕЛО ЗАГРУЗКИ
	//здесь мы знаем откуда загружать и описываем код загрузки
	ОбщегоНазначения.МенеджерОбъектаПоСсылке(Отправитель).ПриЗагрузке(НастройкиТранспорта, ИмяСобытияЖурналаРегистрации, КоличествоПолученныхОбъектов);
КонецПроцедуры

Процедура СоздатьФайлВыгрузкиЗаглушкуДляОбменаНаБСП(ИмяФайлаСообщения)
	//Чтобы типовой механизм понял, что выгрузка данных произошла,
	//надо заполнить типовой файл выгрузки содержимым.
	ЗаписьХМЛ = Новый ЗаписьXML;
	ЗаписьХМЛ.ОткрытьФайл(ИмяФайлаСообщения);
	ТекстЗаглушка = "Этот файл создаётся типовым механизмом обмена БСП. Его следует игнорировать. Можно удалять.";
	ЗаписьХМЛ.ЗаписатьНачалоЭлемента("Данные");
	ЗаписьХМЛ.ЗаписатьТекст(ТекстЗаглушка);
	ЗаписьХМЛ.ЗаписатьКонецЭлемента();
	ЗаписьХМЛ.Закрыть();
КонецПроцедуры

Функция НастройкиТранспортаУзла(Узел, ВыполняемоеДействие)
	//к сожалению, здесь мы не имеем ссылки на сценарий обмена, откуда он и был запущен,
	//а она нужна, чтобы определить ВидТранспортаОбмена, т.е. понять куда выгружать (в каталог, или ftp, или ещё куда)
	//есть несколько вариантов решить эту задачу и все "кривые":
	//
	//1. в модуле менеджера ПО, в функции ИспользуемыеТранспортыСообщенийОбмена() разрешить только один ВидТранспортаОбмена
	//2. сделать ВидТранспортаОбмена равным РегистрыСведений.НастройкиТранспортаОбмена.ВидТранспортаСообщенийОбменаПоУмолчанию(...),
	//но тогда настройка транспорта в сценарии обмена станет фиктивной, что приведёт к непониманию со стороны пользователей
	//(ВидТранспортаСообщенийОбменаПоУмолчанию задаётся в предприятии в настройках плана обмена)
	//3. Для СОВОКУПНОСТИ (УЗЕЛ нашего ПО + выполняемое действие (загрузка или выгрузка))
	//ограничить возможность использования сценариев для обмена одним сценарием.
	//Если их будет создано больше - отменять обмен. Если найден один - брать ВидТранспортаОбмена оттуда.
	//
	//Здесь реализован лучший, на мой взгляд, третий путь. Таким образом, мы получим одно ограничение:
	//чтобы выполнять несколько сценариев с данным обменом и выполняемым действием (загрузка или выгрузка),
	//нужно на каждый новый сценарий создавать копированием узел ПО (на всякий случай уточню: в режиме предприятия)
	//но для подавляющего большинства хватит и одного сценария (ведь возможность их множественности, это фича БСП).
	
	Запрос = Новый Запрос;
	Запрос.Текст =
	//поскольку помеченный на удаление сценарий всё равно можно выполнять, отбирать в запросе только непомеченные нельзя
	"ВЫБРАТЬ
	|	СценарииОбменовДаннымиНастройкиОбмена.ВидТранспортаОбмена
	|ИЗ
	|	Справочник.СценарииОбменовДанными.НастройкиОбмена КАК СценарииОбменовДаннымиНастройкиОбмена
	|ГДЕ
	|	СценарииОбменовДаннымиНастройкиОбмена.УзелИнформационнойБазы = &УзелИнформационнойБазы
	|	И СценарииОбменовДаннымиНастройкиОбмена.ВыполняемоеДействие = &ВыполняемоеДействие";
	Запрос.УстановитьПараметр("УзелИнформационнойБазы", Узел);
	Запрос.УстановитьПараметр("ВыполняемоеДействие", ВыполняемоеДействие);
	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.Количество() > 1 Тогда
		//Вызывающая процедура обработает исключение и запишет его в ЖР
		ВызватьИсключение "Для узлов данного плана обмена нельзя задавать больше чем по одному сценарию обмена!!!";
	ИначеЕсли Выборка.Количество() = 0 Тогда
		//вообще, здесь мы не можем оказаться, но на всякий случай
		ВызватьИсключение "Не найден сценарий обмена для данного узла обмена";
	КонецЕсли;
	Выборка.Следующий();
	НастройкиТранспорта = РегистрыСведений.НастройкиТранспортаОбмена.НастройкиТранспорта(Узел, Выборка.ВидТранспортаОбмена);
	
	Возврат НастройкиТранспорта;
КонецФункции

#КонецОбласти

Сами процедуры обмена данными находятся в модуле менеджера плана обмена. Таким образом, шаблон модуля менеджера ПО будет выглядеть так:

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

#Область ПрограммныйИнтерфейс

#Область ПроцедурыИФункцииБсп

// Возвращает массив используемых транспортов сообщений для этого плана обмена
//
// 1. Например, если план обмена поддерживает только два транспорта сообщений FILE и FTP,
// то тело функции следует определить следующим образом:
//
//	Результат = Новый Массив;
//	Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.FILE);
//	Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.FTP);
//	Возврат Результат;
//
// 2. Например, если план обмена поддерживает все транспорты сообщений, определенных в конфигурации,
// то тело функции следует определить следующим образом:
//
//	Возврат ОбменДаннымиСервер.ВсеТранспортыСообщенийОбменаКонфигурации();
//
// Возвращаемое значение:
//  Массив - массив содержит значения перечисления ВидыТранспортаСообщенийОбмена
//
Функция ИспользуемыеТранспортыСообщенийОбмена() Экспорт
	
	Результат = Новый Массив;
	Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.FILE);
	Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.FTP);
	Возврат Результат;
	
КонецФункции	

#КонецОбласти

#Область ВыгрузкаЗагрузкаЭкспортныеМетоды

//Вызывается из _омОбмен.ПриВыгрузке
//
Процедура ПриВыгрузке(НастройкиТранспорта, ИмяСобытияЖурналаРегистрации, КоличествоОтправленныхОбъектов) Экспорт
		
КонецПроцедуры

//Вызывается из _омОбмен.ПриВыгрузке
//
Процедура ПриЗагрузке(НастройкиТранспорта, ИмяСобытияЖурналаРегистрации, КоличествоПолученныхОбъектов) Экспорт
		
КонецПроцедуры

#КонецОбласти

#КонецОбласти


#Область Выгрузка

#КонецОбласти

#Область Загрузка

#КонецОбласти

#КонецЕсли

Ограничения, особенности использования нашего механизма:

  1. Для СОВОКУПНОСТИ (УЗЕЛ нашего ПО + выполняемое действие (загрузка или выгрузка)) можно задать только один сценарий. Если необходимо больше, то, на каждый новый сценарий надо создавать копированием узел ПО (на всякий случай уточню: в режиме предприятия), но для подавляющего большинства хватит и одного сценария (ведь возможность их множественности, это фича БСП).
  2. В папке обмена будет находиться один лишний файл или (в случае "2.в") придётся смириться с типовым именем файла. Но это тоже легко пережить =)
    1. а) Выгрузка. В папке выгрузки автоматом создаётся ненужный файл "Message_1_2.xml" с текстом "<Данные>Этот файл создаётся типовым механизмом обмена БСП. Его следует игнорировать. Можно удалять.</Данные>"
    2. б) Загрузка. В папку загрузки надо кинуть файл "Message_2_1.xml". Можно поместить в него следующий текст: "<Данные>ФАЙЛ НЕ УДАЛЯТЬ!! Без него него не будет работать механизм загрузки на БСП.</Данные>".
    3. в) Если выгрузка в ХМЛ, то можно обойтись без минусов 1 и 2, больше используя механизм БСП. Поскольку БСП как раз рассчитана именно на выгрузку в ХМЛ, то здесь лишних хлопот не требуется и мы можем прямо в ПриВыгрузкеДанных писать файл выгрузки (т.е. блок методов УниверсальныйОбменДаннымиСПомощьюБСП тут не нужен). Пример, как это сделать см в процедуре СоздатьФайлВыгрузкиЗаглушкуДляОбменаНаБСП. Но, у данного решения есть один недостаток: Имя файла генерирует БСП ("Message_1_2.xml", где "1" и "2" это коды узлов "откуда" и "куда" соответственно).

Особенности использования механизма БСП:

В предприятии надо создать два узла ПО, т.к. обмен с самим собой делать нельзя. Также обоим узлам надо задать Код, иначе обмен не взлетит. Данные проверки производятся в процедуре ОбменДаннымиСервер.ВыполнитьПроверкуСтруктурыОбменаНаВалидность.

Инструкция для пользователей:

В плане обмена создаём два узла. Узел Этой базы (у него на картинке зелёная точка справа внизу) и узел базы приёмника. Обязательно заполняем им код и наименование (для простоты можно назвать как на скрине «1» и «2»). Далее для обмена (выгрузки или загрузки) данными надо выбирать узел базы с которой идёт обмен, т.е. «2». Если выберем «1», то обмен проходить не будет а в ЖР появится запись «Нельзя организовать обмен данными с текущим узлом информационной базы. Обмен отменен.».

Спр. «Сценарии синхронизации данных».

Задаём имя сценария, добавляем строку настройки обмена в ТЧ.

Настраиваем параметры подключения.

После того, как всё настроено, можно настроить РЗ или выполнить обмен прямо сейчас.

После выполнения обмена, можно посмотреть его лог в ЖР.

ОпосляСкриптум:

Пришлось немного разобрать механизмы БСП, вследствие  чего родилась сия статья.  В сухом остатке мы имеем:

  • Чтобы использовать механизм обмена данными БСП для произвольного обмена, нужно просто скопировать описанные процедуры. Всё. Дальше можно заняться собственно самими процедурами обмена.
  • Также представлена инструкция для пользователей.

------------------------------------

ИНТЕРЕСНЫХ ВАМ ЗАДАЧ, ПЛОДОТВОРНОЙ РАБОТЫ И ОРИГИНАЛЬНЫХ/ОПТИМАЛЬНЫХ РЕШЕНИЙ!!

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Сергей Ожерельев (Поручик) 23.08.16 16:46
Полезная вещь.
Патриот; gortol; +2 Ответить 1
2. Александр Шипков (sansys) 24.08.16 05:40
Спасибо за статью, очень помогла.
3. Александр Полтава (Патриот) 24.08.16 09:33
(2) sansys, на здоровье, рад, что мой труд помог ещё кому-то.
(1) Поручик, ваш комментарий, похоже стал шикарнейшей рекламой для статьи =)
4. Роман С (Dach) 24.08.16 09:36
Статья гуд. Кстати, вопрос с ВидомТранспорта можно решить, добавив в план обмена соответствующий реквизит. И для каждого узла заполнить его нужным образом. В этот узел будет через файл выгружаться, а вот в этот - веб-сервисом. Ну а в целом мне очень нравится, когда для нестандартных решений используется стандартный механизм.
Патриот; +1 Ответить 1
5. Александр Полтава (Патриот) 24.08.16 09:52
(4) Dach, да, можно вид транспорта писать в реквизит плана обмена. Но у этого решения присутствует тот же минус, что и у одного из предложенных в статье. Цитирую: можно
//2. сделать ВидТранспортаОбмена равным РегистрыСведений.НастройкиТранспортаОбмена.ВидТранспортаСообщенийОбменаПоУмолчанию(...),
//но тогда настройка транспорта в сценарии обмена станет фиктивной, что приведёт к непониманию со стороны пользователей

Вот если к вашему предложению добавить ещё пару строк кода в форму механизма БСП (при заполненном реквизите у ПО, брать вид транспорта из него, не давая возможности выбора пользователю), то получится уже действительно красиво! Вот только многие ли решатся внести правку в типовой механизм? Спасибо за идею. Попозже добавлю сей вариант в статью.
6. Роман С (Dach) 24.08.16 11:36
(5) Патриот, я это и имел ввиду. Можно создавать несколько сценариев данных, имя сценария должно быть строго определено; при выборе реквизита "ВидТранспорта" в узле плана обмена находить нужный сценарий и менять настройку там. Тогда не придется код БСП править. Ну примерно так, навскидку. Единственное, не особо надежно - если имя сценария кто-то поменяет, но сомневаюсь что кто-то полезет так глубоко
7. Александр Полтава (Патриот) 24.08.16 12:51
(6) Dach, если сделать, как вы предлагаете
при выборе реквизита "ВидТранспорта" в узле плана обмена находить нужный сценарий и менять настройку там. Тогда не придется код БСП править.
то при создании нового сценария, придётся перевыбирать "ВидТранспорта" в узле плана обмена, чтобы он проставился в сценарии, что не очень хорошо.
8. Алексей (alest) 25.08.16 12:14
Поясните, пожалуйста, чем не угодил обмен по правилам. Какой "любой другой обмен" нельзя выполнить из модулей правил обмена?
9. Александр Полтава (Патриот) 25.08.16 12:45
(8) alest, вы прикалываетесь? Хотите сказать, что вам не известно, что кроме как в ХМЛ можно в любой другой формат выгружать (или из него загружать) данные? В зависимости от системы, с которой производится обмен и целей.
10. Роман Озеряный (rozer) 25.08.16 15:53
(9) Патриот, для этого 1с и придумала ED и КД3. Можно описать любую хмл-схему и xdto-пакет по ней или использовать стандартный от 1с...
11. Александр Полтава (Патриот) 25.08.16 16:09
(10) rozer, для чего для этого? Вам раз в день надо выгружать список сотрудников в CSV файл для пропускной системы. И кидать его на ФТП, откуда сторонняя система его заберёт и будет разрешать пропускать тех сотров, которые указаны в файле.
Опишите, будьте добры,
хмл-схему и xdto-пакет
для решения этой задачи
12. Роман Озеряный (rozer) 25.08.16 22:51
(11) Патриот, пожалуйста http://v8.1c.ru/edi/edi_stnd/enterprisedata/1.0/#00000000055, в КД3 создается ПКО и ПОД за 3мин. В КД2 правила регистрации для физлиц еще 2 мин. И через 5мин. - вуаля у вас готов xml-файлик на ФТП. Осталось еще желание изобретать "велик" ?
13. Александр Полтава (Патриот) 25.08.16 22:57
(12) rozer, какая из букв
CSV
вам не понятна в названии формата, требуемого сторонней системой, разработчиком которой вы не являетесь?
14. Елена Кушнир (kkkelena1963) 26.08.16 04:47
А мне статья очень понравилась! Спасибо большое.
15. Александр Полтава (Патриот) 26.08.16 08:11
(14) kkkelena1963, пожалуйста! А если вы ещё нажмёте на плюс статье, то это меня смотивирует написать ещё =)
16. Роман Озеряный (rozer) 26.08.16 08:52
(13) Патриот, все понял.Извиняюсь...
Патриот; +1 Ответить
17. Дмитрий Скляр (dvs69) 26.08.16 09:59
Спасибо за статью, доступно изложен материал, еще раз спасибо.
18. Максим Кузнецов (Makushimo) 30.08.16 09:42
А чем и с кем вы "нестандартно" обменивались в этой статье?
В чем нестандартность вашей ситуации?
19. Александр Полтава (Патриот) 30.08.16 09:51
(18) Makushimo, нестандартность, с точки зрения разработчиков БСП состоит в том, что я грузил данные не в ХМЛ, а в любой другой формат, в зависимости от требований со стороны того, кому я данные выгружаю. Например в эксель или текст.
20. Максим Кузнецов (Makushimo) 30.08.16 10:18
(19) Патриот
я понял.
в статье это осталось за кадром.
спасибо.
21. Kembrik (kembrik) 06.10.16 10:56
(15) Патриот,

Статья отличная, плюс поставил, пишите ещё! Воспользовался, чтобы убрать наконец "костыль" на обработках ожидания с выгрузкой в JSON

Вдруг будете раздумывать над темой новой статьи - очень интересен вариант с доработкой "старой" конфы на БСП (Например УТ 11.0.9.9) до "необходимого минимума", позволяющего использовать обмен данными на основе ED и КД3 (вон выше вам про него напомнили)
Патриот; +1 Ответить