В начало

Обмен регистра сведений «КадровыеПеремещения»

 

            Необходимо сделать обмен данными по кадровым перемещениям сотрудников, которые зафиксированы в регистре сведений «КадровыеПеремещения», подчиненного регистратору, которым является документ «ПриемНаРаботу».

Рис. Структура регистра сведений «КадровыеПеремещения»

 

            Создаем новый план обмена «ОбменКадровыхПеремещений» в конфигураторе центральной базы. Изменяем состав плана обмена, а именно добавляем наш регистр сведений «КадровыеПеремещения».

Рис. Свойства плана обмена «ОбменКадровыхПеремешений», изменение состава

 

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

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

Рис. Форма узла плана обмена «ОбменКадровыхПеремещений»

 

            На форме списка размещаем кнопочку «ЗарегистрироватьИзменения», которая нужна для регистрации изменений регистра сведения «КадровыеПеремещения».

Рис. Форма списка плана обмена «ОбменКадровыхПеремещений»

 

            С визуальной частью плана обмена почти все, переходим к созданию процедур и функций. Первым делом размещаем в модуле объекта плана обмена парочку нужных процедур.

 

Листинг. Модуль объекта плана обмена

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

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

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

            ИмяФайла = Каталог + ?(Прав(Каталог, 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 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>

                               <InformationRegisterRecordSet.КадровыеПеремещения>

                                               <Filter>

                                                               <Recorder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="DocumentRef.ПриемНаРаботу">4bb836c6-fb22-11ea-80dc-001eec3547a4</Recorder>

                                               </Filter>

                                               <Records>

                                                               <Record>

                                                                              <Recorder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="DocumentRef.ПриемНаРаботу">4bb836c6-fb22-11ea-80dc-001eec3547a4</Recorder>

                                                                              <Period>2020-09-20T00:00:00</Period>

                                                                              <Active>true</Active>

                                                                              <Сотрудник>b4c479df-f4c8-11ea-9489-001eec3547a4</Сотрудник>

                                                                              <Подразделение>1e9a4576-fb18-11ea-80dc-001eec3547a4</Подразделение>

                                                                              <Должность>1e9a4575-fb18-11ea-80dc-001eec3547a4</Должность>

                                                                              <Оклад>60000</Оклад>

                                                               </Record>

                                               </Records>

                               </InformationRegisterRecordSet.КадровыеПеремещения>

                </v8msg:Body>

</v8msg:Message>

 

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

            Открываем конфигурацию филиала в конфигураторе, создаём план обмена. Переносим в модуль объекта процедуры «ПрочитатьСообщениеСИзменениями()» и «ЗаписатьСообщениеСИзменениями()».

            Далее создаём форму узла.

Рис. Форма узла плана обмена «ОбменКадровыхПеремещений» в конфигураторе филиала

 

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

 

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

&НаСервере

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

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

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

            КонецЕсли;

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

 

            Потом переходим к созданию формы списка плана обмена.

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

 

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

 

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

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

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

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

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

            "ВЫБРАТЬ

            |          КадровыеПеремещенияИзменения.Регистратор

            |ИЗ

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

           

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

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

            НЗ = РегистрыСведений.КадровыеПеремещения.СоздатьНаборЗаписей();

           

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

                        НЗ.Отбор.Регистратор.Установить(Выборка.Регистратор);

                        НЗ.Прочитать();

                       

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

            КонецЦикла;

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

 

&НаКлиенте

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

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

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

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

 

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

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

            Возврат Узел = ПланыОбмена.ОбменКадровыхПеремещений.ЭтотУзел();

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

 

&НаКлиенте

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

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

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

            Иначе

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

            КонецЕсли;

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

 

            Создаем обработку «ОбменДаннымиКадровыхПеремещений». Создаем форму обработки и размещаем на ней кнопку.

Рис. Форма обработки «ОбменДаннымиКадровыхПеремещений»

 

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

 

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

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

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

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

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

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

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

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

                                  

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

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

                        КонецЕсли;

            КонецЦикла;

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

 

&НаКлиенте

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

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

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

 

            Протестируем в режиме отладки изменения, сделанные в конфигурации филиала.

            Настроим список узлов плана обмена.

Рис. План обмена «Обмен кадровых перемещений», настройка списка узлов

 

            Выделив узел «ЦБ», регистрируем изменения.

            Затем открываем обработку и выполняем обмен.

Рис. Обработка «Обмен данными кадровых перемещений»

 

            Повысим должность Гальцовой ГА до Генерального директора в центральной базе и выполним обмен.

 

Рис. Регистр сведений «КадровыеПеремещения» в центральной базе (сверху) и базе филиала (снизу)

 

            Желательно вместе с записями регистра еще переносить и все остальное, а именно: документ-регистратор «ПриемНаРаботу», справочник «Сотрудники», справочник «Должности».