В начало

Обмен данными регистра «ЗадолженностиПоДтЗ»

 

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

            Далее приведена структура регистра сведений «Задолженности по ДтЗ», хотя в дальнейшем она нам не понадобится и представляет собой чисто справочную информацию.

Рис. Структура регистра сведений на дереве метаданных

 

Рис. Форма списка регистра сведений «Задолженности по ДтЗ» в центральной базе (ЦБ)

 

            Итак, первым делом создаём новый план обмена, который назовём «ОбменЗадолженностиПоДтЗ». На закладке свойств объекта нажимаем на кнопку «Состав» и добавляем регистр сведений «ЗадолженностиПоДтЗ».

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

 

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

            Затем на вкладке «Формы» создаём две формы: ФормуУзла и ФормуСписка.

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

 

            На форме списка размещаем кнопку «Зарегистрировать изменения». Форма содержит следующие колонки: Код, Наименование, Номер отправленного сообщения, Номер принятого сообщения.

Рис. Форма списка плана обмена «ОбменЗадолженностиПоДтЗ»

 

            После этого начинаем работу с модулями, процедурками и функциями.

            Если идти по порядку, то переходим в модуль объекта плана обмена «ОбменЗадолженностиПоДтЗ» и размещаем в нём две процедуры для работы с файлами сообщений.

 

Листинг. Модуль объекта плана обмена «ОбменЗадолженностиПоДтЗ»

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

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

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

            ИмяФайла = Каталог + ?(Прав(Каталог, 1) = "\", "", "\") + "Сообщение_ЗадолженностиПоДтЗ_" +

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

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

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

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

                        Возврат;

            КонецЕсли;

            // *** Чтение документов 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 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>1</v8msg:MessageNo>

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

                </v8msg:Header>

                <v8msg:Body>

                               <InformationRegisterRecordSet.ЗадолженностиПоДтЗ>

                                               <Filter>

                                                               <Организация>65fe85a0-85bc-11eb-9834-001eec3547a4</Организация>

                                                               <Контрагент>d0d0bba6-f01b-11ea-980c-001eec3547a4</Контрагент>

                                                               <Договор>107023fb-d1a6-11eb-8637-001eec3547a4</Договор>

                                               </Filter>

                                               <Records>

                                                               <Record>

                                                                              <Организация>65fe85a0-85bc-11eb-9834-001eec3547a4</Организация>

                                                                              <Контрагент>d0d0bba6-f01b-11ea-980c-001eec3547a4</Контрагент>

                                                                              <Договор>107023fb-d1a6-11eb-8637-001eec3547a4</Договор>

                                                                              <РазыскиваемаяДЗ>0</РазыскиваемаяДЗ>

                                                                              <БумажнаяДЗ>200</БумажнаяДЗ>

                                                                              <ПросроченнаяДЗ>300</ПросроченнаяДЗ>

                                                               </Record>

                                               </Records>

                               </InformationRegisterRecordSet.ЗадолженностиПоДтЗ>

                </v8msg:Body>

</v8msg:Message>

 

            Таким образом, конфигурацию центральной базы мы настроили и отладили, далее нужно также настроить конфигурацию филиала.

            Начинаем с плана обмена в базе филиала.

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

            Добавляем обработчик «ПриСозданииНаСервере».

 

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

&НаСервере

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

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

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

            КонецЕсли;

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

 

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

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

 

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

 

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

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

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

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

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

            "ВЫБРАТЬ

            |          ЗадолженностиПоДтЗИзменения.Организация,

            |          ЗадолженностиПоДтЗИзменения.Контрагент,

            |          ЗадолженностиПоДтЗИзменения.Договор

            |ИЗ

            |          РегистрСведений.ЗадолженностиПоДтЗ.Изменения КАК ЗадолженностиПоДтЗИзменения";

           

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

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

            НЗ = РегистрыСведений.ЗадолженностиПоДтЗ.СоздатьНаборЗаписей();

           

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

                        НЗ.Отбор.Организация.Значение = Выборка.Организация;

                        НЗ.Отбор.Организация.Использование = Истина;

                       

                        НЗ.Отбор.Контрагент.Значение = Выборка.Контрагент;

                        НЗ.Отбор.Контрагент.Использование = Истина;

                       

                        НЗ.Отбор.Договор.Значение = Выборка.Договор;

                        НЗ.Отбор.Договор.Использование = Истина;

                       

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

            КонецЦикла;

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

 

&НаКлиенте

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

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

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

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

 

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

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

            Возврат Узел = ПланыОбмена.ОбменЗадолженностиПоДтЗ.ЭтотУзел();

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

 

&НаКлиенте

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

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

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

            Иначе

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

            КонецЕсли;

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

 

            Создаем обработку обмена «ОбменДаннымиЗадолженностиПоДтЗ». Добавляем форму обработки. Размещаем на форме кнопку «ВыполнитьОбмен».

Рис. Форма обработки «ОбменДаннымиЗадолженностиПоДтЗ»

 

            Добавляем действие для кнопки «Выполнить обмен».

 

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

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

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

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

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

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

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

                                  

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

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

                        КонецЕсли;

            КонецЦикла;

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

 

&НаКлиенте

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

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

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

 

            Запускаем конфигурацию филиала в режиме отладки. Настраиваем список узлов плана обмена.

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

 

            Потом запускаем обработку обмена. Нажимаем на ней кнопку «Выполнить обмен».

Рис. Обработка «Обмен данными задолженности по ДтЗ»

 

            При этом будет прочитан один файл с сообщение от центральной базы и создан другой файл, с изменениями для передачи из филиала в центральную базу «Сообщение_ЗадолженностиПоДтЗ_ФЛ-ЦБ.xml».

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

            Для надёжности нужно выполнить три обмена, т.е. ЦБ->ФЛ, ФЛ->ЦБ и ЦБ->ФЛ, чтобы изменения из центральной базы, если они есть ушли в базу филиала, потом зафиксировать данные из центральной базы в базе филиала и наконец, зафиксировать изменения из филиала в центральной базе.