В начало

План обмена справочника «Животинки»

 

            Нужно организовать обмен справочника «Животинки» между двумя различными конфигурациями посредством плана обмена.

            Сам справочник показан ниже.

Рис. Структура справочника «Животинки» в центральной базе

Рис. Фрагмент формы списка справочника «Животинки» в центральной базе

 

            Создаем новый план обмена, называем его «ОбменЖивотинок». Не откладывая в долгий ящик, тут же корректируем состав плана обмена «ОбменЖивотинок».

Рис. Свойства плана обмена «ОбменЖивотинок», закладка «Основные»

 

            На закладке «Данные» добавляем реквизит «ГлавныйУзел» с типом «Булево», который необходим для разрешения конфликтных ситуаций во время обмена сообщений между базами.

Рис. Свойства плана обмена, закладка «Данные»

 

            На вкладке «Формы» добавляем две формы, а именно: ФормуУзла и ФормуСписка.

Рис. Форма узла плана обмена «ОбменЖивотинок» в конфигураторе центральной базы

 

            Далее немного корректируем форму списка, добавляя на нее кнопку «ЗарегистрироватьИзменения».

Рис. Форма списка плана обмена «ОбменЖивотинок» в конфигураторе центральной базы

 

            После этого начинаем кодить. Первым делом открываем модуль объекта  плана обмена «ОбменЖивотинок» и добавляем нужные процедуры, делаем их экспортными, ибо вызывать их будем в дальнейшем из обработки, которую создадим чуть позже. В данном модуле две процедуры: ЗаписатьСообщениеСИзменениями() и ПрочитатьСообщениеСИзменениями().

 

Листинг. Содержимое модуля объекта плана обмена «ОбменЖивотинок»

Процедура ЗаписатьСообщениеСИзменениями() Экспорт

            Сообщение = Новый СообщениеПользователю;

            Сообщение.Текст = "-------- Выгрузка в узел " + Строка(ЭтотОбъект) + " ------------";

            Сообщение.Сообщить();

            Каталог = КаталогВременныхФайлов();

            // Сформировать имя файла сообщения

            ИмяФайла = Каталог + ?(Прав(Каталог, 1) = "\","", "\") + "Сообщение_ОбменЖивотинок_" +

            СокрЛП(ПланыОбмена.ОбменЖивотинок.ЭтотУзел().Код) + "-" + СокрЛП(Ссылка.Код) + ".xml";

            // Создать объект записи XML

            ЗаписьXML = Новый ЗаписьXML;

            ЗаписьXML.ОткрытьФайл(ИмяФайла);

            ЗаписьXML.ЗаписатьОбъявлениеXML();

            // *** Инфраструктура сообщений

            ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();

            ЗаписьСообщения.НачатьЗапись(ЗаписьXML, Ссылка);

            Сообщение = Новый СообщениеПользователю;

            Сообщение.Текст = " Номер сообщения: " + ЗаписьСообщения.НомерСообщения;

            Сообщение.Сообщить();

            // Получить выборку измененных данных

            // *** Механизм регистрации изменений

            ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения);

            Пока ВыборкаИзменений.Следующий() Цикл

                        ЗаписатьXML(ЗаписьXML, ВыборкаИзменений.Получить());

            КонецЦикла;

            ЗаписьСообщения.ЗакончитьЗапись();

            ЗаписьXML.Закрыть();

            Сообщение = Новый СообщениеПользователю;

            Сообщение.Текст = "-------- Конец выгрузки ------------";

            Сообщение.Сообщить();

КонецПроцедуры

 

