Вход | Регистрация


1С:Предприятие ::

Метки:Обмен данными и УРБД

УРБД на v8 за четыре шага.

Я
   Asmody
 
10.08.04 - 19:10
Волшебник попросил меня опубликовать это здесь. Ну вот:
--------------------------------------------------------
сразу замечу, что все ниже следующее относится к релизу платформы 8.0.7.36 и выше.

Шаг 1. Создание плана обмена.
Создаем в конфигурации план обмена. Называем его, например "РаспределеннаяБаза". Обязательно в свойствах плана обмена ставим галку "Распределенная база".
На закладке "Прочее" по кнопке "Состав" определяем, какие объекты будут включаться в обмен. По умолчанию можно включить все объекты ("Действия"-"Включить все"). Важным моментом является параметр "Авторегистрация". В общем случае ее нужно разрешить для всех объектов. Замечание: при добавлении новых объектов в конфигурацию, они не включаются в план обмена. Т.е. после добавления объекта его необходимо добавить в состав плана обмена.
Если Вы хотите, чтобы некоторые объекты не участвовали в обмене, просто исключаете их из состава плана обмена. Но тогда контроль ссылочной целостности остается целиком на Вашей совести. (Если, к примеру, некий документ не включен в план обмена, а регистр, по которому он делает движения включен, то в базе-приемнике вполне реально получить движения по регистру без документа-регистратора, что согласитесь, не есть хорошо)
В принципе, этих действий достаточно, чтобы РБД заработала в "ручном" режиме. Для этого запускаем Предприятие, открываем наш план обмена через меню "Операции". В плане обмена всегда присутствует узел "с точкой". Это описание текущего узла. Его нужно открыть и заполнить. В нашем случае будут доступны поля "Код" и "Наименование". Присвоим нашему узлу код "AA" и назовем "Центральная".
Добавим в план обмена один узел. Присвоим ему код "ВВ" и назовем "Периферийная".
Теперь мы можем создать образ периферийной базы. Делается это нажатием кнопки "Создать начальный образ". В списке узлов должна быть выбрана периферийная база. Образ базы создается в виде готовой ИБ в каталоге или на сервере 1С:Предприятия. (в отличие от 7.7, где образ ИБ создавался как файл выгрузки). Далее созданную базу можно перенести в нужное место просто скопировав файлик 1CV8.1CD (для файлового варианта), либо через Конфигуратор через выгрузку-загрузку данных.
Если Вы откроете план обмена в периферийной ИБ, то Вы увидите, что узлом "с точкой", т.е. текущим узлом стал узел "Периферийная", а иконка у узла "Центральная" стала красного цвета, т.е. узел "Центральная" является главным узлом по отношению к текущему.
Обмен в "ручном" режиме можно производить при помощи кнопок "Записать изменения" и "Прочитать изменения". В первом случае будет предложено выбрать файл, куда изменения будут записаны, во втором - файл, откуда изменения будут считаны. Обмен ведется в формате xml. Изменения записываются для выбранного узла.
Далее мы займемся автоматизацией процесса обмена.
(продолжение следует)
 
  Рекламное место пустует
   Asmody
 
1 - 10.08.04 - 19:11
Шаг 2. Итак мы создали план обмена, создали периферийную ИБ и даже научились переносить данные между базами. Теперь наша задача научить базы обмениваться по электронной почте.
Добавляем в план обмена два реквизита: ЭлектронныйАдрес типа строка и ВыполнятьОбмен типа булево. В реквизите ЭлектронныйАдрес будем хранить email узла, т.е. тот адрес, на который будем посылать сообщения обмена. Реквизит ВыполнятьОбмен нужен чтобы быстро отключить автоматическую посылку-отправку сообщений.
Для работы с эл.почтой сделаем универсальной, т.е. сделаем возможным использование как MAPI (отправка-получение через MS Outlook), так и прямое обращение к SMTP/POP3 серверам.
Добавим несколько констант:
ИспользоватьОбменПоSMTP       -  Булево
АдресСервераSMTPОбмена        -  Строка(50)
ПортСервераSMTPОбмена         -  Число(4,0)
ПользовательСервераSMTPОбмена - Строка(10)
ПарольПользователяSMTPОбмена  - Строка(10)
АдресСервераPOP3Обмена        -  Строка(50)
ПортСервераPOP3Обмена         -  Число(4,0)
ПользовательСервераPOP3Обмена - Строка(10)
ПарольПользователяPOP3Обмена  - Строка(10)
ВремяОжиданияСервера          - Число(3,0)
ВыводитьСообщенияОбмена          - Булево

