Данная статья является продолжением статьи «Универсальный способ конвертации данных с использованием таблицы значений».(Статью можно прочитать здесь) В упомянутой статье предложен способ передачи таблицы значений из конфигурации-источника (Источник) в конфигурацию-приемник (Приемник). Отметим один существенный момент в предложенном способе: в Приемнике не требуется наличие табличной части для установки соответствия между таблицей значений, сформированной в Источнике. Поэтому все правила обмена сводятся к одному стандартному правилу выгрузки данных и одному правилу конвертации справочника КД, содержащего в реквизите ТЗ передаваемую таблицу значений. Поиск следует производить по наименованию (или по коду). Справочник КД должен быть одинаковым в обеих конфигурациях. В плане обмена нужно включить в состав данный справочник и установить авторегистрацию «Запретить». | ||
Предположим, что ТЗ формируется на основе некоторого документа НашДокумент. Но сам документ передавать в приемник не требуется, так как в приемнике для него нет соответствующего объекта. В этом случае нецелесообразно включать данный документ в состав плана обмена. Однако нужно каким-то образом регистрировать изменения этого документа для того, чтобы формировать ТЗ только по измененным документам. Для этих целей можно создать свой регистр сведений, назовем его «РегистрацияИзменений». Определим для регистра два измерения: Объект (ДокументСсылка.НашДокумент) и НомерСообщения для привязки изменений к номеру принятого сообщения (НомерПринятого). Очистку регистра можно производить в правилах обмена в событии «После выгрузки файла». При этом очищать можно все записи с номером сообщения, равным или меньше значения НомерПринятого. | ||
Для регистрации изменений можно воспользоваться подпиской на события для нашего документа. В качестве номера сообщения нужно брать номер принятого + 1. Если в регистре отсутствует документ с указанным номером, то он добавляется. Одновременно в данной процедуре нужно зарегистрировать изменение нашего справочника КД по соответствующему узлу. | ||
Осталось только получить подтверждение о получении сообщения в Приемнике после удачной загрузки. Поскольку задача состоит лишь в возврате в Приемник номера принятого сообщения, то можно это сделать из правила обмена (загрузки) без использования и настройки типового обмена Источник-Приемник. Просто сформируем файл (в формате txt, xml) и поместим его в каталог, заданный в настройках обмена. Номер принятого сообщения можно взять из плана обмена Узел.НомерПринятого + 1. Соответственно, в Источнике будем брать НомерПринятого из данного файла (путь к которому также находится в настройках обмена, только уже в Источнике). | ||
Фактически мы реализовали односторонний обмен, но при этом смогли получить подтверждение о приеме сообщения в Приемнике. | ||
Предложенный механизм обмена отличается от стандартного использования планов обмена. Но, как указывалось вначале, рассматриваемая конвертация данных представляет сложное преобразование одних объектов Источника в другие объекты Приемника. Собственно, использование справочника КД с реквизитом ТЗ не противоречит правилам конвертации, а, наоборот, четко вписывается в эти правила. Регистрация изменений документов может быть выполнена и стандартным путем через план обмена, но в этом случае будут возникать события конвертации документов, а нам нужно передать в Приемник только справочник, поэтому отказ от регистрации документов с помощью плана обмена вполне обоснован. Получение подтверждения о получении сообщения также может быть выполнено с использованием стандартных механизмов с помощью плана обмена. Однако проще (и надежнее) выполнять обмен только в одну сторону, а передачу подтверждения выполнить своими средствами, включив их в событие загрузки данных в Приемнике. | ||
Приведем тексты программ. | ||
Подписка на событие для документа НашДокумент |
Процедура ЗарегистрироватьИзменениеНашДокумент(Источник, Отказ) Экспорт
УстановитьПривилегированныйРежим(Истина);
Узел = ПланыОбмена.НашПлан.НайтиПоНаименованию("НАШ");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НастройкиТранспортаОбмена.FILEКаталогОбменаИнформацией
|ИЗ
| РегистрСведений.НастройкиТранспортаОбмена КАК НастройкиТранспортаОбмена
|ГДЕ
| НастройкиТранспортаОбмена.Узел = &Узел";
Запрос.УстановитьПараметр("Узел", Узел);
Выборка = Запрос.Выполнить().Выбрать();
НомерПринятого = 0;
Если Выборка.Количество() > 0 Тогда
Выборка.Следующий();
КаталогОбмена = Выборка.FILEКаталогОбменаИнформацией;
ИмяФайла = "Message_НАШ_ERP.txt";
ПолноеИмяФайла = КаталогОбмена + "\" + ИмяФайла;
ФайлСообщенияДляERP = Новый ЧтениеТекста(ПолноеИмяФайла);
НомерПринятого = ФайлСообщенияДляERP.Прочитать();
НомерПринятого = Число(НомерПринятого);
ФайлСообщенияДляERP.Закрыть();
КонецЕсли;
НаборЗаписей = РегистрыСведений.клРегистрацияИзменений.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Объект.Установить(Источник.Ссылка);
НаборЗаписей.Отбор.НомерСообщения.Установить(НомерПринятого + 1);
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() = 0 Тогда
НоваяЗапись = РегистрыСведений.клРегистрацияИзменений.СоздатьМенеджерЗаписи();
НоваяЗапись.Объект = Источник.Ссылка;
НоваяЗапись.НомерСообщения = НомерПринятого + 1;
НоваяЗапись.Записать();
КонецЕсли;
Спр = Справочники.КД.ОбменДанными.ПолучитьОбъект();
Спр.ТЗ = Неопределено;
Спр.Записать();
ПланыОбмена.ЗарегистрироватьИзменения(Узел, Спр);
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
УстановитьПривилегированныйРежим(Истина);
Узел = ПланыОбмена.НашПлан.НайтиПоНаименованию("НАШ");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НастройкиТранспортаОбмена.FILEКаталогОбменаИнформацией
|ИЗ
| РегистрСведений.НастройкиТранспортаОбмена КАК НастройкиТранспортаОбмена
|ГДЕ
| НастройкиТранспортаОбмена.Узел = &Узел";
Запрос.УстановитьПараметр("Узел", Узел);
Выборка = Запрос.Выполнить().Выбрать();
НомерПринятого = 0;
Если Выборка.Количество() > 0 Тогда
Выборка.Следующий();
КаталогОбмена = Выборка.FILEКаталогОбменаИнформацией;
ИмяФайла = "Message_НАШ_ERP.txt";
ПолноеИмяФайла = КаталогОбмена + "\" + ИмяФайла;
ФайлСообщенияДляERP = Новый ЧтениеТекста(ПолноеИмяФайла);
НомерПринятого = ФайлСообщенияДляERP.Прочитать();
НомерПринятого = Число(НомерПринятого);
ФайлСообщенияДляERP.Закрыть();
КонецЕсли;
НаборЗаписей = РегистрыСведений.клРегистрацияИзменений.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Объект.Установить(Источник.Ссылка);
НаборЗаписей.Отбор.НомерСообщения.Установить(НомерПринятого + 1);
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() = 0 Тогда
НоваяЗапись = РегистрыСведений.клРегистрацияИзменений.СоздатьМенеджерЗаписи();
НоваяЗапись.Объект = Источник.Ссылка;
НоваяЗапись.НомерСообщения = НомерПринятого + 1;
НоваяЗапись.Записать();
КонецЕсли;
Спр = Справочники.КД.ОбменДанными.ПолучитьОбъект();
Спр.ТЗ = Неопределено;
Спр.Записать();
ПланыОбмена.ЗарегистрироватьИзменения(Узел, Спр);
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
Определение состава измененных документов в событии ПередВыгрузкой ПКО. |
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НастройкиТранспортаОбмена.FILEКаталогОбменаИнформацией
|ИЗ
| РегистрСведений.НастройкиТранспортаОбмена КАК НастройкиТранспортаОбмена
|ГДЕ
| НастройкиТранспортаОбмена.Узел = &Узел";
Узел = ПланыОбмена.клERP_УСО.НайтиПоНаименованию("НАШ");
Запрос.УстановитьПараметр("Узел", Узел);
Выборка = Запрос.Выполнить().Выбрать();
НомерПринятого = 0;
Если Выборка.Количество() > 0 Тогда
Выборка.Следующий();
КаталогОбмена = Выборка.FILEКаталогОбменаИнформацией;
ИмяФайла = "Message_НАШ_ERP.txt";
ПолноеИмяФайла = КаталогОбмена + "\" + ИмяФайла;
ФайлСообщенияДляERP = Новый ЧтениеТекста(ПолноеИмяФайла);
НомерПринятого = ФайлСообщенияДляERP.Прочитать();
НомерПринятого = Число(НомерПринятого);
ФайлСообщенияДляERP.Закрыть();
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| клРегистрацияИзменений.Объект КАК Ссылка
|ИЗ
| РегистрСведений.клРегистрацияИзменений КАК клРегистрацияИзменений
|ГДЕ
| клРегистрацияИзменений.НомерСообщения > &НомерСообщения";
Запрос.УстановитьПараметр("НомерСообщения", НомерПринятого);
тзИзмененныеОбъекты = Запрос.Выполнить().Выгрузить();
ИзмененныеОбъекты = тзИзмененныеОбъекты.ВыгрузитьКолонку("Ссылка");
Запрос.Текст =
"ВЫБРАТЬ
| НастройкиТранспортаОбмена.FILEКаталогОбменаИнформацией
|ИЗ
| РегистрСведений.НастройкиТранспортаОбмена КАК НастройкиТранспортаОбмена
|ГДЕ
| НастройкиТранспортаОбмена.Узел = &Узел";
Узел = ПланыОбмена.клERP_УСО.НайтиПоНаименованию("НАШ");
Запрос.УстановитьПараметр("Узел", Узел);
Выборка = Запрос.Выполнить().Выбрать();
НомерПринятого = 0;
Если Выборка.Количество() > 0 Тогда
Выборка.Следующий();
КаталогОбмена = Выборка.FILEКаталогОбменаИнформацией;
ИмяФайла = "Message_НАШ_ERP.txt";
ПолноеИмяФайла = КаталогОбмена + "\" + ИмяФайла;
ФайлСообщенияДляERP = Новый ЧтениеТекста(ПолноеИмяФайла);
НомерПринятого = ФайлСообщенияДляERP.Прочитать();
НомерПринятого = Число(НомерПринятого);
ФайлСообщенияДляERP.Закрыть();
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| клРегистрацияИзменений.Объект КАК Ссылка
|ИЗ
| РегистрСведений.клРегистрацияИзменений КАК клРегистрацияИзменений
|ГДЕ
| клРегистрацияИзменений.НомерСообщения > &НомерСообщения";
Запрос.УстановитьПараметр("НомерСообщения", НомерПринятого);
тзИзмененныеОбъекты = Запрос.Выполнить().Выгрузить();
ИзмененныеОбъекты = тзИзмененныеОбъекты.ВыгрузитьКолонку("Ссылка");
Событие «После выгрузки в файл» ПКО |
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НастройкиТранспортаОбмена.FILEКаталогОбменаИнформацией
|ИЗ
| РегистрСведений.НастройкиТранспортаОбмена КАК НастройкиТранспортаОбмена
|ГДЕ
| НастройкиТранспортаОбмена.Узел = &Узел";
Узел = ПланыОбмена.клERP_УСО.НайтиПоНаименованию("НАШ");
Запрос.УстановитьПараметр("Узел", Узел);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Количество() > 0 Тогда
Выборка.Следующий();
КаталогОбмена = Выборка.FILEКаталогОбменаИнформацией;
ИмяФайла = "Message_НАШ_ERP.txt";
ПолноеИмяФайла = КаталогОбмена + "\" + ИмяФайла;
ФайлСообщенияДляERP = Новый ЧтениеТекста(ПолноеИмяФайла);
НомерПринятого = ФайлСообщенияДляERP.Прочитать();
НомерПринятого = Число(НомерПринятого);
ФайлСообщенияДляERP.Закрыть();
Запрос1 = Новый Запрос;
Запрос1.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| клРегистрацияИзменений.НомерСообщения
|ИЗ
| РегистрСведений.клРегистрацияИзменений КАК клРегистрацияИзменений
|ГДЕ
| клРегистрацияИзменений.НомерСообщения <= &НомерСообщения";
Запрос1.УстановитьПараметр("НомерСообщения", НомерПринятого);
Выборка1 = Запрос1.Выполнить().Выбрать();
Пока Выборка1.Следующий() Цикл
НомерПринятого = Выборка1.НомерСообщения;
НаборЗаписей = РегистрыСведений.клРегистрацияИзменений.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.НомерСообщения.Установить(НомерПринятого);
НаборЗаписей.Записать();
КонецЦикла;
КонецЕсли;
Запрос.Текст =
"ВЫБРАТЬ
| НастройкиТранспортаОбмена.FILEКаталогОбменаИнформацией
|ИЗ
| РегистрСведений.НастройкиТранспортаОбмена КАК НастройкиТранспортаОбмена
|ГДЕ
| НастройкиТранспортаОбмена.Узел = &Узел";
Узел = ПланыОбмена.клERP_УСО.НайтиПоНаименованию("НАШ");
Запрос.УстановитьПараметр("Узел", Узел);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Количество() > 0 Тогда
Выборка.Следующий();
КаталогОбмена = Выборка.FILEКаталогОбменаИнформацией;
ИмяФайла = "Message_НАШ_ERP.txt";
ПолноеИмяФайла = КаталогОбмена + "\" + ИмяФайла;
ФайлСообщенияДляERP = Новый ЧтениеТекста(ПолноеИмяФайла);
НомерПринятого = ФайлСообщенияДляERP.Прочитать();
НомерПринятого = Число(НомерПринятого);
ФайлСообщенияДляERP.Закрыть();
Запрос1 = Новый Запрос;
Запрос1.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| клРегистрацияИзменений.НомерСообщения
|ИЗ
| РегистрСведений.клРегистрацияИзменений КАК клРегистрацияИзменений
|ГДЕ
| клРегистрацияИзменений.НомерСообщения <= &НомерСообщения";
Запрос1.УстановитьПараметр("НомерСообщения", НомерПринятого);
Выборка1 = Запрос1.Выполнить().Выбрать();
Пока Выборка1.Следующий() Цикл
НомерПринятого = Выборка1.НомерСообщения;
НаборЗаписей = РегистрыСведений.клРегистрацияИзменений.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.НомерСообщения.Установить(НомерПринятого);
НаборЗаписей.Записать();
КонецЦикла;
КонецЕсли;
Событие «После загрузки» ПКО |
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НастройкиТранспортаОбмена.FILEКаталогОбменаИнформацией
|ИЗ
| РегистрСведений.НастройкиТранспортаОбмена КАК НастройкиТранспортаОбмена
|ГДЕ
| НастройкиТранспортаОбмена.Узел = &Узел";
Узел = ПланыОбмена.клERP_УСО.НайтиПоНаименованию("ERP");
Запрос.УстановитьПараметр("Узел", Узел);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Количество() > 0 Тогда
Выборка.Следующий();
КаталогОбмена = Выборка.FILEКаталогОбменаИнформацией;
ИмяФайла = "Message_НАШ_ERP.txt";
ПолноеИмяФайла = КаталогОбмена + "\" + ИмяФайла;
ФайлСообщенияДляERP = Новый ЗаписьТекста(ПолноеИмяФайла);
НомерПринятого = Формат(Узел.НомерПринятого + 1);
НомерПринятого = СтрЗаменить(НомерПринятого, Символы.НПП, " ");
ФайлСообщенияДляERP.Записать(НомерПринятого);
ФайлСообщенияДляERP.Закрыть();
КонецЕсли;
Запрос.Текст =
"ВЫБРАТЬ
| НастройкиТранспортаОбмена.FILEКаталогОбменаИнформацией
|ИЗ
| РегистрСведений.НастройкиТранспортаОбмена КАК НастройкиТранспортаОбмена
|ГДЕ
| НастройкиТранспортаОбмена.Узел = &Узел";
Узел = ПланыОбмена.клERP_УСО.НайтиПоНаименованию("ERP");
Запрос.УстановитьПараметр("Узел", Узел);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Количество() > 0 Тогда
Выборка.Следующий();
КаталогОбмена = Выборка.FILEКаталогОбменаИнформацией;
ИмяФайла = "Message_НАШ_ERP.txt";
ПолноеИмяФайла = КаталогОбмена + "\" + ИмяФайла;
ФайлСообщенияДляERP = Новый ЗаписьТекста(ПолноеИмяФайла);
НомерПринятого = Формат(Узел.НомерПринятого + 1);
НомерПринятого = СтрЗаменить(НомерПринятого, Символы.НПП, " ");
ФайлСообщенияДляERP.Записать(НомерПринятого);
ФайлСообщенияДляERP.Закрыть();
КонецЕсли;
Если есть вопросы по одностороннему обмену данными с использованием планов обмена - обращайтесь! | ||
Семенов Сергей |