В начало

Обмен документа «ПокупкаАкций» с причиндалами

 

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

 

Рис. Документ «ПокупкаАкций» и независимый справочник «СписокАкций»

 

            Начнем с настройки конфигурации центральной базы «ЦБ». Переходим в раздел «ПланыОбмена» и создаем новый план обмена «ОбменПокупкамиАкций». Сразу переходим в раздел «Основные» свойств плана обмена и изменяем состав.

Рис. Свойства плана обмена «ОбменПокупкамиАкций», изменение состава

 

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

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

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

 

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

Рис. Форма списка плана обмена «ОбменПокупкамиАкций»

 

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

 

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

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

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

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

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

           

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

            Сообщение.Текст = "-Сообщение записано в файл: " + ИмяФайла + Символы.ПС +

                                             "-------- Конец выгрузки ------------";

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

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

 

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

 

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

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

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

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

            КонецЕсли;

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

 

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

 

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

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

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

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

                        "ВЫБРАТЬ

                        |          ПокупкаАкцийИзменения.Ссылка

                        |ИЗ

                        |          Документ.ПокупкаАкций.Изменения КАК ПокупкаАкцийИзменения";

           

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

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

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

           

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

                        //Регистрируем документ "ПокупкаАкций"

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

                        //Перебор списка акций

                        Для Каждого Элем Из Выборка.Ссылка.СписокАкций Цикл

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

                        КонецЦикла; 

            КонецЦикла;

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

 

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

            //Кнопка недоступна для предопределенного узла

            Если ЭлементыФормы.ПланОбменаСписок.ТекущаяСтрока =

                        ПланыОбмена.ОбменПокупкамиАкций.ЭтотУзел() Тогда

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

            Иначе

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

            КонецЕсли;

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

 

            Далее создаем обработку «ОбменДаннымиПокупокАкций». Добавляем форму обработки. Изменяем текст на кнопке «Выполнить».

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

 

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

 

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

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

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

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

                        // Произвести обмен данными со всеми узлами,

                        //кроме текущего

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

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

                                  

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

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

                        КонецЕсли;

            КонецЦикла;

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

 

            Протестируем выполненные изменения. Для этого загружаемся в пользовательском режиме. Переходим к настройке узлов плана обмена.

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

 

            Регистрируем изменения. После чего открываем обработку «ОбменДаннымиПокупокАкций» и выполняем обмен данными.

Рис. Выполнение обмена обработкой

 

            Выводится служебное сообщение, проверяем этот файл-сообщение.

Рис. Содержимое файла-сообщения

 

            Файл-сообщение содержит информацию/данные о документе «ПокупкаАкций» и независимом справочнике «СписокАкций». Хорошо.

            Переходим ко второй части марлезонского балета, а именно настройке конфигурации филиала. Создаем в конфигурации филиала аналогичный план обмена с именем «ОбменПокупкамиАкций».

            Размещаем в модуле объекта плана обмена пресловутую парочку процедур. Они точно такие же, что и в центральной базе «ЦБ».

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

 

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

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

 

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

 

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

&НаСервере

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

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

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

            КонецЕсли;

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

 

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

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

 

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

 

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

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

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

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

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

            "ВЫБРАТЬ

            |          ПокупкаАкцийИзменения.Ссылка

            |ИЗ

            |          Документ.ПокупкаАкций.Изменения КАК ПокупкаАкцийИзменения";

           

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

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

           

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

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

                        Для Каждого Элем Из Выборка.Ссылка.СписокАкций Цикл

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

                        КонецЦикла;

            КонецЦикла;

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

 

&НаКлиенте

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

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

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

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

 

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

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

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

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

 

&НаКлиенте

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

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

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

            Иначе

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

            КонецЕсли;

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

 

 

            Далее создаем обработку «ОбменДаннымиПокупокАкций». Создаем форму обработки, добавляем команду «ВыполнитьОбмен».

Рис. Форма обработки «Обмен данными покупок акций»

 

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

 

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

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

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

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

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

                        // Произвести обмен данными со всеми узлами,

                        //кроме текущего (ЭтотУзел)

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

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

                                  

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

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

                        КонецЕсли;

            КонецЦикла;

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

 

&НаКлиенте

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

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

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

 

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

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

 

            Зарегистрируем изменения для центральной базы и откроем обработку для обмена. Выполним обмен.

Выскакивает ошибка.

Рис. Ошибка преобразования данных

 

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

Рис. Выполнение обмена в базе филиала

 

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

Рис. Документ «Покупка акций» и справочник «Список акций» в базе филиала

 

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