В начало

План обмена для документа «ЕжиИУжи»

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

Рис. Документ «ЕжиИУжи» в дереве метаданных

 

            Создаем новый план обмена «ОбменЕжамиИУжами» в главной базе. На закладке «Основные» свойств плана обмена нажимаем кнопку «Состав» и добавляем в состав обмена документ «ЕжиИУжи».

Рис. План обмена «ОбменЕжамиИУжами»

 

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

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

 

            Потом в плане обмена «ОбменЕжамиИУжами» необходимо создать две формы: ФормуУзла и ФормуСписка. Создаем их.

Рис. Форма узла плана обмена

 

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

 

Листинг. Модуль формы узла плана обмена «ОбменУжамиИЕжами»

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

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

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

            КонецЕсли;

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

 

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

            Кроме того в модуле формы списка нужно описать доступность кнопки в событии  «ПриАктивацииСтроки».

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

Рис. Первоначальный  вид плана обмена в пользовательском режиме

 

Рис. Добавление узлов ЦБ и ФЛ

 

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

 

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

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

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

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

 

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

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

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

 

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

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

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

            Иначе

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

            КонецЕсли;

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

 

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

Рис. Форма обработки «ОбменЕжамиИУжами»

 

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

 

Листинг. Обработка «ОбменЕжамиИУжами»

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

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

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

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

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

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

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

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

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

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

                        КонецЕсли;

            КонецЦикла;

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

 

            Затем возвращаемся в модуль плана обмена для создания процедур по чтению и записи сообщений с изменениями.

 

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

 

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

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

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

            ИмяФайла = Каталог + ?(Прав(Каталог, 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С: Предприятие», открываем план обмена «ОбменЕжамиИУжами», выделяем узел «ФЛ», нажимаем кнопку «Зарегистрировать изменения», после чего запускаем обработку «Обмен ежами и ужами» и жмем кнопку «Выполнить обмен».  Если все сделано правильно, без ошибок, то в каталоге временных файлов «C:\Users\Guest\AppData\Local\Temp» должен появиться 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>

                        <DocumentObject.ЕжиИУжи>

                                   <Ref>3dd830f2-a7a3-11ec-8fd8-001eec3547a4</Ref>

                                   <DeletionMark>false</DeletionMark>

                                   <Date>2022-03-19T19:40:11</Date>

                                   <Number>000000001</Number>

                                   <Posted>true</Posted>

                                   <Ежи>

 

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

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

 

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

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

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

 

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

&НаСервере

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

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

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

            КонецЕсли;

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

 

            Форма списка плана обмена тоже будет немного отличаться.

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

           

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

 

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

 

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

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

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

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

 

&НаКлиенте

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

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

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

 

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

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

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

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

 

&НаКлиенте

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

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

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

            Иначе

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

            КонецЕсли;

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

 

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

Рис. Формы списка и узла плана обмена «ОбменЕжамиИУжами»

 

            Обработка «ОбменЕжамиИУжами» также будет отличаться только наличием управляемой формы вместо обычной.

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

 

            Содержимое модуля формы обработке приведено далее.

 

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

 

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

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

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

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

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

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

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

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

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

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

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

                        КонецЕсли;

            КонецЦикла;

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

 

&НаКлиенте

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

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

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

 

            Далее запускаемся в режиме отладки и проверяем работу. Первым делом переходим в план обмена «ОбменЕжамиИУжами» и регистрируем изменения для узла центральной базы «ЦБ».

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

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

            Итак, если все правильно, то данные в документе «ЕжиИУжи» должны соответствовать.

 

Рис. Форма списка документа «Ежи и ужи»:

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

 

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