Процедура ПрочитатьСообщениеСИзменениями() Экспорт

            Каталог = КаталогВременныхФайлов();

            // Сформировать имя файла.

            ИмяФайла = Каталог + ?(Прав(Каталог, 1) = "\", "", "\") + "Сообщение_ОбменЖивотинок_" +

                       СокрЛП(Ссылка.Код) + "-" +

                       СокрЛП(ПланыОбмена.ОбменЖивотинок.ЭтотУзел().Код) + ".xml";

            Файл = Новый Файл(ИмяФайла);

            Если Не Файл.Существует() Тогда

                        Возврат;

            КонецЕсли;

            // *** Чтение документов XML

            // Попытаться открыть файл.

            ЧтениеXML = Новый ЧтениеXML;

            Попытка

                        ЧтениеXML.ОткрытьФайл(ИмяФайла);

            Исключение

                        Сообщение = Новый СообщениеПользователю;

                        Сообщение.Текст = "Невозможно открыть файл обмена данными.";

                        Сообщение.Сообщить();

                        Возврат;

            КонецПопытки;

            Сообщение = Новый СообщениеПользователю;

            Сообщение.Текст = "-------- Загрузка из " + Строка(ЭтотОбъект) + " ------------";

            Сообщение.Сообщить();

            Сообщение = Новый СообщениеПользователю;

            Сообщение.Текст = " – Считывается файл " + ИмяФайла;

            Сообщение.Сообщить();

            // Загрузить из найденного файла

            // *** Инфраструктура сообщений.

            ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();

            // Читать заголовок сообщения обмена данными – файла XML.

            ЧтениеСообщения.НачатьЧтение(ЧтениеXML);

            // Сообщение предназначено не для этого узла.

            Если ЧтениеСообщения.Отправитель <> Ссылка Тогда

                        ВызватьИсключение "Неверный узел";

            КонецЕсли;

            // Удаляем регистрацию изменений для узла отправителя сообщения

            // *** Служба регистрации изменений.

            ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель,

            ЧтениеСообщения.НомерПринятого);

            // Читаем данные из сообщения *** XML-сериализация.

            Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл

                        // Читаем очередное значение.

                        Данные = ПрочитатьXML(ЧтениеXML);

                        // Не переносим изменение, полученное в главный из неглавного,

                        // если есть регистрация изменения.

                        Если Не ЧтениеСообщения.Отправитель.ГлавныйУзел И

                                   ПланыОбмена.ИзменениеЗарегистрировано(

                                   ЧтениеСообщения.Отправитель, Данные) Тогда

                                   Сообщение = Новый СообщениеПользователю;

                                   Сообщение.Текст = " – Изменения отклонены";

                                   Сообщение.Сообщить();

                                   Продолжить;

                        КонецЕсли;

                        // Записать полученные данные.

                        Данные.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель;

                        Данные.ОбменДанными.Загрузка = Истина;

                        Данные.Записать();

            КонецЦикла;

            ЧтениеСообщения.ЗакончитьЧтение();

            ЧтениеXML.Закрыть();

            УдалитьФайлы(ИмяФайла);

            Сообщение = Новый СообщениеПользователю;

            Сообщение.Текст = "-------- Конец загрузки ------------";

            Сообщение.Сообщить();

КонецПроцедуры

 

            Далее переходим в модуль формы узла и создаем обработчик «ПередОткрытием», который будет устанавливать доступность реквизита «ГлавныйУзел» объекта план обмена «ОбменЖивотинок».

 

Листинг. Модуль формы узла плана обмена «ОбменЖивотинок»

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)

            Если ЭтотОбъект.Ссылка = ПланыОбмена.ОбменЖивотинок.ЭтотУзел() Тогда

                        ЭлементыФормы.ГлавныйУзел.Доступность = Ложь;

            КонецЕсли;

КонецПроцедуры

 

            Затем переходим в модуль формы списка плана обмена и добавляем действие на нажатие кнопки «ЗарегистрироватьИзменения» и обработчик «ПриАктивизацииСтроки».

 

Листинг. Модуль формы списка плана обмена «ОбменЖивотинок»

Процедура ЗарегистрироватьИзмененияНажатие(Элемент)

            Запрос = Новый Запрос;

            Запрос.Текст =

            "ВЫБРАТЬ

            |         ЖивотинкиИзменения.Ссылка

            |ИЗ

            |         Справочник.Животинки.Изменения КАК ЖивотинкиИзменения";

           

            Результат = Запрос.Выполнить();

            Выборка = Результат.Выбрать();

            ТекУзел = ЭлементыФормы.ПланОбменаСписок.ТекущаяСтрока;

           

            Пока Выборка.Следующий() Цикл

                        ПланыОбмена.ЗарегистрироватьИзменения(ТекУзел, Выборка.Ссылка);

            КонецЦикла;         

КонецПроцедуры

 

Функция ЭтоПредопределенныйУзел(Узел)

            Возврат Узел = ПланыОбмена.ОбменЖивотинок.ЭтотУзел();

