1. Создание плана обмена.
2. Выгрузка изменений в XML-файл и отправка по электронной почте
3. Получение обновлений по электронной почте и запись их в ИБ
4. Настройка автоматического обмена
Ключевые слова: распределенная, УРБД, XML, регистрация, узел, узла, авторегистрация, начальный, образ, POP3, SMTP, ПочтовоеСообщение, периферийная, центральная, репликация, обмен
Шаг 1. Создание плана обмена
Создаем в конфигурации план обмена. Называем его, например "РаспределеннаяБаза". Обязательно в
свойствах плана обмена ставим флажок "Распределенная информационная база".
На закладке "Прочее" по кнопке "Состав" определяем, какие объекты будут включаться в обмен. По
умолчанию можно включить все объекты ("Действия"-"Включить все"). Важным моментом является параметр
"Авторегистрация". В общем случае ее нужно разрешить для всех объектов.
Замечание: при добавлении новых объектов в конфигурацию, они не включаются в план обмена. Т.е. после
добавления объекта его необходимо добавить в состав плана обмена.
Если Вы хотите, чтобы некоторые объекты не участвовали в обмене, просто исключаете их из состава
плана обмена. Но тогда контроль ссылочной целостности остается целиком на вашей совести. Если, к
примеру, некий документ не включен в план обмена, а регистр, по которому он делает движения включен,
то в базе-приемнике вполне реально получить движения по регистру без документа-регистратора, что
согласитесь, не есть хорошо.
В принципе, этих действий достаточно, чтобы РБД заработала в "ручном" режиме. Для этого запускаем
Предприятие, открываем наш план обмена через меню "Операции". В плане обмена всегда присутствует
предопределенный узел "с точкой". Это описание текущего узла. Его нужно открыть и заполнить. В нашем
случае будут доступны поля "Код" и "Наименование". Присвоим нашему узлу код "AA" и назовем
"Центральная". Добавим в план обмена один узел. Присвоим ему код "ВВ" и назовем "Периферийная".
Теперь мы можем создать образ периферийной базы. Делается это нажатием кнопки "Создать начальный
образ". В списке узлов должна быть выбрана периферийная база. Образ базы создается в виде готовой ИБ
в каталоге или на сервере 1С:Предприятия. (в отличие от 7.7, где образ ИБ создавался как файл
выгрузки). Далее созданную базу можно перенести в нужное место, просто скопировав файлик 1CV8.1CD
(для файлового варианта), либо через Конфигуратор через выгрузку-загрузку данных.
Если Вы откроете план обмена в периферийной ИБ, то Вы увидите, что узлом "с точкой", т.е. текущим
узлом стал узел "Периферийная", а иконка у узла "Центральная" стала красного цвета, т.е. узел
"Центральная" является главным узлом по отношению к текущему.
Обмен в "ручном" режиме можно производить при помощи кнопок "Записать изменения" и "Прочитать
изменения". В первом случае будет предложено выбрать файл, куда изменения будут записаны, во втором
- файл, откуда изменения будут считаны. Обмен ведется в формате xml. Изменения записываются для
выбранного узла.
Шаг 2. Выгрузка изменений в XML-файл и отправка по электронной почте
Итак мы создали план обмена, создали периферийную ИБ и даже научились переносить данные между
базами. Теперь наша задача научить базы обмениваться по электронной почте.
Добавляем в план обмена два реквизита: ЭлектронныйАдрес типа "строка" и "ВыполнятьОбмен" типа
"булево". В реквизите ЭлектронныйАдрес будем хранить email узла, т.е. тот адрес, на который будем
посылать сообщения обмена. Реквизит ВыполнятьОбмен нужен, чтобы быстро отключить автоматическую
посылку-отправку сообщений.
Процедуру для работы с электронной почтой сделаем универсальной, т.е. сделаем возможным
использование как MAPI (отправка-получение через почтового клиента, например, MS Outlook), так и
прямое обращение к SMTP/POP3 серверам.
Добавим в конфигурацию несколько констант:
Имя :: Тип
ПользовательСервераPOP3Обмена :: Строка(10)
ПарольПользователяPOP3Обмена :: Строка(10)
ВремяОжиданияСервера :: Число(3,0)
ВыводитьСообщенияОбмена :: Булево
ИспользоватьОбменПоSMTP :: Булево
АдресСервераSMTPОбмена :: Строка(50)
ПортСервераSMTPОбмена :: Число(4,0)
ПользовательСервераSMTPОбмена :: Строка(10)
ПарольПользователяSMTPОбмена :: Строка(10)
АдресСервераPOP3Обмена :: Строка(50)
ПортСервераPOP3Обмена :: Число(4,0)
где-нибудь в общей форме обеспечиваем редактирование значений этих констант.
обавим общий модуль, назовем его "рбРаспределеннаяБаза". В нем пишем:
Процедура рбОтправитьСообщенияОбмена() Экспорт
ИспользоватьSMTP = Константы.ИспользоватьОбменПоSMTP.Получить();
//Сначала создаем объект Почта, который в зависимости от настроек будет типа ИнтернетПочта,
//если используется прямое обращение к серверам, либо Почта если используется MAPI.
Если ИспользоватьSMTP Тогда
//Для объекта типа ИнтернетПочта создаем и заполняем почтовый профиль.
ПочтовыйПрофиль = Новый ИнтернетПочтовыйПрофиль;
ПочтовыйПрофиль.АдресСервераSMTP = Константы.АдресСервераSMTPОбмена.Получить();
ПочтовыйПрофиль.ПортSMTP = Константы.ПортСервераSMTPОбмена.Получить();
ПочтовыйПрофиль.ПользовательSMTP = Константы.ПользовательСервераSMTPОбмена.Получить();
ПочтовыйПрофиль.ПарольSMTP =
Константы.ПарольПользователяSMTPОбмена.Получить();
ПочтовыйПрофиль.ВремяОжидания = Константы.ВремяОжиданияСервера.Получить();
Почта = Новый ИнтернетПочта();
Попытка
Почта.Подключиться(ПочтовыйПрофиль);
Исключение
Сообщить("ОБМЕН: Ошибка при подключении к почтовому профилю! Обмен не выполнен! " +
ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
Возврат;
КонецПопытки;
Иначе
Почта = Новый Почта();
Попытка
Почта.Подключиться();
Исключение
Сообщить("ОБМЕН: Ошибка при подключении к почтовому профилю пользователя!
|Обмен не выполнен! " + ОписаниеОшибки(),
СтатусСообщения.ОченьВажное);
Возврат;
КонецПопытки;
КонецЕсли;
//Далее выбираем все узлы из плана обмена, за исключением текущего,
//у которых установлен реквизит ВыполнятьОбмен.
ВыборкаУзлов = ПланыОбмена.РаспределеннаяБаза.Выбрать();
Пока ВыборкаУзлов.Следующий() Цикл
Если Не ВыборкаУзлов.ВыполнятьОбмен Тогда
Продолжить;
КонецЕсли;
Если ВыборкаУзлов.Ссылка = ПланыОбмена.РаспределеннаяБаза.ЭтотУзел() Тогда
Продолжить;
КонецЕсли;
ЭлектронныйАдрес = СокрЛП(ВыборкаУзлов.ЭлектронныйАдрес);
Если ЭлектронныйАдрес = "" Тогда
Продолжить;
КонецЕсли;
//С помощью объектов ЗаписьXML и ЗаписьСообщения выполняем запись изменений
//для выбранного узла в xml-файл.
Узел = ВыборкаУзлов.Ссылка;
ЗаписьXML = Новый ЗаписьXML();
ИмяФайлаСообщения = КаталогВременныхФайлов() + "Message_" +
СокрЛП(ПланыОбмена.РаспределеннаяБаза.ЭтотУзел().Код) +
"_" + СокрЛП(Узел.Код) + ".xml";
ЗаписьXML.ОткрытьФайл(ИмяФайлаСообщения);
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
ЗаписьСообщения.НачатьЗапись(ЗаписьXML,Узел);
ПланыОбмена.ЗаписатьИзменения(ЗаписьСообщения);
ЗаписьСообщения.ЗакончитьЗапись();
ЗаписьXML.Закрыть();
//Затем создаем новое письмо, прикрепляем к нему полученный xml-файл и
//отправляем по адресу, указанному в реквизите ЭлектронныйАдрес узла.
Файл = Новый Файл(ИмяФайлаСообщения);
ТемаСообщения = "1С:Обмен " +
СокрЛП(ПланыОбмена.РаспределеннаяБаза.ЭтотУзел().Код) +
"_" + СокрЛП(Узел.Код);
Если ИспользоватьSMTP Тогда
ПочтовоеСообщение = Новый ИнтернетПочтовоеСообщение;
ПочтовоеСообщение.Тема = ТемаСообщения;
ПочтовоеСообщение.Вложения.Добавить(ИмяФайлаСообщения, Файл.Имя);
ПочтовоеСообщение.Получатели.Добавить(ЭлектронныйАдрес);
Почта.Послать(ПочтовоеСообщение);
Иначе
ПочтовоеСообщение = Новый ПочтовоеСообщение;
ПочтовоеСообщение.Тема = ТемаСообщения;
ПочтовоеСообщение.Вложения.Добавить(ИмяФайлаСообщения);
ПочтовоеСообщение.Получатели.Добавить(ЭлектронныйАдрес);
Почта.Послать(ПочтовоеСообщение, Ложь);
КонецЕсли;
Если Константы.ВыводитьСообщенияОбмена.Получить() Тогда
Сообщить("ОБМЕН: Сообщение обмена для узла " + Узел.Наименование +
" отправлено!", СтатусСообщения.Информация);
КонецЕсли;
УдалитьФайлы(ИмяФайлаСообщения);
КонецЦикла;
Почта.Отключиться();
КонецПроцедуры
Процедура рбПолучитьСообщенияОбмена() Экспорт
ИспользоватьSMTP = Константы.ИспользоватьОбменПоSMTP.Получить();
//так же, как в процедуре рбОтправитьСообщенияОбмена(), сначала создаем объект
Почта
Если ИспользоватьSMTP Тогда
ПочтовыйПрофиль = Новый ИнтернетПочтовыйПрофиль;
ПочтовыйПрофиль.АдресСервераPOP3 = Константы.АдресСервераPOP3Обмена.Получить();
ПочтовыйПрофиль.ПортPOP3 = Константы.ПортСервераPOP3Обмена.Получить();
ПочтовыйПрофиль.Пользователь = Константы.ПользовательСервераPOP3Обмена.Получить();
ПочтовыйПрофиль.Пароль =
Константы.ПарольПользователяPOP3Обмена.Получить();
ПочтовыйПрофиль.ВремяОжидания = Константы.ВремяОжиданияСервера.Получить();
Почта = Новый ИнтернетПочта();
Попытка
Почта.Подключиться(ПочтовыйПрофиль);
Исключение
Сообщить("ОБМЕН: Ошибка при подключении к почтовому профилю!
|Обмен не выполнен!", СтатусСообщения.ОченьВажное);
Возврат;
КонецПопытки;
Иначе
Почта = Новый Почта();
Попытка
Почта.Подключиться();
Исключение
Сообщить("ОБМЕН: Ошибка при подключении к почтовому профилю пользователя!
|Обмен не выполнен!", СтатусСообщения.ОченьВажное);
Возврат;
КонецПопытки;
КонецЕсли;
МассивСообщений = Новый Массив;
Если ИспользоватьSMTP Тогда
ВсеСообщения = Почта.Выбрать(Ложь);
Иначе
ВсеСообщения = Почта.Выбрать(Ложь, Ложь);
КонецЕсли;
//Отбираем среди всех писем те, которые имеют тему "1С:Обмен".
//Маленькое, но важное замечание:
//считаем, что все полученные письма с темой "1С:Обмен" предназначены
//именно для текущего узла,
//т.е. что у разных узлов в плане обмена РАЗНЫЕ электронные адреса.
Для Каждого Сообщение Из ВсеСообщения Цикл
Если Лев(Сообщение.Тема, 8) <> "1С:Обмен" Тогда
Продолжить;
КонецЕсли;
Попытка
МассивСообщений.Добавить(Сообщение);
//Вложение письма сохраняем на диске.
//Аккуратную проверку вложения оставим пока "за кадром."
Вложение = Сообщение.Вложения[0];
ИмяФайлаСообщения = КаталогВременныхФайлов() + Вложение.Name;
ДанныеОбмена = Вложение.Данные;
ДанныеОбмена.Записать(ИмяФайлаСообщения);
//С помощью объектов ЧтениеXML и ЧтениеСообщения читаем данные
//обновления из сохраненного файла. Перед записью обновлений в ИБ
//устанавливаем параметр сеанса ИдетОбменРаспределеннойБазы в Истина.
//Затем читаем изменения в ИБ: ПланыОбмена.ПрочитатьИзменения(ЧтениеСообщения).
//Попутно сохраняем сообщения в массиве, чтобы потом их все сразу удалить.
ЧтениеXML = Новый ЧтениеXML();
ЧтениеXML.ОткрытьФайл(ИмяФайлаСообщения);
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
ЧтениеСообщения.НачатьЧтение(ЧтениеXML);
ПараметрыСеанса.ИдетОбменРаспределеннойБазы = Истина;
ПланыОбмена.ПрочитатьИзменения(ЧтениеСообщения);
ЧтениеСообщения.ЗакончитьЧтение();
ЧтениеXML.Закрыть();
Если Константы.ВыводитьСообщенияОбмена.Получить() Тогда
Сообщить("ОБМЕН: Данные обмена приняты",СтатусСообщения.Информация);
КонецЕсли;
Исключение
Сообщить("ОБМЕН: Ошибка при получении данных обмена: " + ОписаниеОшибки(),
СтатусСообщения.ОченьВажное);
КонецПопытки;
//После того, как чтение данных обмена закончено, возвращаем
//параметру сеанса ИдетОбменРаспределеннойБазы значение Ложь.
ПараметрыСеанса.ИдетОбменРаспределеннойБазы = Ложь;
Попытка
УдалитьФайлы(ИмяФайлаСообщения);
Исключение
//если не получилось, ну и ладно
КонецПопытки;
КонецЦикла;
Если ИспользоватьSMTP Тогда
Почта.УдалитьСообщения(МассивСообщений);
КонецЕсли;
Почта.Отключиться();
КонецПроцедуры
Процедура рбВыполнитьОбмен(прПользователь) Экспорт
Если нпПолучитьЗначениеПоУмолчанию(прПользователь,
"ВыполнятьОбменРаспределенныхБаз") Тогда
рбПолучитьСообщенияОбмена();
рбОтправитьСообщенияОбмена();
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьПодключениеАвтообмена() Экспорт
Если нпПолучитьЗначениеПоУмолчанию(глТекущийПользователь,
"ВыполнятьОбменРаспределенныхБаз")
И Константы.ИнтервалАвтообменаРаспределеннойБазы.Получить() > 0
Тогда
ПодключитьОбработчикОжидания("ВыполнитьАвтообмен",
Константы.ИнтервалАвтообменаРаспределеннойБазы.Получить());
Иначе
ОтключитьОбработчикОжидания("ВыполнитьАвтообмен");
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьАвтообмен() Экспорт
рбВыполнитьОбмен(глТекущийПользователь);
ОтключитьОбработчикОжидания("ВыполнитьАвтообмен");
Если нпПолучитьЗначениеПоУмолчанию(глТекущийПользователь,
"ВыполнятьОбменРаспределенныхБаз")
И Константы.ИнтервалАвтообменаРаспределеннойБазы.Получить() > 0 Тогда
ПодключитьОбработчикОжидания("ВыполнитьАвтообмен",
Константы.ИнтервалАвтообменаРаспределеннойБазы.Получить());
КонецЕсли;
КонецПроцедуры
Процедура ОтключитьАвтообмен() Экспорт
ОтключитьОбработчикОжидания("ВыполнитьАвтообмен");
КонецПроцедуры
ПараметрыСеанса.ИдетОбменРаспределеннойБазы = Ложь;
ПроверитьПодключениеАвтообмена();
1cv8.exe CONFIG /F<путь к ИБ> /N<Пользователь> /P<Пароль> /UpdateIBCfg
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua