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-файла
|
// 0. Создаем объект ЗаписьXML для формирования XML-файла
|
||||||
ПутьКФайлуСообщения = "S:\Exchange\Message_ИС_ПР.xml";
|
ПутьКФайлуСообщения = "S:\Exchange\Message_ИС_ПР.xml";
|
||||||
ЗаписьXML = Новый ЗаписьXML();
|
ЗаписьXML = Новый ЗаписьXML();
|
||||||
@ -40,6 +40,10 @@ slug: общие-обмен-данными-планы-обмена/работа-
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Как прочитать сообщение обмена в другой базе
|
||||||
|
|
||||||
|
В базе приемнике должен быть создан такой же план обмена
|
||||||
|
|
||||||
## Как прочитать изменения, зарегистрированные в плане обмена
|
## Как прочитать изменения, зарегистрированные в плане обмена
|
||||||
### С присваиванием номера сообщения
|
### С присваиванием номера сообщения
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user