В начало

Обмен данными регистра «ЗакупочныеЦены»

 

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

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

Рис. Свойства плана обмена, изменение состава обмена

 

            На закладке «Данные» добавляем реквизит «ГлавныйУзел» с типом «Булево».

            Далее на вкладке «Формы» создаем форму узла и форму списка.

Рис. Форма узла плана обмена «ОбменЗакупочнымиЦенами»

 

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

Рис. Форма списка плана обмена «ОбменЗакупочнымиЦенами»

 

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

 

Листинг. Модуль объекта плана обмена «ОбменЗакупочнымиЦенами»

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

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

            Сообщение.Текст = "-------- Выгрузка в узел " + Строка(ЭтотОбъект) + " ------------";

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

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

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

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