new
This commit is contained in:
parent
428e09a8e2
commit
6b5b4af34e
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: Код текущего узла обмена
|
||||
slug: общие-обмен-данными-планы-обмена/код-текущего-узла-обмена
|
||||
---
|
||||
|
||||
```bsl
|
||||
КодТекущегоУзла = ПланыОбмена.<ИмяПланаОбмена>.ЭтотУзел().Код;
|
||||
```
|
@ -0,0 +1,319 @@
|
||||
---
|
||||
title: Пример простого обмена двух баз через файл с квитированием
|
||||
slug: общие-обмен-данными-планы-обмена/пример-простого-обмена-двух-баз-через-файл-с-квитированием
|
||||
---
|
||||
|
||||
В общем виде обмен с квитированием осущетвляется в несколько шагов:
|
||||
1. Создание сообщения обмена в источнике
|
||||
2. Чтение и обработка сообщения обмена в приемнике
|
||||
3. Создание подтверждающего сообщения в приемнике (квитирование)
|
||||
4. Чтение и удаление успешно переданного из плана обмена в источнике
|
||||
|
||||
|
||||
## Сообщение обмена Источник-Приемник
|
||||
|
||||
### Создание сообщения
|
||||
|
||||
Создаем план обмена, реализуем выгрузку. В примере в плане обмена источника зарегистрирован один справочник "Номенклатура"
|
||||
|
||||
```bsl
|
||||
// Узел обмена - целевой узел обмена базы приемника в плане обмена
|
||||
Процедура ВыгрузитьНоменклатуруВФайл(УзелОбмена) Экспорт
|
||||
|
||||
Если Не ЗначениеЗаполнено(УзелОбмена) Тогда
|
||||
ВызватьИсключение "Не установлен узел обмена";
|
||||
КонецЕсли;
|
||||
|
||||
// полное имя файла, куда будет записываться выгрузка
|
||||
ИмяСообщения = "C:\путь-до-папки-обмена\Выгрузка_Источник_Приемник.xml";
|
||||
|
||||
ЗаписьXML = Новый ЗаписьXML;
|
||||
ЗаписьXML.ОткрытьФайл(ИмяСообщения, "UTF-8");
|
||||
|
||||
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
|
||||
|
||||
// тут записываются служебные заголовки сообщения - узел, номер сообщения и пр.
|
||||
ЗаписьСообщения.НачатьЗапись(ЗаписьXML, УзелОбмена);
|
||||
|
||||
// выгружаем все изменения, дополнительно устанавливаем номер сообщения из ЗаписьСообщения,
|
||||
// т.к. до выгрузки изменений номер сообщения в таблице изменений = NULL
|
||||
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(УзелОбмена, ЗаписьСообщения.НомерСообщения);
|
||||
|
||||
// Записываем данные любым способом, которым удобно
|
||||
// тут приведен пример примитивной поузловой записи
|
||||
ЗаписьXML.ЗаписатьНачалоЭлемента("СписокНоменклатуры");
|
||||
|
||||
Пока ВыборкаИзменений.Следующий() Цикл
|
||||
|
||||
Данные = ВыборкаИзменений.Получить();
|
||||
|
||||
ЗаписьXML.ЗаписатьНачалоЭлемента("Номенклатура");
|
||||
|
||||
ЗаписьXML.ЗаписатьНачалоЭлемента("Код");
|
||||
ЗаписьXML.ЗаписатьТекст(Данные.Код);
|
||||
ЗаписьXML.ЗаписатьКонецЭлемента();
|
||||
|
||||
...
|
||||
|
||||
ЗаписьXML.ЗаписатьНачалоЭлемента("ПометкаУдаления");
|
||||
ЗаписьXML.ЗаписатьТекст(Строка(Данные.ПометкаУдаления));
|
||||
ЗаписьXML.ЗаписатьКонецЭлемента();
|
||||
|
||||
ЗаписьXML.ЗаписатьКонецЭлемента();
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
ЗаписьXML.ЗаписатьКонецЭлемента();
|
||||
|
||||
// закрываем служебные узлы сообщения
|
||||
ЗаписьСообщения.ЗакончитьЗапись();
|
||||
|
||||
ЗаписьXML.Закрыть();
|
||||
|
||||
Сообщение = Новый СообщениеПользователю;
|
||||
Сообщение.Текст = "Успешная выгрузка";
|
||||
Сообщение.Сообщить();
|
||||
|
||||
КонецПроцедуры
|
||||
|
||||
```
|
||||
|
||||
В результате получим xml вида:
|
||||
|
||||
```xml
|
||||
|
||||
<!--Начало блока, добавляемого методом ЗаписьСообщения.НачатьЗапись()-->
|
||||
<v8msg:Message xmlns:v8msg="http://v8.1c.ru/messages">
|
||||
<v8msg:Header>
|
||||
<v8msg:ExchangePlan>СН_ОбменСПриемником</v8msg:ExchangePlan>
|
||||
<v8msg:To>ПБ</v8msg:To>
|
||||
<v8msg:From>ИБ</v8msg:From>
|
||||
<v8msg:MessageNo>16</v8msg:MessageNo>
|
||||
<v8msg:ReceivedNo>0</v8msg:ReceivedNo>
|
||||
</v8msg:Header>
|
||||
<v8msg:Body>
|
||||
<!--конец блока, добавляемого методом ЗаписьСообщения.НачатьЗапись()-->
|
||||
|
||||
<!--Начало блока, который формируется нами вручную-->
|
||||
<СписокНоменклатуры>
|
||||
<Номенклатура>
|
||||
<Код>000000006</Код>
|
||||
...
|
||||
<ПометкаУдаления>Нет</ПометкаУдаления>
|
||||
</Номенклатура>
|
||||
<Номенклатура>
|
||||
...
|
||||
</Номенклатура>
|
||||
...
|
||||
<Номенклатура>
|
||||
...
|
||||
</Номенклатура>
|
||||
</СписокНоменклатуры>
|
||||
<!--Конец блока, который формируется нами вручную-->
|
||||
|
||||
<!--Начало блока, добавляемого методом ЗаписьСообщения.ЗакончитьЗапись()-->
|
||||
</v8msg:Body>
|
||||
</v8msg:Message>
|
||||
<!--Конец блока, добавляемого методом ЗаписьСообщения.ЗакончитьЗапись()-->
|
||||
|
||||
```
|
||||
|
||||
### Чтение сообщения в базе-приемнике
|
||||
|
||||
> **ВАЖНО! В приемнике должен быть план обмена с таким же именем, что и в источнике. Также нужно, чтобы код узла базы приемника совпадал с кодом, указанным в шапке сообщения в блоке `<v8msg:To>`** . Это необходимо для того, чтобы методы чтения сообщения корректно сработали
|
||||
|
||||
Считываем данные для обработки в приемнике
|
||||
|
||||
```bsl
|
||||
// ПолноеИмяФайла - путь к файлу обмена, созданному источником
|
||||
// ТаблицаДляЗагрузки - промежуточная таблица для последующей загрузки в запрос
|
||||
Процедура ЗаполнитьТаблицуДляЗагрузки(ПолноеИмяФайла, ТаблицаДляЗагрузки)
|
||||
|
||||
СоответствиеКолонокУзлам = Новый Соответствие;
|
||||
СоответствиеКолонокУзлам.Вставить("Наименование", "Наименование");
|
||||
...
|
||||
СоответствиеКолонокУзлам.Вставить("ПометкаУдаления", "ПометкаУдаления");
|
||||
|
||||
// Создаем объект чтения сообщения
|
||||
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
|
||||
|
||||
// Создаем объект, который будет использоваться чтением сообщения
|
||||
ЧтениеXML = Новый ЧтениеXML;
|
||||
ЧтениеXML.ОткрытьФайл(ПолноеИмяФайла);
|
||||
|
||||
// Считываем служебную информацию сообщения. Код узла, номера сообщений и пр.
|
||||
ЧтениеСообщения.НачатьЧтение(ЧтениеXML);
|
||||
|
||||
// Проверяем, что отправитель это именно та база, откуда мы ожидаем сообщение
|
||||
Если ЧтениеСообщения.Отправитель <> "ИБ" Тогда
|
||||
//Обработка ошибки
|
||||
Возврат;
|
||||
КонецЕсли;
|
||||
|
||||
// Считываем данные, записанные в <body> узле сообщения
|
||||
Пока ЧтениеXML.Прочитать() Цикл
|
||||
|
||||
// Мы должны закончить чтение на узле </v8msg:Body>,
|
||||
// иначе метод ЧтениеСообщения.ЗакончитьЧтение() завершится с ошибкой
|
||||
Если ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента
|
||||
И ЧтениеXML.Имя = "v8msg:Body" Тогда
|
||||
Прервать;
|
||||
КонецЕсли;
|
||||
|
||||
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
|
||||
|
||||
ИмяТекущегоУзла = ЧтениеXML.Имя;
|
||||
Если ИмяТекущегоУзла = "Номенклатура" Тогда
|
||||
СтрокаТаблицы = ТаблицаДляЗагрузки.Добавить();
|
||||
КонецЕсли;
|
||||
|
||||
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
|
||||
|
||||
ИмяКолонкиТаблицы = СоответствиеКолонокУзлам.Получить(ИмяТекущегоУзла);
|
||||
|
||||
Если ИмяКолонкиТаблицы <> Неопределено Тогда
|
||||
СтрокаТаблицы[ИмяКолонкиТаблицы] = ЧтениеXML.Значение;
|
||||
КонецЕсли;
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
// Считываем закрывающие служебные тэги сообщения
|
||||
ЧтениеСообщения.ЗакончитьЧтение();
|
||||
|
||||
// завершаем чтение файла
|
||||
ЧтениеXML.Закрыть();
|
||||
|
||||
КонецПроцедуры
|
||||
|
||||
```
|
||||
Чтение будет проходить следующими этапами
|
||||
|
||||
```xml
|
||||
|
||||
<!--ЧтениеСообщения.НачатьЧтение()-->
|
||||
<v8msg:Message xmlns:v8msg="http://v8.1c.ru/messages">
|
||||
<v8msg:Header>
|
||||
<v8msg:ExchangePlan>СН_ОбменСПриемником</v8msg:ExchangePlan>
|
||||
<v8msg:To>ПБ</v8msg:To>
|
||||
<v8msg:From>ИБ</v8msg:From>
|
||||
<v8msg:MessageNo>16</v8msg:MessageNo>
|
||||
<v8msg:ReceivedNo>0</v8msg:ReceivedNo>
|
||||
</v8msg:Header>
|
||||
<v8msg:Body>
|
||||
<!--Конец ЧтениеСообщения.НачатьЧтение()-->
|
||||
|
||||
<!--ЧтениеXML.Прочитать()-->
|
||||
<СписокНоменклатуры>
|
||||
<Номенклатура>
|
||||
<Код>000000006</Код>
|
||||
...
|
||||
<ПометкаУдаления>Нет</ПометкаУдаления>
|
||||
</Номенклатура>
|
||||
<Номенклатура>
|
||||
...
|
||||
</Номенклатура>
|
||||
<Номенклатура>
|
||||
...
|
||||
</Номенклатура>
|
||||
...
|
||||
<Номенклатура>
|
||||
...
|
||||
</Номенклатура>
|
||||
</СписокНоменклатуры>
|
||||
<!--Конец ЧтениеXML.Прочитать()-->
|
||||
|
||||
<!--ЧтениеСообщения.ЗакончитьЧтение()-->
|
||||
</v8msg:Body>
|
||||
</v8msg:Message>
|
||||
<!--Конец ЧтениеСообщения.ЗакончитьЧтение()-->
|
||||
|
||||
<!--ЧтениеXML.Закрыть()-->
|
||||
|
||||
```
|
||||
|
||||
Дальше обрабатываем данные файла в приемнике как нужно.
|
||||
|
||||
## Сообщение Приемник-Источник. Квитирование (гарантия доставки)
|
||||
|
||||
### Формирование сообщения в базе приемнике
|
||||
|
||||
Квитирование необходимо для того, чтобы дать источнику данные о том, какие сообщения приемник получил и успешно обработал. Записи таблицы изменений, где номер сообщения меньше либо равен номеру, указанному в квитанции можно удалять из таблицы изменений.
|
||||
|
||||
Простыми словами, после того, как в базе источнике мы обработали все данные, нужно сформировать ответное сообщение только с шапкой, без данных. В шапке будет указан `НомерПринятого`, который будет равен `НомеруОтправленного` из полученного ранее сообщения
|
||||
|
||||
```bsl
|
||||
|
||||
Процедура СформироватьКвитанциюЗаписатьВКаталогОбмена()
|
||||
|
||||
// куда сохраняем квитанцию
|
||||
ИмяФайла = "C:\путь-до-папки-обмена\Квитанция_ПБ_ИБ.xml";
|
||||
|
||||
// Узел в плане обмена, которому направляем квитанцию о получении
|
||||
Узел = ПланыОбмена.СН_ОбменСПриемником.НайтиПоКоду("ИБ");
|
||||
Если Не ЗначениеЗаполнено(Узел) Тогда
|
||||
ВызватьИсключение "Неопределенный узел получателя квитанции";
|
||||
КонецЕсли;
|
||||
|
||||
Запись = Новый ЗаписьXML;
|
||||
Запись.ОткрытьФайл(ИмяФайла);
|
||||
|
||||
// Тут записываем шапку
|
||||
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
|
||||
ЗаписьСообщения.НачатьЗапись(Запись, Узел);
|
||||
|
||||
// заканчиваем запись, не записывая тело. Только шапка
|
||||
ЗаписьСообщения.ЗакончитьЗапись();
|
||||
|
||||
// Закрываем файл
|
||||
Запись.Закрыть();
|
||||
|
||||
КонецПроцедуры
|
||||
|
||||
```
|
||||
|
||||
Пример квитанции
|
||||
```xml
|
||||
<v8msg:Message xmlns:v8msg="http://v8.1c.ru/messages">
|
||||
<v8msg:Header>
|
||||
<v8msg:ExchangePlan>СН_ОбменСПриемником</v8msg:ExchangePlan>
|
||||
<v8msg:To>ИБ</v8msg:To>
|
||||
<v8msg:From>ПБ</v8msg:From>
|
||||
<v8msg:MessageNo>4</v8msg:MessageNo>
|
||||
<v8msg:ReceivedNo>20</v8msg:ReceivedNo>
|
||||
</v8msg:Header>
|
||||
<v8msg:Body/>
|
||||
</v8msg:Message>
|
||||
```
|
||||
|
||||
### Чтение квитанции в базе-источнике. Удаление записей о регистрации изменений
|
||||
В источнике нужно считать квитанцию, сформированную выше, и удалить из таблиц изменений все записи, **номер отправленного** которых меньше или равен **номеру принятого в квитанции**
|
||||
|
||||
```bsl
|
||||
Процедура ПрочитатьКвитанциюУдалитьИзмененияИзПланаОбмена(УзелОбмена) Экспорт
|
||||
|
||||
ПутьКФайлу = "C:\путь-до-папки-обмена\Квитанция_ПБ_ИБ.xml";
|
||||
|
||||
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
|
||||
|
||||
Чтение = Новый ЧтениеXML;
|
||||
Чтение.ОткрытьФайл(ПутьКФайлу);
|
||||
|
||||
// считываем квитанцию
|
||||
ЧтениеСообщения.НачатьЧтение(Чтение);
|
||||
|
||||
НомерПринятого = ЧтениеСообщения.НомерПринятого;
|
||||
|
||||
// удаляем переданное по номеру принятого, указанного в квитанции
|
||||
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, НомерПринятого);
|
||||
|
||||
ЧтениеСообщения.ЗакончитьЧтение();
|
||||
|
||||
Чтение.Закрыть();
|
||||
|
||||
// удаляем квитанции
|
||||
УдалитьФайлы(ПутьКФайлу);
|
||||
|
||||
КонецПроцедуры
|
||||
```
|
@ -13,8 +13,8 @@ slug: общие-обмен-данными-планы-обмена/работа-
|
||||
```
|
||||
|
||||
## Как создать сообщение обмена
|
||||
```bsl
|
||||
|
||||
```bsl
|
||||
// 0. Создаем объект ЗаписьXML для формирования XML-файла
|
||||
ПутьКФайлуСообщения = "S:\Exchange\Message_ИС_ПР.xml";
|
||||
ЗаписьXML = Новый ЗаписьXML();
|
||||
@ -40,6 +40,10 @@ slug: общие-обмен-данными-планы-обмена/работа-
|
||||
|
||||
```
|
||||
|
||||
## Как прочитать сообщение обмена в другой базе
|
||||
|
||||
В базе приемнике должен быть создан такой же план обмена
|
||||
|
||||
## Как прочитать изменения, зарегистрированные в плане обмена
|
||||
### С присваиванием номера сообщения
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user