КонецФункции

 

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

            Если ЭтоПредопределенныйУзел(ЭлементыФормы.ПланОбменаСписок.ТекущаяСтрока) Тогда

                        ЭлементыФормы.ЗарегистрироватьИзменения.Доступность = Ложь;

            Иначе

                        ЭлементыФормы.ЗарегистрироватьИзменения.Доступность = Истина;

            КонецЕсли;

КонецПроцедуры

 

            Далее создаём обработку «ОбменДаннымиЖивотинок», добавляем форму обработки и добавляем событие на нажатие кнопки «Выполнить обмен данными».

Рис. Форма обработки «ОбменДаннымиЖивотинок» в конфигураторе центральной базы

 

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

 

Листинг. Модуль формы обработки «ОбменДаннымиЖивотинок»

Процедура КнопкаВыполнитьНажатие(Кнопка)

            ВыборкаУзлов = ПланыОбмена.ОбменЖивотинок.Выбрать();

            Пока ВыборкаУзлов.Следующий() Цикл

                        // Произвести обмен данными со всеми узлами, кроме текущего

                        Если ВыборкаУзлов.Ссылка <> ПланыОбмена.ОбменЖивотинок.ЭтотУзел() Тогда

                                   УзелОбъект = ВыборкаУзлов.ПолучитьОбъект();

                                  

                                   УзелОбъект.ПрочитатьСообщениеСИзменениями();

                                   УзелОбъект.ЗаписатьСообщениеСИзменениями();

                        КонецЕсли;

            КонецЦикла;

КонецПроцедуры

 

            Протестируем изменения в режиме отладки. Открываем план обмена «Обмен животинок» и настраиваем узлы. Предопределенный узел называем «ЦБ», что означает «Центральная база», также создаем еще один узел для филиала, который называем «ФЛ», как показано далее. Выделяем узел «ФЛ» и нажимаем кнопку «Зарегистрировать изменения».

Рис. Настройка узлов в плане обмена «Обмен животинок»

 

            Затем вызываем обработку «ОбменДаннымиЖивотинок» и нажимаем кнопку выполнить обмен. Если ошибок нет, то увидим служебное сообщение в нижней части экрана.

Рис. Служебное сообщение обработки «ОбменДаннымиЖивотинок»

 

            При этом будет создан XML-файл сообщения в каталоге временных файлов с именем «Сообщение_ОбменЖивотинок_ЦБ-ФЛ.xml». Из его названия видно, кто создал файл (ОбменЖивотинок) и откуда-куда (ЦБ-ФЛ) переносятся данные справочника «Животинки». В данном случае мы переносим данные из центральной базы «ЦБ» в базу филиала организации «ФЛ».

            Файл обмена можно просмотреть текстовым редактором или браузером, а потом проанализировать.

Листинг. Файл сообщения «Сообщение_ОбменЖивотинок_ЦБ-ФЛ.xml»

<?xml version="1.0" encoding="UTF-8"?>

<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>2</v8msg:MessageNo>

                        <v8msg:ReceivedNo>0</v8msg:ReceivedNo>

            </v8msg:Header>

            <v8msg:Body>

                        <CatalogObject.Животинки>

                                   <Ref>78076726-a7a1-11ec-8fd8-001eec3547a4</Ref>

                                   <DeletionMark>false</DeletionMark>

                                   <Code>000000005</Code>

                                   <Description>Амурский ёж</Description>

                        </CatalogObject.Животинки>

            </v8msg:Body>

</v8msg:Message>

 

            Далее аналогичным способом настроим конфигурацию филиала. Поскольку в филиале используются управляемые формы, то  будут иметь место некоторые отличия.

            Начнем с модуля плана обмена. В модуле плана обмена должны располагаться две процедуры, они полностью идентичны процедурам, расположенным в конфигурации центральной базы.

            В плане обмена создаем форму узла.

Рис. Форма узла плана обмена в конфигураторе филиала

 

            В модуль формы узла добавляем обработчик «ПриСозданииНаСервере».

 

Листинг. Модуль формы узла плана обмена в конфигураторе филиала

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

            Если Объект.Ссылка = ПланыОбмена.ОбменЖивотинок.ЭтотУзел() Тогда

                        Элементы.ГлавныйУзел.Доступность = Ложь;

            КонецЕсли;

КонецПроцедуры

 

            Далее создаём форму списка плана обмена и добавляем команду «ЗарегистрироватьИзменения».

Рис. Форма списка плана обмена в конфигураторе филиала

 

            Добавляем действие на нажатие команды/кнопки «ЗарегистрироватьИзменения» и обработчик события «ПриАктивизацииСтроки».

 

