В начало

План обмена документа «МухиИКотлеты»

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

Рис. Форма списка документа «Мухи и котлеты»:

в главной базе (слева), в филиале (права)

 

            Итак, переходим в конфигуратор главной базы и создаём новый план обмена, называем его «ОбменМухИКотлет». Настраиваем план обмена. На закладке «Основные» имеется кнопка «Состав», нажав которую можно/нужно установить состав плана обмена, а именно отыскать в списке документов необходимый для обмена документ и поставить галочку/флажок. Заходим, находим, ставим.

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

 

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

Рис. Вкладка «Данные» свойств плана обмена «ОбменМухИКотлет»

 

            В модуле объекта «ОбменМухИКотлет» заранее размещаем пару процедур, при помощи которых будет происходить процесс чтения и записи файлов с сообщениями, в которых будут данные обмена. Листинг модуля объекта идет ниже.

 

Листинг. Модуль объекта «ОбменМухИКотлет» с процедурами

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

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

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

            ИмяФайла = Каталог + ?(Прав(Каталог, 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.Закрыть();

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

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

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

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

 

            Затем переходим на закладку «Формы» свойств плана обмена «ОбменМухИКотлет» и создаем формы: форму узла и форму списка, как показано далее.

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

 

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

Рис. Форма узла плана обмена «ОбменМухИКотлет» в конфигураторе

 

            Далее приведен листинг формы узла плана обмена «ОбменМухИКотлет» с обработчиком/процедурой «ПередОткрытием».

 

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

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

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

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

            КонецЕсли;

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

 

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

Потом для данной кнопки нужно написать обработчик нажатия, а для самого списка узлов обработчик «ПриАктивизацииСтроки».  Пишем.  Код приведен далее.

 

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

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

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

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

 

////////////////////////////////////////////////

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

            Возврат Узел = ПланыОбмена.ОбменМухИКотлет.ЭтотУзел();

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

 

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

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

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

            Иначе

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

            КонецЕсли;

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

 

            И наконец, создаём обработку, которая будет запускать экспортные процедуры из модуля плана обмена «ОбменМухИКотлет».  Назовём, извините за тавтологию, данную обработку «ОбменМухИКотлет». В данной обработке нужно будет сделать форму, на которой для кнопки  скажем «Выполнить обмен» создать обработчик.

Рис. Форма обработки «ОбменМухИКотлет» в кофигураторе

 

            Далее приведён листинг модуля формы обработки «ОбменМухИКотлет». В данном листинге всего одна процедура, это обработчик нажатия кнопки «Выполнить обмен».

 

Листинг. Модуль формы «ОбменМухИКотлет»

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

            ВыборкаУзлов = ПланыОбмена.ОбменМухИКотлет.Выбрать();

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

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

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

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

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

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

                        КонецЕсли;

            КонецЦикла;

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

 

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

Рис. План обмена «ОбменМухИКотлет» в центральной базе

           

            Зарегистрируем изменения, предварительно выделив узел «ФЛ» и нажав на, ставшую доступной кнопку «Зарегистрировать изменения».

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

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

            В данной конфигурации также создаём план обмена «ОбменМухИКотлет». Чистый копипаст через буфер обмена не получится, поскольку конфигурация филиала использует управляемые формы и их придется создавать.

            Создаем форму узла.

Рис. Форма узла плана обмена «ОбменМухИКотлет» в конфигураторе

 

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

 

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

&НаСервере

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

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

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

            КонецЕсли;

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

 

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

Рис. Форма списка плана обмена «ОбменМухИКотлет»

 

            Листинг с процедурами, расположенными в модуле формы списка плана обмена «ОбменМухИКотлет» привожу ниже.

 

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

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

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

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

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

 

&НаКлиенте

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

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

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

 

/////////////////////////////////////////////////////////////////////

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

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

            Возврат Узел = ПланыОбмена.ОбменМухИКотлет.ЭтотУзел();

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

 

&НаКлиенте

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

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

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

            Иначе

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

            КонецЕсли;

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

 

            Обработка «ОбменМухИКотлет» также будет немного отличаться от той, что расположена в конфигурации центральной базы. Нужно будет создать управляемую форму для обработки вместо обычной. А также разбить обработчик на две части.

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

Рис. Форма обработки «ОбменМухИКотлет», с расположенной на ней кнопкой

 

            Ниже показан обработчик, расположенный в модуле формы обработки «ОбменМухИКотлет».

 

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

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

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

            ВыборкаУзлов = ПланыОбмена.ОбменМухИКотлет.Выбрать();

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

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

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

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

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

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

                        КонецЕсли;

            КонецЦикла;

 

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

 

&НаКлиенте

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

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

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

 

            Протестируем изменения в конфигурации. Сначала настроем план обмена «ОбменМухИКотлет». В плане обмена переименуем Код и Наименование для предопределенного узла и сделаем его филиалом, обозначив его как «ФЛ». Также создадим еще один узел – «ЦБ».

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

 

            Для узла центральной базы «ЦБ» проставим галочку на реквизите «ЭтоГлавныйУзел».

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

 

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

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

Рис. Изменения для тестирования: «ЦБ» слева, «ФЛ» справа

Рис. Результат после выполненных двух обменов

 

            В результате изменения в документе «МухиИКотлеты» выравниваются.