где-нибудь в общей форме обеспечиваем редактирование значений этих констант.

Добавим общий модуль, назовем его рбРаспределеннаяБаза
в нем пишем:

Процедура рбОтправитьСообщенияОбмена() Экспорт
    ИспользоватьSMTP=Константы.ИспользоватьОбменПоSMTP.Получить();
    
    Если ИспользоватьSMTP Тогда
        ПочтовыйПрофиль=Новый ИнтернетПочтовыйПрофиль;
        ПочтовыйПрофиль.АдресСервераSMTP=Константы.АдресСервераSMTPОбмена.Получить();
        ПочтовыйПрофиль.ПортSMTP=Константы.ПортСервераSMTPОбмена.Получить();
        ПочтовыйПрофиль.ПользовательSMTP=Константы.ПользовательСервераSMTPОбмена.Получить();
        ПочтовыйПрофиль.ПарольSMTP=Константы.ПарольПользователяSMTPОбмена.Получить();
        ПочтовыйПрофиль.ВремяОжидания=Константы.ВремяОжиданияСервера.Получить();
        
        Почта=Новый ИнтернетПочта();
        Попытка
            Почта.Подключиться(ПочтовыйПрофиль);
        Исключение
            Сообщить("ОБМЕН: Ошибка при подключении к почтовому профилю! Обмен не выполнен! "+ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
            Возврат;
        КонецПопытки;
    Иначе    
        Почта=Новый Почта();
        Попытка
            Почта.Подключиться();
        Исключение
            Сообщить("ОБМЕН: Ошибка при подключении к почтовому профилю пользователя! Обмен не выполнен! "+ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
            Возврат;
        КонецПопытки;
    КонецЕсли;
    
    ВыборкаУзлов=ПланыОбмена.РаспределеннаяБаза.Выбрать();
    Пока ВыборкаУзлов.Следующий() Цикл
        Если Не ВыборкаУзлов.ВыполнятьОбмен Тогда
            Продолжить;
        КонецЕсли;
        Если ВыборкаУзлов.Ссылка <> ПланыОбмена.РаспределеннаяБаза.ЭтотУзел() Тогда
            ЭлектронныйАдрес=СокрЛП(ВыборкаУзлов.ЭлектронныйАдрес);
            Если ЭлектронныйАдрес="" Тогда
                Продолжить;
            КонецЕсли;
            Узел=ВыборкаУзлов.Ссылка;
            ЗаписьXML=Новый ЗаписьXML();
            ИмяФайлаСообщения=КаталогВременныхФайлов()+"Message_"+СокрЛП(ПланыОбмена.РаспределеннаяБаза.ЭтотУзел().Код)+"_"+СокрЛП(Узел.Код)+".xml";
            ЗаписьXML.ОткрытьФайл(ИмяФайлаСообщения);
            ЗаписьСообщения=ПланыОбмена.СоздатьЗаписьСообщения();
            ЗаписьСообщения.НачатьЗапись(ЗаписьXML,Узел);
            ПланыОбмена.ЗаписатьИзменения(ЗаписьСообщения);
            ЗаписьСообщения.ЗакончитьЗапись();
            ЗаписьXML.Закрыть();
            
            Если ИспользоватьSMTP Тогда
                ПочтовоеСообщение=Новый ИнтернетПочтовоеСообщение;
            Иначе
                ПочтовоеСообщение=Новый ПочтовоеСообщение;
            КонецЕсли;
            Файл=Новый Файл(ИмяФайлаСообщения);
            ПочтовоеСообщение.Тема="1С:Обмен "+СокрЛП(ПланыОбмена.РаспределеннаяБаза.ЭтотУзел().Код)+"_"+СокрЛП(Узел.Код);
            Если ИспользоватьSMTP Тогда
                ПочтовоеСообщение.Вложения.Добавить(ИмяФайлаСообщения, Файл.Имя);
            Иначе
                ПочтовоеСообщение.Вложения.Добавить(ИмяФайлаСообщения);
            КонецЕсли;
            ПочтовоеСообщение.Получатели.Добавить(ЭлектронныйАдрес);
            
            Если ИспользоватьSMTP Тогда
                Почта.Послать(ПочтовоеСообщение);
            Иначе
                Почта.Послать(ПочтовоеСообщение, Ложь);
            КонецЕсли;
            Если Константы.ВыводитьСообщенияОбмена.Получить() Тогда
                Сообщить("ОБМЕН: Сообщение обмена для узла "+Узел.Наименование+" отправлено!",СтатусСообщения.Информация);
            КонецЕсли;
            УдалитьФайлы(ИмяФайлаСообщения);
        КонецЕсли;
    КонецЦикла;
    
    Почта.Отключиться();
    
КонецПроцедуры

комментарий к процедуре: сначала создаем объект Почта, который в зависимости от настроек будет    типа ИнтернетПочта если используется прямое обращение к серверам, либо Почта если используется MAPI. Для объекта типа ИнтернетПочта создаем и заполняем почтовый профиль. Далее выбираем все узлы из плана обмена, за исключением текущего, у которых установлен реквизит ВыполнятьОбмен. С помощью объектов ЗаписьXML и ЗаписьСообщения выполняем запись изменений для выбранного узла в xml-файл. Затем создаем новое письмо, прикрепляем к нему полученный xml-файл и отправляем по адресу, указанному в реквизите ЭлектронныйАдрес узла.
Рекомендую в интерфейс добавить дополнительную панель, на одну из кнопок которой повесить вызов этой процедуры. Теперь осталось запустить Предприятие, настроить электронный адрес периферийной ИБ, поставить галку "Выполнять обмен", нажать на кнопку процедуры на панели и бежать получать почту для указанного эл. адреса. Должно придти письмо с темой "1С:Обмен AA_BB" и вложеным файлом "Message_AA_BB.xml".
Итак, половина дела сделана: мы научили 8ку отправлять сообщения обмена РБД по электронной почте.
   Asmody
 
2 - 10.08.04 - 19:11
Шаг 3. Теперь займемся обратной процедурой: получение обновлений по электронной почте и запись их в ИБ.
в параметры сеанса добавим реквизит ИдетОбменРаспределеннойБазы типа Булево. Ниже я объясню его назначение.

Добавим в модуль рбРаспределеннаяБаза такую процедуру:

Процедура рбПолучитьСообщенияОбмена() Экспорт
    ИспользоватьSMTP=Константы.ИспользоватьОбменПоSMTP.Получить();

    Если ИспользоватьSMTP Тогда
        ПочтовыйПрофиль=Новый ИнтернетПочтовыйПрофиль;
        ПочтовыйПрофиль.АдресСервераPOP3=Константы.АдресСервераPOP3Обмена.Получить();
        ПочтовыйПрофиль.ПортPOP3=Константы.ПортСервераPOP3Обмена.Получить();
        ПочтовыйПрофиль.Пользователь=Константы.ПользовательСервераPOP3Обмена.Получить();
        ПочтовыйПрофиль.Пароль=Константы.ПарольПользователяPOP3Обмена.Получить();
        ПочтовыйПрофиль.ВремяОжидания=Константы.ВремяОжиданияСервера.Получить();
        
        Почта=Новый ИнтернетПочта();
        Попытка
            Почта.Подключиться(ПочтовыйПрофиль);
        Исключение
            Сообщить("ОБМЕН: Ошибка при подключении к почтовому профилю! Обмен не выполнен!",СтатусСообщения.ОченьВажное);
            Возврат;
        КонецПопытки;
    Иначе    
        Почта=Новый Почта();
        Попытка
            Почта.Подключиться();
        Исключение
            Сообщить("ОБМЕН: Ошибка при подключении к почтовому профилю пользователя! Обмен не выполнен!",СтатусСообщения.ОченьВажное);
            Возврат;
        КонецПопытки;
    КонецЕсли;
    
    МассивСообщений=Новый Массив;
    Если ИспользоватьSMTP Тогда
        ВсеСообщения=Почта.Выбрать(Ложь);
    Иначе
        ВсеСообщения=Почта.Выбрать(Ложь, Ложь);
    КонецЕсли;
    Для Каждого Сообщение из ВсеСообщения Цикл
        
        Если Лев(Сообщение.Тема, 8)<>"1С:Обмен" Тогда
            Продолжить;
        КонецЕсли;
        Попытка
            МассивСообщений.Добавить(Сообщение);
            Вложение=Сообщение.Вложения[0];
            ИмяФайлаСообщения=КаталогВременныхФайлов()+Вложение.Name;
            ДанныеОбмена=Вложение.Данные;
            ДанныеОбмена.Записать(ИмяФайлаСообщения);
            
            ЧтениеXML=Новый ЧтениеXML();
            ЧтениеXML.ОткрытьФайл(ИмяФайлаСообщения);
            ЧтениеСообщения=ПланыОбмена.СоздатьЧтениеСообщения();
            ЧтениеСообщения.НачатьЧтение(ЧтениеXML);
            ПараметрыСеанса.ИдетОбменРаспределеннойБазы=Истина;
            ПланыОбмена.ПрочитатьИзменения(ЧтениеСообщения);
            ЧтениеСообщения.ЗакончитьЧтение();
            ЧтениеXML.Закрыть();
            Если Константы.ВыводитьСообщенияОбмена.Получить() Тогда
                Сообщить("ОБМЕН: Данные обмена приняты",СтатусСообщения.Информация);
            КонецЕсли;
        Исключение
            Сообщить("ОБМЕН: Ошибка при получении данных обмена: "+ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
        КонецПопытки;
        ПараметрыСеанса.ИдетОбменРаспределеннойБазы=Ложь;
        
        Попытка
            УдалитьФайлы(ИмяФайлаСообщения);
        Исключение
        КонецПопытки;
        
    КонецЦикла;
    
    Если ИспользоватьSMTP Тогда
        Почта.УдалитьСообщения(МассивСообщений);
    КонецЕсли;
    Почта.Отключиться();
    
КонецПроцедуры

коментарий к процедуре: так же, как в процедуре рбОтправитьСообщенияОбмена(), сначала создаем объект Почта. Отбираем среди всех писем те, которые имеют тему "1С:Обмен". (Маленькое, но важное замечание: считаем, что все полученные письма с темой "1С:Обмен" прдназначены именно для текущего узла. Т.е. что у разныз узлов в плане обмена РАЗНЫЕ электронные адреса.) Вложение письма сохраняем на диске. Аккуратную проверку вложения оставим пока "за кадром." С помощью объектов ЧтениеXML и ЧтениеСообщения читаем данные обновления из сохраненного файла. Перед записью обновлений в ИБ устанавливаем параметр сеанса ИдетОбменРаспределеннойБазы в Истина. Затем читаем изменения в ИБ: ПланыОбмена.ПрочитатьИзменения(ЧтениеСообщения). Попутно сохраняем сообщения в массиве, чтобы потом их все сразу удалить. После того, как чтение данных обмена закончено, возвращаем параметру сеанса ИдетОбменРаспределеннойБазы значение Ложь.
Теперь про то, для чего нужен параметр сеанса ИдетОбменРаспределеннойБазы. Дело в том, что при чтении данных методом ПланыОбмена.ПрочитатьИзменения() происходит вызов процедур-обработчиков события ПередЗаписью() изменяемых/добавляемых объектов. И если при записи какого-либо объекта в процедуре обработчике параметр Отказ будет установлен в значение Истина, то при выполнении ПланыОбмена.ПрочитатьИзменения() возникнет исключение, и, соответственно, обмен выполнен не будет. Значение параметра сеанса ИдетОбменРаспределеннойБазы может быть проанализированно в процедурах-обработчиках, дабы избежать подобной ситуации.
Теперь в интерфейсе на нашей панели добавляем еще одну кнопку, на которую вешаем вызов этой процедуры. Запускаем Предприятие и наслаждемся.
Почти все сделано, осталось малость: заставить наши процедуры выполняться в автоматическом режиме.
(продолжение следует)
   Asmody
 
3 - 10.08.04 - 19:11
Шаг 4.
Итак, мы почти вплотную приблизились к цели нашего повествования.
Остался всего один шаг: запустить выполнение процедур обмена в автоматическом режиме.
Приступим.

Добавим константу ИнтервалАвтообменаРаспределеннойБазы типа Число(5,0).
В настройки пользователя добавим параметр ВыполнятьОбменРаспределенныхБаз. Для УТ это делается так:
В план видов характеристик "НастройкиПользователей" добавим предопределенную характеристику ВыполнятьОбменРаспределенныхБаз типа Булево.
В форме элемента справочника "Пользователи" настраиваем изменение этого параметра (как это сделать можно посмотреть в модуле формы, по аналогии с остальными параметрами).
В модуль рбРаспределеннаяБаза добавляем процедуру:

Процедура рбВыполнитьОбмен(прПользователь) Экспорт
    Если нпПолучитьЗначениеПоУмолчанию(прПользователь, "ВыполнятьОбменРаспределенныхБаз") Тогда
        рбПолучитьСообщенияОбмена();
        рбОтправитьСообщенияОбмена();
    КонецЕсли;
КонецПроцедуры

в модуль приложения:

Процедура ПроверитьПодключениеАвтообмена() Экспорт
    Если нпПолучитьЗначениеПоУмолчанию(глТекущийПользователь,"ВыполнятьОбменРаспределенныхБаз")
         и Константы.ИнтервалАвтообменаРаспределеннойБазы.Получить() > 0 Тогда
         ПодключитьОбработчикОжидания("ВыполнитьАвтообмен",Константы.ИнтервалАвтообменаРаспределеннойБазы.Получить());
     Иначе
         ОтключитьОбработчикОжидания("ВыполнитьАвтообмен");
    КонецЕсли;
КонецПроцедуры

Процедура ВыполнитьАвтообмен() Экспорт
    рбВыполнитьОбмен(глТекущийПользователь);
    
    ОтключитьОбработчикОжидания("ВыполнитьАвтообмен");
    Если нпПолучитьЗначениеПоУмолчанию(глТекущийПользователь,"ВыполнятьОбменРаспределенныхБаз")
         и Константы.ИнтервалАвтообменаРаспределеннойБазы.Получить() > 0 Тогда
         ПодключитьОбработчикОжидания("ВыполнитьАвтообмен",Константы.ИнтервалАвтообменаРаспределеннойБазы.Получить());
    КонецЕсли;
КонецПроцедуры

Процедура ОтключитьАвтообмен() Экспорт
    ОтключитьОбработчикОжидания("ВыполнитьАвтообмен");
КонецПроцедуры

в процедуру ПриНачалеРаботыСистемы() модуля приложения добавим такие строки:
(после подключения торгового оборудования)
...
    ПараметрыСеанса.ИдетОбменРаспределеннойБазы=Ложь;
    ПроверитьПодключениеАвтообмена();
...

Добавим на нашу панель еще пару кнопок для управления процессом: на одну вешаем процедуру ПроверитьПодключениеАвтообмена(), на другую - ОтключитьАвтообмен()
Запускаем предприятие, настраиваем свойства пользователя и интервал автообмена и все!
Теперь при заходе в базу под этим-самым-настроенным пользователем будет запускаться обработчик ожидания ВыполнитьАвтообмен(). Естественно, в периферийной базе тоже нужно настроить пользователя для обмена.
   Asmody
 
4 - 10.08.04 - 19:12
Еще одно маленькое, но важное замечание:
Во всей, созданной нами прелести, присутствует одна неприятность: изменение конфигурации. При получении периферийной базой сообщения, в котором будут содержаться изменения конфигурации, оно будет принято, но возникнет исключительная ситуация. При этом измененная конфигурация будет загружена. Для обновления конфигурации БД необходимо выгнать всех пользователей, зайти в конфигуратор и выполнить обновление конфигурации БД (перед этим неплохо сделать выгрузку данных). К сожалению, это неизбежное зло. Можно немного облегчить себе жизнь, написав коротенький bat-файл примерно такого содержания:

1cv8.exe CONFIG /F<путь к ИБ> /N<Пользователь> /P<Пароль> /UpdateIBCfg
   Asmody
 
5 - 10.08.04 - 19:12
И еще одно замечание:
К сожалению, xml-файлы не отличаются компактностью, но, к счастью, прекрасно сжимаются. Можно в процедуры отправки и получения сообщений добавить упаковку-распаковку файлов. Делать это можно либо внешним архиватором, либо используя ВК, например Wheel.AddIn (http://1c.proclub.ru/modules/mydownloads/personal.php?cid=81&lid=2714). Реализацию сего оставляю вам для самостоятельного упражнения.



Список тем форума
Рекламное место пустует   Рекламное место пустует
Независимо от того, куда вы едете — это в гору и против ветра!
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Ветка сдана в архив. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует