В начало

Обмен данными справочника Сотрудники

           

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

            Далее показана структура справочника «Сотрудники» в конфигураторе на дереве объектов. Справочник помимо основных/стандартных реквизитов имеет реквизиты: Пол (с типом перечисление), ДатаРождения (с типом дата) и Должность (ссылочного типа из справочника Должности).

Рис. Структура справочника «Сотрудники»

 

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

Рис. План обмена «ОбменСотрудников» в дереве метаданных

 

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

 

Листинг. Модуль объекта плана обмена «ОбменСотрудников» в главной/центральной базе

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

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

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

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

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

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

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

                        Возврат;

            КонецЕсли;

            // *** Чтение документов 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.Закрыть();

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

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

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

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

 

            Далее переходим в раздел «Формы» и создаем две формы: форму узла и форму списка. В модуле ФормыУзла размещаем процедуру для доступности реквизита «Главный».

 

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

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

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

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

            КонецЕсли;

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

 

            Затем добавляем кнопку на форму списка и код в модуль формы списка плана обмена «ОбменСотрудников».

Рис. Внешний вид формы списка плана обмена «ОбменСотрудников»,

центральная база, обычная форма

 

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

Процедура ДействияФормыЗарегистрироватьИзменения(Кнопка)

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

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

 

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

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

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

 

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

            //На "Элемент" подсказка через точку не работает!

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

                        //Если кнопка на панели "Действия"

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

            Иначе

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

            КонецЕсли;

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

 

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

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

 

            В модуле формы обработки размещаем код, обрабатывающий нажатие кнопки «ВыполнитьОбмен».

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

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

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

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

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

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

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

                                   // Получить сообщение.

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

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

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

                        КонецЕсли;

            КонецЦикла;

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

 

            Итак, в центральной базе, в конфигураторе было все подготовлено. Можно запустить режим «1С: Предприятие» и настроить план обмена. Во первых нужно настроить предопределенный узел (тот, что с зеленой точкой в правом нижнем углу), а именно вписать Код и Наименование. Во вторых нужно создать еще один узел для базы «Филиал», для которого также вписать Код и Наименование. Можно также нажать кнопку «Зарегистрировать изменения».

Рис. План обмена «ОбменСотрудников» в режиме «1С: Предприятие»

 

            После этого запустить обработку «Обмен данными сотрудников» и нажать кнопку «ВыполнитьОбмен».

Рис. Обработка «Обмен данными сотрудников»

 

            При этом в каталоге временных файлов («C:\Users\Guest\AppData\Local\Temp») будет создан файл типа «Сообщение_ОбменСотрудников_ЦБ-ФЛ.xml», который содержит данные для обмена между конфигурациями центральной базы и базы филиала. Данный файл можно просмотреть в любом браузере или текстовом редакторе.

Рис. Фрагмент файла «Сообщение_ОбменСотрудников_ЦБ-ФЛ.xml»

 

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

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

Рис. Процедуры в модуле объекта плана обмена в базе филиала

 

            Затем переходим к настройке формы узла плана обмена базы филиала. Форма показана далее.

Рис. Форма узла плана обмена «ОбменСотрудников»

 

            Потом добавляем в модуль ФормыУзла плана обмена процедуру «ПриСозданииНаСервере», данную процедуру предваряет соответствующая директива «&НаСервере».

 

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

&НаСервере

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

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

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

            КонецЕсли;

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

 

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

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

 

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

 

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

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

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

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

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

 

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

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

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

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

 

&НаКлиенте

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

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

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

 

&НаКлиенте

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

            //Через точку подсказка на "Элемент" НЕ работает!

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

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

            Иначе

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

            КонецЕсли;

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

 

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

Рис. Форма обработки «ОбменДаннымиСотрудников» в базе «Филиал»

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

 

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

&НаКлиенте

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

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

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

 

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

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

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

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

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

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

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

                                   // Получить сообщение.

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

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

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

                        КонецЕсли;

            КонецЦикла;

 

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

 

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

Рис. План обмена «Обмен сотрудников» в базе филиала организации

 

            Затем запускаем обработку «Обмен данными сотрудников», в которой нажимаем кнопку «Выполнить обмен». Будет создан файл формата XML в каталоге временных файлов «C:\Users\Guest\AppData\Local\Temp» с именем «Сообщение_ОбменСотрудников_ФЛ-ЦБ.xml». Одновременно будут прочитан файл «Сообщение_ОбменСотрудников_ЦБ-ФЛ.xml» и внесены изменения в справочник «Сотрудники». Первый файл «…ФЛ-ЦБ.xml» - это данные из филиала в центральную базу, второй, с именем «…ЦБ- ФЛ.xml» содержит данные из центральной базы в базу филиала. Для полноты обмена нужно вернуться в центральную базу и там еще раз в обработке «ОбменДаннымиСотрудников» нажать кнопку «Выполнить обмен».

            Далее открываем справочник «Сотрудники» в двух базах, всячески экспериментируем (удаляем, помечаем, добавляем элементы справочника) и потом сравниваем данные после обмена. Все вроде норм. Ниже приведен устаканенный справочник «Сотрудники».

 

Рис. Справочник «Сотрудники»:

в центральной базе (слева) и базе филиала (справа)

 

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