Листинг. Модуль формы узла плана обмена в конфигурации филиала

&НаСервереБезКонтекста

Функция ЭтоПредопределенныйУзел(Узел)

            Возврат Узел = ПланыОбмена.ОбменЖивотинок.ЭтотУзел();

КонецФункции

 

&НаКлиенте

Процедура СписокПриАктивизацииСтроки(Элемент)

            Если ЭтоПредопределенныйУзел(Элемент.ТекущаяСтрока) Тогда

                        Элементы.ЗарегистрироватьИзменения.Доступность = Ложь;

            Иначе

                        Элементы.ЗарегистрироватьИзменения.Доступность = Истина;

            КонецЕсли;

КонецПроцедуры

 

&НаСервереБезКонтекста

Процедура ЗарегистрироватьИзмененияНаСервере(ТекУзел)

            Запрос = Новый Запрос;

            Запрос.Текст =

            "ВЫБРАТЬ

            |         ЖивотинкиИзменения.Ссылка

            |ИЗ

            |         Справочник.Животинки.Изменения КАК ЖивотинкиИзменения";

           

            Результат = Запрос.Выполнить();

            Выборка = Результат.Выбрать();

           

            Пока Выборка.Следующий() Цикл

                        ПланыОбмена.ЗарегистрироватьИзменения(ТекУзел, Выборка.Ссылка);

            КонецЦикла;

КонецПроцедуры

 

&НаКлиенте

Процедура ЗарегистрироватьИзменения(Команда)

            ЗарегистрироватьИзмененияНаСервере(Элементы.Список.ТекущаяСтрока);

КонецПроцедуры

 

            Потом создадим обработку «ОбменДаннымиЖивотинок» в конфигурации филиала. Создаём форму обработки, затем команду «ВыполнитьОбменДанных».

Рис. Форма обработки «ОбменДаннымиЖивотинок»

 

            Далее добавим действие для команды «ВыполнитьОбменДанных», для чего перейдем в модуль формы обработки.

 

Листинг. Форма обработки «ОбменДаннымиЖивотинок»

&НаСервереБезКонтекста

Процедура ВыполнитьОбменДанныхНаСервере()

            ВыборкаУзлов = ПланыОбмена.ОбменЖивотинок.Выбрать();

            Пока ВыборкаУзлов.Следующий() Цикл

                        // Произвести обмен данными со всеми узлами, кроме текущего

                        Если ВыборкаУзлов.Ссылка <> ПланыОбмена.ОбменЖивотинок.ЭтотУзел() Тогда

                                   УзелОбъект = ВыборкаУзлов.ПолучитьОбъект();

                                  

                                   УзелОбъект.ПрочитатьСообщениеСИзменениями();

                                   УзелОбъект.ЗаписатьСообщениеСИзменениями();

                        КонецЕсли;

            КонецЦикла;

КонецПроцедуры

 

&НаКлиенте

Процедура ВыполнитьОбменДанных(Команда)

            ВыполнитьОбменДанныхНаСервере();

КонецПроцедуры

 

            Конфигурация филиала готова, протестируем ее в режиме отладки. Переходим в план обмена «Обмен животинок» и настраиваем узлы. Предопределенный узел будет филиал с кодом «ФЛ». Добавляем узел центральной базы с кодом «ЦБ», для которого ставим галочку на элементе «Главный узел».

Рис. Настройка узлов плана обмена «Обмен животинок»

 

            Затем выделяем узел «ЦБ» и нажимаем кнопку «Зарегистрировать изменения».

            Далее вызываем обработку «ОбменДаннымиЖивотинок» и жмем «Выполнить обмен данных». Если ошибок нет. То будет выведено сообщение, как показано далее, а также создан другой файл, с именем  «Сообщение_ОбменЖивотинок_ФЛ-ЦБ.xml» для передачи данных из филиала в центральную базу.

Рис. Сообщение обработки «ОбменДаннымиЖивотинок»

 

            Также будут внесены изменения в справочник «Животинки».

Рис. Справочник «Животинки» в базе филиала

            Чтобы еще лучше протестировать обмен данными справочника «Животинки», надо вернуться в центральную базу и вызвав обработку «ОбменДаннымиЖивотинок» повторить обмен. Таким образом обмен будет выглядеть так: ЦБ –> ФЛ –> ЦБ.