///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2021, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
// модуль дополнен для использования в качестве фикстуры
///////////////////////////////////////////////////////////////////////////////////////////////////////
#Область ПрограммныйИнтерфейс
// Получает значение настройки плана обмена по ее имени.
// Для несуществующих настроек возвращается Неопределено.
//
// Параметры:
// ИмяПланаОбмена - Строка - имя плана обмена из метаданных.
// ИмяПараметра - Строка - имя параметра плана обмена или список параметров, разделенных запятыми.
// Список допустимых значений см. в функциях НастройкиПланаОбменаПоУмолчанию,
// ОписаниеВариантаНастройкиОбменаПоУмолчанию.
// ИдентификаторНастройки - Строка - имя предопределенной настройки плана обмена.
// ВерсияКорреспондента - Строка - версия конфигурации корреспондента.
//
// Возвращаемое значение:
// Произвольный, Структура - тип возвращаемого значения зависит от типа значения получаемой настройки.
// Произвольный, если в качестве ИмяПараметра был передан единичный параметр
// Структура, если в качестве параметра ИмяПараметра была передан список параметров через запятую.
//
Функция ЗначениеНастройкиПланаОбмена(ИмяПланаОбмена, ИмяПараметра, ИдентификаторНастройки = "", ВерсияКорреспондента = "") Экспорт
ЗначениеПараметра = Новый Структура;
НастройкиПланаОбмена = Неопределено;
ОписаниеВариантаНастройки = Неопределено;
ИмяПараметра = СтрЗаменить(ИмяПараметра, Символы.ПС, "");
ИменаПараметров = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ИмяПараметра,,Истина);
НастройкиПланаОбменаПоУмолчанию = НастройкиПланаОбменаПоУмолчанию(ИмяПланаОбмена);
ОписаниеВариантаПоУмолчанию = ОписаниеВариантаНастройкиОбменаПоУмолчанию(ИмяПланаОбмена);
Если ИменаПараметров.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Для Каждого ЕдиничныйПараметр Из ИменаПараметров Цикл
ЗначениеЕдиничногоПараметра = Неопределено;
Если НастройкиПланаОбменаПоУмолчанию.Свойство(ЕдиничныйПараметр) Тогда
Если НастройкиПланаОбмена = Неопределено Тогда
НастройкиПланаОбмена = ОбменДаннымиПовтИсп.НастройкиПланаОбмена(ИмяПланаОбмена);
КонецЕсли;
НастройкиПланаОбмена.Свойство(ЕдиничныйПараметр, ЗначениеЕдиничногоПараметра);
ИначеЕсли ОписаниеВариантаПоУмолчанию.Свойство(ЕдиничныйПараметр) Тогда
Если ОписаниеВариантаНастройки = Неопределено Тогда
ОписаниеВариантаНастройки = ОбменДаннымиПовтИсп.ОписаниеВариантаНастройки(ИмяПланаОбмена, ИдентификаторНастройки, ВерсияКорреспондента);
КонецЕсли;
ОписаниеВариантаНастройки.Свойство(ЕдиничныйПараметр, ЗначениеЕдиничногоПараметра);
КонецЕсли;
Если ИменаПараметров.Количество() = 1 Тогда
Возврат ЗначениеЕдиничногоПараметра;
Иначе
ЗначениеПараметра.Вставить(ЕдиничныйПараметр, ЗначениеЕдиничногоПараметра);
КонецЕсли;
КонецЦикла;
Возврат ЗначениеПараметра;
КонецФункции
// Процедура-обработчик события "ПриСозданииНаСервере" для формы узла плана обмена.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - форма, из которой вызвана процедура:
// * Объект - ДанныеФормыСтруктура:
// ** Ссылка - ПланОбменаСсылка - узел плана обмена.
// Отказ - Булево - признак отказа от создания формы. Если установить в Истина, то форма создана не будет.
//
Процедура ФормаУзлаПриСозданииНаСервере(Форма, Отказ) Экспорт
ПредставлениеПланаОбмена = ЗначениеНастройкиПланаОбмена(
Форма.Объект.Ссылка.Метаданные().Имя,
"ЗаголовокУзлаПланаОбмена",
ВариантОбменаДанными(Форма.Объект.Ссылка));
Форма.АвтоЗаголовок = Ложь;
Форма.Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Форма.Объект.Наименование + " (%1)",
ПредставлениеПланаОбмена);
КонецПроцедуры
// Процедура-обработчик события "ПриЗаписиНаСервере" для формы узла плана обмена.
//
// Параметры:
// ТекущийОбъект - ПланОбменаОбъект - записываемый узел плана обмена.
// Отказ - Булево - входящий, признак отказа от записи узла обмена.
// Если установлен в Истина, то для узла не будет
// зафиксировано завершение настройки синхронизации.
//
Процедура ФормаУзлаПриЗаписиНаСервере(ТекущийОбъект, Отказ) Экспорт
Если Отказ Тогда
Возврат;
КонецЕсли;
Если Не НастройкаСинхронизацииЗавершена(ТекущийОбъект.Ссылка) Тогда
ЗавершитьНастройкуСинхронизацииДанных(ТекущийОбъект.Ссылка);
КонецЕсли;
КонецПроцедуры
// Процедура-обработчик события "ПриСозданииНаСервере" для формы настройки узла.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - форма, из которой вызвана процедура.
// ИмяПланаОбмена - Строка - имя плана обмена, для которого создана форма.
//
Процедура ФормаНастройкиУзлаПриСозданииНаСервере(Форма, ИмяПланаОбмена) Экспорт
ИдентификаторНастройки = "";
Если Форма.Параметры.Свойство("ИдентификаторНастройки") Тогда
ИдентификаторНастройки = Форма.Параметры.ИдентификаторНастройки;
КонецЕсли;
ПроверитьОбязательныеРеквизитыФормы(Форма, "НастройкаОтборовНаУзле, ВерсияКорреспондента");
Форма.ВерсияКорреспондента = Форма.Параметры.ВерсияКорреспондента;
Форма.НастройкаОтборовНаУзле = НастройкаОтборовНаУзле(ИмяПланаОбмена, Форма.ВерсияКорреспондента, ИдентификаторНастройки);
ФормаНастройкиУзлаОбработчикПриСозданииНаСервере(Форма, "НастройкаОтборовНаУзле");
КонецПроцедуры
// Определяет необходимость выполнения обработчика события "ПослеВыгрузкиДанных" при обмене в РИБ.
//
// Параметры:
// Объект - ПланОбменаОбъект - узел плана обмена, для которого выполняется обработчик.
// Ссылка - ПланОбменаСсылка - ссылка на узел плана обмена, для которого выполняется обработчик.
//
// Возвращаемое значение:
// Булево - если Истина, то необходимо выполнить обработчик "ПослеВыгрузкиДанных"; Ложь - нет.
//
Функция НадоВыполнитьОбработчикПослеВыгрузкиДанных(Объект, Ссылка) Экспорт
Возврат НадоВыполнитьОбработчик(Объект, Ссылка, "НомерОтправленного");
КонецФункции
// Определяет необходимость выполнения обработчика события "ПослеЗагрузкиДанных" при обмене в РИБ.
//
// Параметры:
// Объект - ПланОбменаОбъект - узел плана обмена, для которого выполняется обработчик.
// Ссылка - ПланОбменаСсылка - ссылка на узел плана обмена, для которого выполняется обработчик.
//
// Возвращаемое значение:
// Булево - если Истина, то необходимо выполнить обработчик "ПослеЗагрузкиДанных"; Ложь - нет.
//
Функция НадоВыполнитьОбработчикПослеЗагрузкиДанных(Объект, Ссылка) Экспорт
Возврат НадоВыполнитьОбработчик(Объект, Ссылка, "НомерПринятого");
КонецФункции
// Возвращает префикс этой информационной базы.
//
// Возвращаемое значение:
// Строка - префикс этой информационной базы.
//
Функция ПрефиксИнформационнойБазы() Экспорт
Возврат ПолучитьФункциональнуюОпцию("ПрефиксИнформационнойБазы");
КонецФункции
// Возвращает версию конфигурации корреспондента.
// Если версия конфигурации корреспондента не определена, то возвращает пустую версию - "0.0.0.0".
//
// Параметры:
// Корреспондент - ПланОбменаСсылка - узел плана обмена, для которого необходимо получить версию конфигурации.
//
// Возвращаемое значение:
// Строка - версия конфигурации корреспондента.
//
// Пример:
// Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ОбменДаннымиСервер.ВерсияКорреспондента(Корреспондент), "2.1.5.1")
// >= 0 Тогда ...
//
Функция ВерсияКорреспондента(Знач Корреспондент) Экспорт
УстановитьПривилегированныйРежим(Истина);
Возврат РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.ВерсияКорреспондента(Корреспондент);
КонецФункции
// Устанавливает префикс этой информационной базы.
//
// Параметры:
// Префикс - Строка - новое значение префикса информационной базы.
//
Процедура УстановитьПрефиксИнформационнойБазы(Знач Префикс) Экспорт
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПрефиксацияОбъектов")
И Не ОткрытьПомощникСозданияОбменаДаннымиДляНастройкиПодчиненногоУзла() Тогда
МодульПрефиксацияОбъектовСлужебный = ОбщегоНазначения.ОбщийМодуль("ПрефиксацияОбъектовСлужебный");
ПараметрыИзмененияПрефикса = Новый Структура("НовыйПрефиксИБ, ПродолжитьНумерацию",
СокрЛП(Префикс), Истина);
МодульПрефиксацияОбъектовСлужебный.ИзменитьПрефиксИБ(ПараметрыИзмененияПрефикса);
Иначе
// Изменение данных с целью перенумерации справочников и документов не должно выполняться
// - в случае, если подсистема префиксации не встроена,
// - при первом запуске подчиненного узла РИБ.
Константы.ПрефиксУзлаРаспределеннойИнформационнойБазы.Установить(СокрЛП(Префикс));
КонецЕсли;
ОбменДаннымиСлужебный.СброситьКэшМеханизмаРегистрацииОбъектов();
КонецПроцедуры
// Проверяет факт восстановления этой базы из резервной копии.
// Если база была восстановлена из резервной копии, то необходимо выполнить синхронизацию номеров отправленных и
// полученных сообщений для двух баз (номеру отправленного сообщения в этой базе присваивается значение номера
// принятого сообщения из базы-корреспондента).
// Если база была восстановлена из резервной копии, то рекомендуется не снимать с регистрации изменения данных на
// текущем узле, т.к. эти данные могли быть еще не отправлены.
//
// Параметры:
// Отправитель - ПланОбменаСсылка - узел, от имени которого было сформировано и отправлено сообщение обмена.
// НомерПринятого - Число - номер принятого сообщения в базе-корреспонденте.
//
// Возвращаемое значение:
// ФиксированнаяСтруктура:
// * Отправитель - ПланОбменаСсылка - см. выше параметр Отправитель.
// * НомерПринятого - Число - см. выше параметр НомерПринятого.
// * ВосстановленаРезервнаяКопия - Булево - Истина, если обнаружен факт восстановления этой базы из резервной копии.
//
Функция ПараметрыРезервнойКопии(Знач Отправитель, Знач НомерПринятого) Экспорт
// Для базы, которая была поднята из резервной копии, номер отправленного сообщения
// будет меньше номера принятого сообщения в корреспонденте.
// Т.е. эта база получит номер принятого сообщения,
// который она еще не отправляла - "сообщение из будущего".
Результат = Новый Структура("Отправитель, НомерПринятого, ВосстановленаРезервнаяКопия");
Результат.Отправитель = Отправитель;
Результат.НомерПринятого = НомерПринятого;
Результат.ВосстановленаРезервнаяКопия = (НомерПринятого > ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Отправитель, "НомерОтправленного"));
Возврат Новый ФиксированнаяСтруктура(Результат);
КонецФункции
// Выполняет синхронизацию номеров отправленных и полученных сообщений
// для двух баз (номеру отправленного сообщения в этой базе присваивается значение номера принятого сообщения из
// базы-корреспондента).
//
// Параметры:
// ПараметрыРезервнойКопии - ФиксированнаяСтруктура:
// * Отправитель - ПланОбменаСсылка - узел, от имени которого было сформировано и отправлено
// сообщение обмена.
// * НомерПринятого - Число - номер принятого сообщения в базе-корреспонденте.
// * ВосстановленаРезервнаяКопия - Булево - признак восстановления этой базы из резервной копии.
//
Процедура ПриВосстановленииРезервнойКопии(Знач ПараметрыРезервнойКопии) Экспорт
Если ПараметрыРезервнойКопии.ВосстановленаРезервнаяКопия Тогда
НачатьТранзакцию();
Попытка
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить(ОбщегоНазначения.ИмяТаблицыПоСсылке(ПараметрыРезервнойКопии.Отправитель));
ЭлементБлокировки.УстановитьЗначение("Ссылка", ПараметрыРезервнойКопии.Отправитель);
Блокировка.Заблокировать();
ЗаблокироватьДанныеДляРедактирования(ПараметрыРезервнойКопии.Отправитель);
ОтправительОбъект = ПараметрыРезервнойКопии.Отправитель.ПолучитьОбъект();
ОтправительОбъект.НомерОтправленного = ПараметрыРезервнойКопии.НомерПринятого;
ОтправительОбъект.ОбменДанными.Загрузка = Истина;
ОтправительОбъект.Записать();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецЕсли;
КонецПроцедуры
// Возвращает идентификатор сохраненного варианта настройки плана обмена.
// Параметры:
// УзелПланаОбмена - ПланОбменаСсылка - узел плана обмена, для которого необходимо получить переопределяемое
// имя.
//
// Возвращаемое значение:
// Строка - идентификатор сохраненной настройки как он задан в конфигураторе.
//
Функция СохраненныйВариантНастройкиУзлаПланаОбмена(УзелПланаОбмена) Экспорт
ВариантНастройки = "";
Если ОбщегоНазначения.ЕстьРеквизитОбъекта("ВариантНастройки", УзелПланаОбмена.Метаданные()) Тогда
УстановитьПривилегированныйРежим(Истина);
ВариантНастройки = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(УзелПланаОбмена, "ВариантНастройки");
КонецЕсли;
Возврат ВариантНастройки;
КонецФункции
// Возвращает массив всех видов транспорта сообщений обмена, определенных в конфигурации.
//
// Возвращаемое значение:
// Массив из ПеречислениеСсылка.ВидыТранспортаСообщенийОбмена - все виды транспорта сообщений обмена.
//
Функция ВсеТранспортыСообщенийОбменаКонфигурации() Экспорт
Результат = Новый Массив;
Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.COM);
Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.WS);
Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.FILE);
Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.FTP);
Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.EMAIL);
Результат.Добавить(Перечисления.ВидыТранспортаСообщенийОбмена.WSПассивныйРежим);
Возврат Результат;
КонецФункции
// Выполняет отправку или получение данных для узла информационной базы используя любой из
// доступных для плана обмена канал связи, кроме COM-соединения и web-сервиса.
//
// Параметры:
// Отказ - Булево - флаг отказа, устанавливается в Истина в случае
// не успешного выполнения процедуры.
// УзелИнформационнойБазы - УзелОбменаСсылка - ПланОбменаСсылка - узел плана обмена,
// для которого выполняется действие обмена данными.
// ДействиеПриОбмене - ПеречислениеСсылка.ДействияПриОбмене - выполняемое действие обмена данными.
// ВидТранспортаСообщенийОбмена - ПеречислениеСсылка.Перечисления.ВидыТранспортаСообщенийОбмена - вид транспорта,
// который будет использоваться в процессе обмена данными. Если не указан,
// определяется из параметров транспорта, заданных для узла плана обмена при
// настройке обмена. Необязательный, значение по умолчанию Неопределено.
// ТолькоПараметры - Булево - содержит признак выборочной загрузки данных при обмене РИБ.
// ДополнительныеПараметры - Структура - зарезервировано для служебного использования.
//
Процедура ВыполнитьДействиеОбменаДляУзлаИнформационнойБазы(
Отказ,
УзелИнформационнойБазы,
ДействиеПриОбмене,
ВидТранспортаСообщенийОбмена = Неопределено,
Знач ТолькоПараметры = Ложь,
ДополнительныеПараметры = Неопределено) Экспорт
Если ДополнительныеПараметры = Неопределено Тогда
ДополнительныеПараметры = Новый Структура;
КонецЕсли;
УстановитьПривилегированныйРежим(Истина);
// ИНИЦИАЛИЗАЦИЯ ОБМЕНА ДАННЫМИ
СтруктураНастроекОбмена = НастройкиОбменаДляУзлаИнформационнойБазы(
УзелИнформационнойБазы, ДействиеПриОбмене, ВидТранспортаСообщенийОбмена);
ЗафиксироватьНачалоОбменаВРегистреСведений(СтруктураНастроекОбмена);
Если СтруктураНастроекОбмена.Отказ Тогда
// Если настройка содержит ошибки, то обмен не производим; статус "Отменено".
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Отказ = Истина;
Возврат;
КонецЕсли;
Для Каждого Параметр Из ДополнительныеПараметры Цикл
СтруктураНастроекОбмена.ДополнительныеПараметры.Вставить(Параметр.Ключ, Параметр.Значение);
КонецЦикла;
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено;
СтрокаСообщения = НСтр("ru = 'Начало процесса обмена данными для узла %1'", ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, СтруктураНастроекОбмена.УзелИнформационнойБазыНаименование);
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщения, СтруктураНастроекОбмена);
// ОБМЕН ДАННЫМИ
ВыполнитьОбменДаннымиЧерезФайловыйРесурс(СтруктураНастроекОбмена, ТолькоПараметры);
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Для Каждого Параметр Из СтруктураНастроекОбмена.ДополнительныеПараметры Цикл
ДополнительныеПараметры.Вставить(Параметр.Ключ, Параметр.Значение);
КонецЦикла;
Если Не РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена) Тогда
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
// Возвращает количество нерассмотренных проблем обмена данными. Используется для отображения
// количества проблем обмена в пользовательском интерфейсе. Например, для использования в заголовке
// гиперссылки для перехода к монитору проблем обмена.
//
// Параметры:
// Узлы - Массив из ПланОбменаСсылка - узлы обмена.
//
// Возвращаемое значение:
// Число - количество нерассмотренных проблем обмена данными.
//
Функция КоличествоНерассмотренныхПроблем(Узлы = Неопределено) Экспорт
Возврат КоличествоПроблемОбменаДанными(Узлы) + КоличествоПроблемВерсионирования(Узлы);
КонецФункции
// Возвращает структуру заголовка гиперссылки для перехода к монитору проблем обмена данными.
//
// Параметры:
// Узлы - Массив из ПланОбменаСсылка - узлы обмена.
//
// Возвращаемое значение:
// Структура:
// * Заголовок - Строка - заголовок гиперссылки.
// * Картинка - Картинка - картинка для гиперссылки.
//
Функция СтруктураЗаголовкаГиперссылкиМонитораПроблем(Узлы = Неопределено) Экспорт
Количество = КоличествоНерассмотренныхПроблем(Узлы);
Если Количество > 0 Тогда
Заголовок = НСтр("ru = 'Предупреждения (%1)'");
Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Заголовок, Количество);
Картинка = БиблиотекаКартинок.Предупреждение;
Иначе
Заголовок = НСтр("ru = 'Предупреждений нет'");
Картинка = Новый Картинка;
КонецЕсли;
СтруктураЗаголовка = Новый Структура;
СтруктураЗаголовка.Вставить("Заголовок", Заголовок);
СтруктураЗаголовка.Вставить("Картинка", Картинка);
Возврат СтруктураЗаголовка;
КонецФункции
// Определяет, существует ли каталог на FTP-сервере.
//
// Параметры:
// Путь - Строка - путь к каталогу.
// ИмяКаталога - Строка - имя каталога.
// FTPСоединение - FTPСоединение - FTPСоединение, используемое для подключения к FTP-серверу.
//
// Возвращаемое значение:
// Булево - если Истина, то каталог существует; Ложь - нет.
//
Функция FTPКаталогСуществует(Знач Путь, Знач ИмяКаталога, Знач FTPСоединение) Экспорт
Для Каждого FTPФайл Из FTPСоединение.НайтиФайлы(Путь) Цикл
Если FTPФайл.ЭтоКаталог() И FTPФайл.Имя = ИмяКаталога Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
// Возвращает данные таблиц для реквизитов узла обмена.
//
// Параметры:
// Таблицы - Массив из Строка - имена реквизитов узла плана обмена.
// ИмяПланаОбмена - Строка - имя плана обмена.
//
// Возвращаемое значение:
// Соответствие - соответствие таблиц и их данных.
//
Функция ДанныеТаблицКорреспондента(Таблицы, Знач ИмяПланаОбмена) Экспорт
Результат = Новый Соответствие;
РеквизитыПланаОбмена = Метаданные.ПланыОбмена[ИмяПланаОбмена].Реквизиты;
Для Каждого Элемент Из Таблицы Цикл
Реквизит = РеквизитыПланаОбмена.Найти(Элемент);
Если Реквизит <> Неопределено Тогда
ТипыРеквизита = Реквизит.Тип.Типы();
Если ТипыРеквизита.Количество() <> 1 Тогда
СтрокаСообщения = НСтр("ru = 'Составной тип данных для значений по умолчанию не поддерживается.
|Реквизит ""%1"".'");
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, Реквизит.ПолноеИмя());
ВызватьИсключение СтрокаСообщения;
КонецЕсли;
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипыРеквизита.Получить(0));
Если Не ОбщегоНазначения.ЭтоСправочник(ОбъектМетаданных) Тогда
СтрокаСообщения = НСтр("ru = 'Выбор значений по умолчанию поддерживается только для справочников.
|Реквизит ""%1"".'");
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, Реквизит.ПолноеИмя());
ВызватьИсключение СтрокаСообщения;
КонецЕсли;
ПолноеИмяОбъектаМетаданных = ОбъектМетаданных.ПолноеИмя();
ДанныеТаблицы = Новый Структура("СвойстваОбъектаМетаданных, ТаблицаБазыКорреспондента");
ДанныеТаблицы.СвойстваОбъектаМетаданных = СвойстваОбъектаМетаданных(ПолноеИмяОбъектаМетаданных);
ДанныеТаблицы.ТаблицаБазыКорреспондента = ПолучитьОбъектыТаблицы(ПолноеИмяОбъектаМетаданных);
Результат.Вставить(ПолноеИмяОбъектаМетаданных, ДанныеТаблицы);
КонецЕсли;
КонецЦикла;
Результат.Вставить("{ДополнительныеДанные}", Новый Структура); // Для обратной совместимости с 2.4.x
Возврат Результат;
КонецФункции
// Выполняет установку в константе количества элементов в транзакции загрузки данных.
//
// Параметры:
// Количество - Число - количество элементов в транзакции.
//
Процедура УстановитьКоличествоЭлементовВТранзакцииЗагрузкиДанных(Количество) Экспорт
УстановитьПривилегированныйРежим(Истина);
Константы.КоличествоЭлементовВТранзакцииЗагрузкиДанных.Установить(Количество);
КонецПроцедуры
// Возвращает представление даты синхронизации.
//
// Параметры:
// ДатаСинхронизации - Дата - абсолютная дата синхронизации данных.
//
// Возвращаемое значение:
// Строка - строковое представление даты.
//
Функция ПредставлениеДатыСинхронизации(Знач ДатаСинхронизации) Экспорт
Если Не ЗначениеЗаполнено(ДатаСинхронизации) Тогда
Возврат НСтр("ru = 'Синхронизация не выполнялась.'");
КонецЕсли;
Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Последняя синхронизация: %1'"), ОтносительнаяДатаСинхронизации(ДатаСинхронизации));
КонецФункции
// Возвращает представление относительной даты синхронизации.
//
// Параметры:
// ДатаСинхронизации - Дата - абсолютная дата синхронизации данных.
//
// Возвращаемое значение:
// Строка - представление относительной даты синхронизации:
// *Никогда (Т = пустая дата).
// *Сейчас (Т < 5 мин)
// *5 минут назад (5 мин < Т < 15 мин)
// *15 минут назад (15 мин < Т < 30 мин)
// *30 минут назад (30 мин < Т < 1 час)
// *1 час назад (1 час < Т < 2 час)
// *2 часа назад (2 час < Т < 3 час).
// *Сегодня, 12:44:12 (3 час < Т < вчера).
// *Вчера, 22:30:45 (вчера < Т < позавчера).
// *Позавчера, 21:22:54 (позавчера < Т < поза-позавчера).
// *<12 Марта 2012г.> (поза-позавчера < Т).
//
Функция ОтносительнаяДатаСинхронизации(Знач ДатаСинхронизации) Экспорт
Если Не ЗначениеЗаполнено(ДатаСинхронизации) Тогда
Возврат НСтр("ru = 'Никогда'");
КонецЕсли;
ДатаТекущая = ТекущаяДатаСеанса();
Интервал = ДатаТекущая - ДатаСинхронизации;
Если Интервал < 0 Тогда // 0 мин
Результат = Формат(ДатаСинхронизации, "ДЛФ=DD");
ИначеЕсли Интервал < 60 * 5 Тогда // 5 мин
Результат = НСтр("ru = 'Сейчас'");
ИначеЕсли Интервал < 60 * 15 Тогда // 15 мин
Результат = НСтр("ru = '5 минут назад'");
ИначеЕсли Интервал < 60 * 30 Тогда // 30 мин
Результат = НСтр("ru = '15 минут назад'");
ИначеЕсли Интервал < 60 * 60 * 1 Тогда // 1 час
Результат = НСтр("ru = '30 минут назад'");
ИначеЕсли Интервал < 60 * 60 * 2 Тогда // 2 часа
Результат = НСтр("ru = '1 час назад'");
ИначеЕсли Интервал < 60 * 60 * 3 Тогда // 3 часа
Результат = НСтр("ru = '2 часа назад'");
Иначе
КоличествоДнейРазницы = КоличествоДнейРазницы(ДатаСинхронизации, ДатаТекущая);
Если КоличествоДнейРазницы = 0 Тогда // сегодня
Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Сегодня, %1'"), Формат(ДатаСинхронизации, "ДЛФ=T"));
ИначеЕсли КоличествоДнейРазницы = 1 Тогда // вчера
Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Вчера, %1'"), Формат(ДатаСинхронизации, "ДЛФ=T"));
ИначеЕсли КоличествоДнейРазницы = 2 Тогда // позавчера
Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Позавчера, %1'"), Формат(ДатаСинхронизации, "ДЛФ=T"));
Иначе // давно
Результат = Формат(ДатаСинхронизации, "ДЛФ=DD");
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Возвращает идентификатор поставляемого профиля групп доступа "Синхронизация данных с другими программами".
//
// Возвращаемое значение:
// Строка - идентификатор поставляемого профиля групп доступа.
//
Функция ПрофильДоступаСинхронизацияДанныхСДругимиПрограммами() Экспорт
Возврат "04937803-5dba-11df-a1d4-005056c00008";
КонецФункции
// Проверяет наличие возможности администрирования обменов у текущего пользователя.
//
// Возвращаемое значение:
// Булево - если Истина - права есть, Ложь - прав нет.
//
Функция ЕстьПраваНаАдминистрированиеОбменов() Экспорт
Возврат Пользователи.ЭтоПолноправныйПользователь();
КонецФункции
// Функция возвращает объект WSПрокси веб-сервиса Exchange, созданный с переданными параметрами.
//
// Параметры:
// СтруктураНастроек - Структура:
// * WSURLВебСервиса - Строка - месторасположение wsdl.
// * WSИмяСервиса - Строка - имя сервиса.
// * WSURLПространстваИменСервиса - Строка - URI пространства имен web-сервиса.
// * WSИмяПользователя - Строка - имя пользователя для входа на сервер.
// * WSПароль - Строка - пароль пользователя.
// * WSТаймаут - Число - таймаут на операции выполняемые через полученное прокси.
// СтрокаСообщенияОбОшибке - Строка - содержит подробное описание ошибки в случае неуспешного подключения;
// СообщениеПользователю - Строка - содержит краткое описание ошибки в случае неуспешного подключения.
//
// Возвращаемое значение:
// WSПрокси - объект WSПрокси веб-сервиса Exchange.
//
Функция ПолучитьWSПрокси(СтруктураНастроек, СтрокаСообщенияОбОшибке = "", СообщениеПользователю = "") Экспорт
УдалитьНезначащиеСимволыВНастройкахПодключения(СтруктураНастроек);
СтруктураНастроек.Вставить("WSURLПространстваИменСервиса", "http://www.1c.ru/SSL/Exchange");
СтруктураНастроек.Вставить("WSИмяСервиса", "Exchange");
СтруктураНастроек.Вставить("WSТаймаут", 600);
Возврат ПолучитьWSПроксиПоПараметрамПодключения(СтруктураНастроек, СтрокаСообщенияОбОшибке, СообщениеПользователю);
КонецФункции
// Функция возвращает объект WSПрокси веб-сервиса Exchange_2_0_1_6, созданный с переданными параметрами.
//
// Параметры:
// СтруктураНастроек - Структура:
// * WSURLВебСервиса - Строка - месторасположение wsdl.
// * WSИмяСервиса - Строка - имя сервиса.
// * WSURLПространстваИменСервиса - Строка - URI пространства имен web-сервиса.
// * WSИмяПользователя - Строка - имя пользователя для входа на сервер.
// * WSПароль - Строка - пароль пользователя.
// * WSТаймаут - Число - таймаут на операции выполняемые через полученное прокси.
// СтрокаСообщенияОбОшибке - Строка - содержит подробное описание ошибки в случае неуспешного подключения;
// СообщениеПользователю - Строка - содержит краткое описание ошибки в случае неуспешного подключения.
//
// Возвращаемое значение:
// WSПрокси - объект WSПрокси веб-сервиса Exchange_2_0_1_6.
//
Функция ПолучитьWSПрокси_2_0_1_6(СтруктураНастроек, СтрокаСообщенияОбОшибке = "", СообщениеПользователю = "") Экспорт
УдалитьНезначащиеСимволыВНастройкахПодключения(СтруктураНастроек);
СтруктураНастроек.Вставить("WSURLПространстваИменСервиса", "http://www.1c.ru/SSL/Exchange_2_0_1_6");
СтруктураНастроек.Вставить("WSИмяСервиса", "Exchange_2_0_1_6");
СтруктураНастроек.Вставить("WSТаймаут", 600);
Возврат ПолучитьWSПроксиПоПараметрамПодключения(СтруктураНастроек, СтрокаСообщенияОбОшибке, СообщениеПользователю);
КонецФункции
// Функция возвращает объект WSПрокси веб-сервиса Exchange_2_0_1_7, созданный с переданными параметрами.
//
// Параметры:
// СтруктураНастроек - Структура:
// * WSURLВебСервиса - Строка - месторасположение wsdl.
// * WSИмяСервиса - Строка - имя сервиса.
// * WSURLПространстваИменСервиса - Строка - URI пространства имен web-сервиса.
// * WSИмяПользователя - Строка - имя пользователя для входа на сервер.
// * WSПароль - Строка - пароль пользователя.
// * WSТаймаут - Число - таймаут на операции выполняемые через полученное прокси.
// СтрокаСообщенияОбОшибке - Строка - содержит подробное описание ошибки в случае неуспешного подключения;
// СообщениеПользователю - Строка - содержит краткое описание ошибки в случае неуспешного подключения.
// Таймаут - Число - таймаут.
//
// Возвращаемое значение:
// WSПрокси - объект WSПрокси веб-сервиса Exchange_2_0_1_7.
//
Функция ПолучитьWSПрокси_2_1_1_7(СтруктураНастроек, СтрокаСообщенияОбОшибке = "", СообщениеПользователю = "", Таймаут = 600) Экспорт
УдалитьНезначащиеСимволыВНастройкахПодключения(СтруктураНастроек);
СтруктураНастроек.Вставить("WSURLПространстваИменСервиса", "http://www.1c.ru/SSL/Exchange_2_0_1_6");
СтруктураНастроек.Вставить("WSИмяСервиса", "Exchange_2_0_1_6");
СтруктураНастроек.Вставить("WSТаймаут", Таймаут);
Возврат ПолучитьWSПроксиПоПараметрамПодключения(СтруктураНастроек, СтрокаСообщенияОбОшибке, СообщениеПользователю, Истина);
КонецФункции
// Функция возвращает объект WSПрокси веб-сервиса Exchange_3_0_1_1, созданный с переданными параметрами.
//
// Параметры:
// СтруктураНастроек - Структура:
// * WSURLВебСервиса - Строка - месторасположение wsdl.
// * WSИмяСервиса - Строка - имя сервиса.
// * WSURLПространстваИменСервиса - Строка - URI пространства имен web-сервиса.
// * WSИмяПользователя - Строка - имя пользователя для входа на сервер.
// * WSПароль - Строка - пароль пользователя.
// * WSТаймаут - Число - таймаут на операции выполняемые через полученное прокси.
// СтрокаСообщенияОбОшибке - Строка - содержит подробное описание ошибки в случае неуспешного подключения;
// СообщениеПользователю - Строка - содержит краткое описание ошибки в случае неуспешного подключения.
// Таймаут - Число - таймаут.
//
// Возвращаемое значение:
// WSПрокси - объект WSПрокси веб-сервиса Exchange_3_0_1_1.
//
Функция ПолучитьWSПрокси_3_0_1_1(СтруктураНастроек, СтрокаСообщенияОбОшибке = "", СообщениеПользователю = "", Таймаут = 600) Экспорт
УдалитьНезначащиеСимволыВНастройкахПодключения(СтруктураНастроек);
СтруктураНастроек.Вставить("WSURLПространстваИменСервиса", "http://www.1c.ru/SSL/Exchange_3_0_1_1");
СтруктураНастроек.Вставить("WSИмяСервиса", "Exchange_3_0_1_1");
СтруктураНастроек.Вставить("WSТаймаут", Таймаут);
Возврат ПолучитьWSПроксиПоПараметрамПодключения(СтруктураНастроек, СтрокаСообщенияОбОшибке, СообщениеПользователю, Истина);
КонецФункции
// Возвращает допустимое количество элементов, обрабатываемых в одной транзакции загрузки данных.
//
// Возвращаемое значение:
// Число - допустимое количество элементов, обрабатываемых в одной транзакции загрузки данных.
//
Функция КоличествоЭлементовВТранзакцииЗагрузкиДанных() Экспорт
УстановитьПривилегированныйРежим(Истина);
Возврат Константы.КоличествоЭлементовВТранзакцииЗагрузкиДанных.Получить();
КонецФункции
// Возвращает допустимое количество элементов, обрабатываемых в одной транзакции выгрузки данных.
//
// Возвращаемое значение:
// Число - допустимое количество элементов, обрабатываемых в одной транзакции выгрузки данных.
//
Функция КоличествоЭлементовВТранзакцииВыгрузкиДанных() Экспорт
Возврат 1;
КонецФункции
// Возвращает таблицу с данными узлов всех настроенных обменов БСП.
//
// Возвращаемое значение:
// ТаблицаЗначений:
// * УзелИнформационнойБазы - ПланОбменаСсылка - ссылка на узел плана обмена.
// * Наименование - Строка - наименование узла плана обмена.
// * ИмяПланаОбмена - Строка - имя плана обмена.
//
Функция УзлыОбменаБСП() Экспорт
Запрос = Новый Запрос(ТекстЗапросаПланыОбменаДляМонитора());
УстановитьПривилегированныйРежим(Истина);
УзлыОбменаБСП = Запрос.Выполнить().Выгрузить();
УстановитьПривилегированныйРежим(Ложь);
Возврат УзлыОбменаБСП;
КонецФункции
// Определяет, используются ли типовых правила конвертации для плана обмена.
//
// Параметры:
// ИмяПланаОбмена - Строка - имя плана обмена, для которого загружаются правила.
//
// Возвращаемое значение:
// Булево - если Истина, то используются; Ложь - нет.
//
Функция ИспользуютсяТиповыеПравила(ИмяПланаОбмена) Экспорт
Возврат РегистрыСведений.ПравилаДляОбменаДанными.ИспользуютсяТиповыеПравила(ИмяПланаОбмена);
КонецФункции
// Устанавливает внешнее соединение с информационной базой и возвращает описание соединения.
//
// Параметры:
// Параметры - Структура - параметры для установки внешнего соединения с информационной базой.
// Свойства см. в функции
// ОбщегоНазначенияКлиентСервер.СтруктураПараметровДляУстановкиВнешнегоСоединения:
//
// * ВариантРаботыИнформационнойБазы - Число - вариант работы информационной базы: 0 - файловый; 1 -
// клиент-серверный;
// * КаталогИнформационнойБазы - Строка - каталог информационной базы для файлового режима работы;
// * ИмяСервера1СПредприятия - Строка - имя сервера1С:Предприятия;
// * ИмяИнформационнойБазыНаСервере1СПредприятия - Строка - имя информационной базы на сервере1С:Предприятия;
// * АутентификацияОперационнойСистемы - Булево - признак аутентификации операционной системы при создании
// внешнего подключения к информационной базе;
// * ИмяПользователя - Строка - имя пользователя информационной базы;
// * ПарольПользователя - Строка - пароль пользователя информационной базы.
//
// Возвращаемое значение:
// Структура:
// * Соединение - COMОбъект
// - Неопределено - указатель на COM-объект соединения или Неопределено в
// случае ошибки;
// * КраткоеОписаниеОшибки - Строка - краткое описание ошибки;
// * ПодробноеОписаниеОшибки - Строка - подробное описание ошибки;
// * ОшибкаПодключенияКомпоненты - Булево - флаг ошибки подключения COM.
//
Функция ВнешнееСоединениеСБазой(Параметры) Экспорт
// Преобразуем настройки - параметры внешнего соединения в параметры транспорта.
НастройкиТранспорта = НастройкиТранспортаПоПараметрамВнешнегоСоединения(Параметры);
Возврат УстановитьВнешнееСоединениеСБазой(НастройкиТранспорта);
КонецФункции
// Точка входа для выполнения итерации обмена данными (загрузки и выгрузки) с внешней системой по узлу плана обмена.
//
// Параметры:
// Корреспондент - ПланОбменаСсылка - узел плана обмена, соответствующий внешней системе.
// ПараметрыОбмена - Структура - должна содержать следующие параметры:
// * ВыполнятьЗагрузку - Булево - флаг необходимости выполнять загрузку данных.
// * ВыполнятьОтправкуНастроек - Булево - флаг необходимости выполнять отправку настроек XDTO.
// ФлагОшибка - Булево - Истина, в случае возникновения ошибки при выполнении обмена.
// Подробная информация об ошибке фиксируется в журнале регистрации.
//
Процедура ВыполнитьОбменДаннымиСВнешнейСистемой(Корреспондент, ПараметрыОбмена, ФлагОшибка) Экспорт
ДополнительныеПараметры = Новый Структура;
ДействиеЗагрузка = Перечисления.ДействияПриОбмене.ЗагрузкаДанных;
ДействиеВыгрузка = Перечисления.ДействияПриОбмене.ВыгрузкаДанных;
ПроверитьВозможностьВыполненияОбменов();
ПроверитьИспользованиеОбменаДанными();
ТолькоПараметры = Ложь;
ВидТранспортаСообщенийОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.ВнешняяСистема;
ФлагОшибка = Ложь;
Если ПараметрыОбмена.ВыполнятьЗагрузку Тогда
ВыполнитьДействиеОбменаДляУзлаИнформационнойБазы(ФлагОшибка, Корреспондент,
ДействиеЗагрузка, ВидТранспортаСообщенийОбмена, ТолькоПараметры, ДополнительныеПараметры);
КонецЕсли;
Если ПараметрыОбмена.ВыполнятьОтправкуНастроек Тогда
ВыполнитьДействиеОбменаДляУзлаИнформационнойБазы(ФлагОшибка, Корреспондент,
ДействиеВыгрузка, ВидТранспортаСообщенийОбмена, ТолькоПараметры, ДополнительныеПараметры);
КонецЕсли;
КонецПроцедуры
#Область НастройкиПодключенияКВнешнейСистеме
// Сохраняет настройки подключения для обмена с внешней системой через EnterpriseData.
//
// Параметры:
// Контекст - Структура - контекст выполнения операции:
// * Режим - Строка - режим, в котором вызывается обработчик.
// Возможные значения: "НовоеПодключение" | "РедактированиеПараметровПодключения".
// * Корреспондент - ПланОбменаСсылка
// - Неопределено - узел обмена, соответствующий корреспонденту.
// Для режима "НовоеПодключение" равен Неопределено;
// * ИмяПланаОбмена - Строка
// - Неопределено - имя плана обмена, на котором создается узел.
// * ИдентификаторНастройки - Строка
// - Неопределено - идентификатор варианта настройки,
// как он указан в модуле менеджера плана обмена.
// ПараметрыПодключения - Структура - структура параметров подключения:
// * ИдентификаторКорреспондента - Строка - строка длиной 36 символов
// - Неопределено - уникальный идентификатор корреспондента.
// * НаименованиеКорреспондента - Строка
// - Неопределено - название корреспондента, как он будет отображаться
// в списке настроенных синхронизаций.
// * НастройкиТранспорта - Произвольный
// - Неопределено - произвольное значение, описывающее параметры подключения.
// * РасписаниеСинхронизации - РасписаниеРегламентногоЗадания
// - Неопределено - расписание запуска синхронизации.
// * НастройкиXDTO - Структура
// - Неопределено - структура настроек XDTO корреспондента:
// ** ПоддерживаемыеВерсии - Массив - перечень поддерживаемых корреспондентом версий формата.
// ** ПоддерживаемыеОбъекты - см. ОбменДаннымиXDTOСервер.ПоддерживаемыеОбъектыФормата
// Результат - Структура:
// * УзелОбмена - ПланОбменаСсылка - узел плана обмена, соответствующий корреспонденту.
// * ИдентификаторКорреспондента - Строка - уникальный идентификатор корреспондента.
//
Процедура ПриСохраненииНастроекПодключенияВнешнейСистемы(Контекст, ПараметрыПодключения, Результат) Экспорт
Корреспондент = Неопределено;
Контекст.Свойство("Корреспондент", Корреспондент);
НастройкиXDTO = Неопределено;
ПараметрыПодключения.Свойство("НастройкиXDTO", НастройкиXDTO);
ВерсияФорматаОбмена = "";
Если Не НастройкиXDTO = Неопределено Тогда
Если НастройкиXDTO.ПоддерживаемыеВерсии <> Неопределено
И НастройкиXDTO.ПоддерживаемыеВерсии.Количество() > 0 Тогда
ВерсияФорматаОбмена = ОбменДаннымиXDTOСервер.МаксимальнаяОбщаяВерсияФормата(
Контекст.ИмяПланаОбмена, НастройкиXDTO.ПоддерживаемыеВерсии);
КонецЕсли;
КонецЕсли;
УстановитьПривилегированныйРежим(Истина);
НачатьТранзакцию();
Попытка
Если Контекст.Режим = "НовоеПодключение" Тогда
ИдентификаторКорреспондента = Неопределено;
ПараметрыПодключения.Свойство("ИдентификаторКорреспондента", ИдентификаторКорреспондента);
Если Не ЗначениеЗаполнено(ИдентификаторКорреспондента) Тогда
ИдентификаторКорреспондента = XMLСтрока(Новый УникальныйИдентификатор);
КонецЕсли;
Корреспондент = НовыйУзелОбменаДаннымиXDTO(
Контекст.ИмяПланаОбмена,
Контекст.ИдентификаторНастройки,
ИдентификаторКорреспондента,
ПараметрыПодключения.НаименованиеКорреспондента,
ВерсияФорматаОбмена);
Если Не ОбщегоНазначения.РазделениеВключено() Тогда
ВыполнитьОбновлениеПравилДляОбменаДанными();
КонецЕсли;
ТаблицаОбъектыБазы = ОбменДаннымиXDTOСервер.ПоддерживаемыеОбъектыФормата(
Контекст.ИмяПланаОбмена, "ОтправкаПолучение", Корреспондент);
МенеджерНастройкиXDTO = ОбщегоНазначения.ОбщийМодуль("РегистрыСведений.НастройкиОбменаДаннымиXDTO");
МенеджерНастройкиXDTO.ОбновитьНастройки(
Корреспондент, "ПоддерживаемыеОбъекты", ТаблицаОбъектыБазы);
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("УзелИнформационнойБазы", Корреспондент);
СтруктураЗаписи.Вставить("ИмяПланаОбменаКорреспондента", Контекст.ИмяПланаОбмена);
ОбменДаннымиСлужебный.ОбновитьЗаписьВРегистрСведений(СтруктураЗаписи, "НастройкиОбменаДаннымиXDTO");
ИначеЕсли Контекст.Режим = "РедактированиеПараметровПодключения" Тогда
ДанныеКорреспондента = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Корреспондент, "Код, Наименование, ВерсияФорматаОбмена");
ЗначенияДляОбновления = Новый Структура;
Если ПараметрыПодключения.Свойство("ИдентификаторКорреспондента")
И ЗначениеЗаполнено(ПараметрыПодключения.ИдентификаторКорреспондента)
И СокрЛП(ПараметрыПодключения.ИдентификаторКорреспондента) <> СокрЛП(ДанныеКорреспондента.Код) Тогда
ЗначенияДляОбновления.Вставить("Код", СокрЛП(ПараметрыПодключения.ИдентификаторКорреспондента));
КонецЕсли;
Если ПараметрыПодключения.Свойство("НаименованиеКорреспондента")
И ЗначениеЗаполнено(ПараметрыПодключения.НаименованиеКорреспондента)
И СокрЛП(ПараметрыПодключения.НаименованиеКорреспондента) <> СокрЛП(ДанныеКорреспондента.Наименование) Тогда
ЗначенияДляОбновления.Вставить("Наименование", СокрЛП(ПараметрыПодключения.НаименованиеКорреспондента));
КонецЕсли;
Если ЗначениеЗаполнено(ВерсияФорматаОбмена)
И Не ВерсияФорматаОбмена = ДанныеКорреспондента.ВерсияФорматаОбмена Тогда
ЗначенияДляОбновления.Вставить("ВерсияФорматаОбмена", ВерсияФорматаОбмена);
КонецЕсли;
Если ЗначенияДляОбновления.Количество() > 0 Тогда
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить(ОбщегоНазначения.ИмяТаблицыПоСсылке(Корреспондент));
ЭлементБлокировки.УстановитьЗначение("Ссылка", Корреспондент);
Блокировка.Заблокировать();
ЗаблокироватьДанныеДляРедактирования(Корреспондент);
КорреспондентОбъект = Корреспондент.ПолучитьОбъект();
Для Каждого ЗначениеДляОбновления Из ЗначенияДляОбновления Цикл
КорреспондентОбъект[ЗначениеДляОбновления.Ключ] = ЗначениеДляОбновления.Значение;
КонецЦикла;
КорреспондентОбъект.ОбменДанными.Загрузка = Истина;
КорреспондентОбъект.Записать();
КонецЕсли;
Иначе
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не подходящий режим вызова функции: %1'"), Контекст.Режим);
КонецЕсли;
Если Не НастройкиXDTO = Неопределено Тогда
Если Не НастройкиXDTO.ПоддерживаемыеОбъекты = Неопределено Тогда
МенеджерНастройкиXDTO = ОбщегоНазначения.ОбщийМодуль("РегистрыСведений.НастройкиОбменаДаннымиXDTO");
МенеджерНастройкиXDTO.ОбновитьНастройкиКорреспондента(
Корреспондент, "ПоддерживаемыеОбъекты", НастройкиXDTO.ПоддерживаемыеОбъекты);
КонецЕсли;
КонецЕсли;
МенеджерНастроекТранспорта = ОбщегоНазначения.ОбщийМодуль("РегистрыСведений.НастройкиТранспортаОбменаДанными");
МенеджерНастроекТранспорта.СохранитьНастройкиТранспортаВнешнейСистемы(
Корреспондент, ПараметрыПодключения.НастройкиТранспорта);
Если ПараметрыПодключения.Свойство("РасписаниеСинхронизации")
И ПараметрыПодключения.РасписаниеСинхронизации <> Неопределено Тогда
ИспользоватьРегламентноеЗадание = ?(ПараметрыПодключения.Свойство("ИспользоватьРегламентноеЗадание"),
ПараметрыПодключения.ИспользоватьРегламентноеЗадание, Истина);
Если ОбщегоНазначения.РазделениеВключено() Тогда
Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.ОчередьЗаданий") Тогда
МодульОчередьЗаданий = ОбщегоНазначения.ОбщийМодуль("ОчередьЗаданий");
МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
КлючЗадания = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Обмен данными с внешней системой (%1)'"),
ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Корреспондент, "Код"));
ПараметрыЗадания = Новый Структура;
ПараметрыЗадания.Вставить("ОбластьДанных", МодульРаботаВМоделиСервиса.ЗначениеРазделителяСеанса());
ПараметрыЗадания.Вставить("Использование", ИспользоватьРегламентноеЗадание);
ПараметрыЗадания.Вставить("ИмяМетода", "ОбменДаннымиСервер.ВыполнитьОбменДаннымиСВнешнейСистемой");
ПараметрыЗадания.Вставить("Параметры", Новый Массив);
ПараметрыЗадания.Параметры.Добавить(Корреспондент);
ПараметрыЗадания.Параметры.Добавить(Новый Структура("ВыполнятьЗагрузку, ВыполнятьОтправкуНастроек", Истина, Истина));
ПараметрыЗадания.Параметры.Добавить(Ложь);
ПараметрыЗадания.Вставить("Ключ", КлючЗадания);
ПараметрыЗадания.Вставить("Расписание", ПараметрыПодключения.РасписаниеСинхронизации);
Если Контекст.Режим = "НовоеПодключение" Тогда
МодульОчередьЗаданий.ДобавитьЗадание(ПараметрыЗадания);
ИначеЕсли Контекст.Режим = "РедактированиеПараметровПодключения" Тогда
Отбор = Новый Структура("ОбластьДанных, ИмяМетода, Ключ");
ЗаполнитьЗначенияСвойств(Отбор, ПараметрыЗадания);
ТаблицаЗадания = МодульОчередьЗаданий.ПолучитьЗадания(Отбор);
Если ТаблицаЗадания.Количество() > 0 Тогда
МодульОчередьЗаданий.ИзменитьЗадание(ТаблицаЗадания[0].Идентификатор, ПараметрыЗадания);
Иначе
МодульОчередьЗаданий.ДобавитьЗадание(ПараметрыЗадания);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если Контекст.Режим = "НовоеПодключение" Тогда
Справочники.СценарииОбменовДанными.СоздатьСценарий(
Корреспондент, ПараметрыПодключения.РасписаниеСинхронизации, ИспользоватьРегламентноеЗадание);
ИначеЕсли Контекст.Режим = "РедактированиеПараметровПодключения" Тогда
Запрос = Новый Запрос(
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| СценарииОбменовДанными.Ссылка КАК Сценарий,
| СценарииОбменовДанными.Ссылка.ИспользоватьРегламентноеЗадание КАК ИспользоватьРегламентноеЗадание
|ИЗ
| Справочник.СценарииОбменовДанными КАК СценарииОбменовДанными
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.СценарииОбменовДанными.НастройкиОбмена КАК СценарииОбменовДаннымиНастройкиОбмена
| ПО (СценарииОбменовДаннымиНастройкиОбмена.Ссылка = СценарииОбменовДанными.Ссылка)
|ГДЕ
| СценарииОбменовДаннымиНастройкиОбмена.УзелИнформационнойБазы = &УзелИнформационнойБазы
| И НЕ СценарииОбменовДанными.ПометкаУдаления");
Запрос.УстановитьПараметр("УзелИнформационнойБазы", Корреспондент);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
СценарийОбъект = Выборка.Сценарий.ПолучитьОбъект(); // СправочникОбъект.СценарииОбменовДанными
Отказ = Ложь;
Справочники.СценарииОбменовДанными.ОбновитьДанныеРегламентногоЗадания(
Отказ, ПараметрыПодключения.РасписаниеСинхронизации, СценарийОбъект);
Если Не Отказ Тогда
СценарийОбъект.ИспользоватьРегламентноеЗадание = ИспользоватьРегламентноеЗадание;
СценарийОбъект.Записать();
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
Если Контекст.Режим = "НовоеПодключение" Тогда
// Отправка формализованных настроек XDTO.
ПараметрыОбмена = Новый Структура;
ПараметрыОбмена.Вставить("ВыполнятьЗагрузку", Ложь);
ПараметрыОбмена.Вставить("ВыполнятьОтправкуНастроек", Истина);
Отказ = Ложь;
СообщениеОбОшибке = "";
Попытка
ВыполнитьОбменДаннымиСВнешнейСистемой(Корреспондент, ПараметрыОбмена, Отказ);
Исключение
Отказ = Истина;
СообщениеОбОшибке = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииСозданиеОбменаДанными(),
УровеньЖурналаРегистрации.Ошибка, , , СообщениеОбОшибке);
КонецПопытки;
Если Отказ Тогда
НастройкиУдаления = Новый Структура;
НастройкиУдаления.Вставить("УзелОбмена", Корреспондент);
НастройкиУдаления.Вставить("УдалитьНастройкуВКорреспонденте", Истина);
ПараметрыПроцедуры = Новый Структура;
ПараметрыПроцедуры.Вставить("НастройкиУдаления", НастройкиУдаления);
АдресРезультата = "";
Попытка
МодульПомощникСозданияОбменаДанными().УдалитьНастройкуСинхронизации(ПараметрыПроцедуры, АдресРезультата);
Исключение
ВызватьИсключение;
КонецПопытки;
ВызватьИсключение СообщениеОбОшибке;
КонецЕсли;
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("УзелОбмена", Корреспондент);
Результат.Вставить("ИдентификаторКорреспондента",
ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Корреспондент, "Код"));
КонецПроцедуры
// Заполняет структуру сохраненных параметров подключения к внешней системе.
//
// Параметры:
// Контекст - Структура - контекст выполнения операции:
// * Корреспондент - ПланОбменаСсылка - узел обмена, соответствующий корреспонденту.
// ПараметрыПодключения - Структура - структура параметров подключения:
// * ИдентификаторКорреспондента - Строка - строка длиной 36 символов, уникальный идентификатор корреспондента.
// * НаименованиеКорреспондента - Строка - название корреспондента, как он отображается
// в списке настроенных синхронизаций.
// * НастройкиТранспорта - Произвольный - сохраненные настройки транспорта сообщений обмена внешней системы.
// * РасписаниеСинхронизации - РасписаниеРегламентногоЗадания - расписание автоматического запуска обмена.
// * НастройкиXDTO - Структура
// - Неопределено - структура настроек XDTO корреспондента:
// ** ПоддерживаемыеВерсии - Массив - перечень поддерживаемых корреспондентом версий формата.
// ** ПоддерживаемыеОбъекты - см. ОбменДаннымиXDTOСервер.ПоддерживаемыеОбъектыФормата.
//
Процедура ПриПолученииНастроекПодключенияВнешнейСистемы(Контекст, ПараметрыПодключения) Экспорт
УстановитьПривилегированныйРежим(Истина);
ДанныеУзлаОбмена = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Контекст.Корреспондент, "Код, Наименование");
ПараметрыПодключения = Новый Структура;
ПараметрыПодключения.Вставить("ИдентификаторКорреспондента", ДанныеУзлаОбмена.Код);
ПараметрыПодключения.Вставить("НаименованиеКорреспондента", ДанныеУзлаОбмена.Наименование);
ПараметрыПодключения.Вставить("НастройкиТранспорта",
РегистрыСведений.НастройкиТранспортаОбменаДанными.НастройкиТранспортаВнешнейСистемы(Контекст.Корреспондент));
ПараметрыПодключения.Вставить("РасписаниеСинхронизации");
ПараметрыПодключения.Вставить("НастройкиXDTO", Новый Структура);
ПараметрыПодключения.НастройкиXDTO.Вставить("ПоддерживаемыеВерсии",
РегистрыСведений.НастройкиОбменаДаннымиXDTO.ЗначениеНастройкиКорреспондента(Контекст.Корреспондент, "ПоддерживаемыеВерсии"));
ПараметрыПодключения.НастройкиXDTO.Вставить("ПоддерживаемыеОбъекты",
РегистрыСведений.НастройкиОбменаДаннымиXDTO.ЗначениеНастройкиКорреспондента(Контекст.Корреспондент, "ПоддерживаемыеОбъекты"));
КонецПроцедуры
// Таблица настроек транспорта обмена для всех настроенных обменов данными с внешними системами.
//
// Возвращаемое значение:
// ТаблицаЗначений:
// * Корреспондент - ПланОбменаСсылка - узел обмена, соответствующий корреспонденту.
// * НастройкиТранспорта - Произвольный - сохраненные настройки транспорта сообщений обмена внешней системы.
//
Функция ВсеНастройкиТранспортаОбменаСВнешнимиСистемами() Экспорт
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Корреспондент");
Результат.Колонки.Добавить("НастройкиТранспорта");
ОбщийТекстЗапроса = "";
ПланыОбменаБСП = ОбменДаннымиПовтИсп.ПланыОбменаБСП();
Для Каждого ПланОбмена Из ПланыОбменаБСП Цикл
Если Не ОбменДаннымиПовтИсп.ЭтоПланОбменаXDTO(ПланОбмена) Тогда
Продолжить;
КонецЕсли;
ТекстЗапроса =
"ВЫБРАТЬ
| Т.Ссылка КАК Корреспондент,
| НастройкиТранспортаОбменаДанными.ПараметрыПодключенияВнешнейСистемы КАК ПараметрыПодключенияВнешнейСистемы
|ИЗ
| #ТаблицаПланаОбмена КАК Т
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиТранспортаОбменаДанными КАК НастройкиТранспортаОбменаДанными
| ПО (НастройкиТранспортаОбменаДанными.Корреспондент = Т.Ссылка)
|ГДЕ
| НЕ Т.ЭтотУзел
| И НастройкиТранспортаОбменаДанными.ВидТранспортаСообщенийОбменаПоУмолчанию = ЗНАЧЕНИЕ(Перечисление.ВидыТранспортаСообщенийОбмена.ВнешняяСистема)";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ТаблицаПланаОбмена", "ПланОбмена." + ПланОбмена);
Если Не ПустаяСтрока(ОбщийТекстЗапроса) Тогда
ОбщийТекстЗапроса = ОбщийТекстЗапроса + "
|
|ОБЪЕДИНИТЬ ВСЕ
|
|";
КонецЕсли;
ОбщийТекстЗапроса = ОбщийТекстЗапроса + ТекстЗапроса;
КонецЦикла;
Если ПустаяСтрока(ОбщийТекстЗапроса) Тогда
Возврат Результат;
КонецЕсли;
Запрос = Новый Запрос(ОбщийТекстЗапроса);
УстановитьПривилегированныйРежим(Истина);
ТаблицаНастройки = Запрос.Выполнить().Выгрузить();
Для Каждого СтрокаНастройки Из ТаблицаНастройки Цикл
СтрокаРезультат = Результат.Добавить();
СтрокаРезультат.Корреспондент = СтрокаНастройки.Корреспондент;
СтрокаРезультат.НастройкиТранспорта = СтрокаНастройки.ПараметрыПодключенияВнешнейСистемы.Получить();
КонецЦикла;
Возврат Результат;
КонецФункции
#КонецОбласти
#Область СохранениеНастроекСинхронизацииДанных
// Начинает сохранение настроек синхронизации данных в длительной операции.
// При сохранении настроек выполняется перенос на узел обмена переданных данных заполнения,
// и устанавливается признак, что настройка синхронизации завершена.
// Рекомендуется использовать в помощнике настройки синхронизации данных.
//
// Параметры:
// НастройкиСинхронизации - Структура - структура параметров для сохранения настроек:
// * УзелОбмена - ПланОбменаСсылка - узел плана обмена, для которого выполняется сохранение настроек синхронизации.
// * ДанныеЗаполнения - Структура - произвольная структура для заполнения настроек на узле.
// Будет передана в алгоритм "ПриСохраненииНастроекСинхронизацииДанных" (при его наличии).
// ПараметрыОбработчика - Структура - исходящий служебный параметр. Зарезервирован для внутреннего использования.
// Применяется для отслеживания состояния длительной операции.
// На вход следует передавать реквизит формы типа "Произвольный",
// не используемый ни в каких других операциях.
// ПродолжитьОжидание - Булево - исходящий параметр. Истина, если сохранение настройки запущено в длительной операции.
// Для отслеживания состояния в этом случае следует использовать процедуру
// ОбменДаннымиСервер.ПриОжиданииСохраненияНастроекСинхронизации.
//
Процедура ПриНачалеСохраненияНастроекСинхронизации(НастройкиСинхронизации, ПараметрыОбработчика, ПродолжитьОжидание = Истина) Экспорт
МодульПомощникСозданияОбменаДанными().ПриНачалеСохраненияНастроекСинхронизации(НастройкиСинхронизации,
ПараметрыОбработчика,
ПродолжитьОжидание);
КонецПроцедуры
// Используется при ожидании завершения настройки синхронизации данных.
// Проверяет статус выполнения длительной операции по сохранению настройки, и возвращает признак
// необходимости продолжения ожидания, либо сообщает, что операция сохранения настройки завершена.
//
// Параметры:
// ПараметрыОбработчика - Структура - входящий/исходящий служебный параметр. Зарезервирован для внутреннего использования.
// Применяется для отслеживания состояния длительной операции.
// На вход следует передавать реквизит формы типа "Произвольный",
// который был использован при запуске настройки синхронизации
// вызовом метода ОбменДаннымиСервер.ПриНачалеСохраненияНастроекСинхронизации.
// ПродолжитьОжидание - Булево - исходящий параметр. Истина, если необходимо продолжить ожидание завершения
// операции сохранения настройки синхронизации, Ложь - если настройка
// синхронизации завершена.
//
Процедура ПриОжиданииСохраненияНастроекСинхронизации(ПараметрыОбработчика, ПродолжитьОжидание) Экспорт
МодульПомощникСозданияОбменаДанными().ПриОжиданииСохраненияНастроекСинхронизации(ПараметрыОбработчика,
ПродолжитьОжидание);
КонецПроцедуры
// Получает статус завершения операции настройки синхронизации. Вызывается, когда процедуры
// ОбменДаннымиСервер.ПриНачалеСохраненияНастроекСинхронизации или ОбменДаннымиСервер.ПриОжиданииСохраненияНастроекСинхронизации
// устанавливают флаг ПродолжитьОжидание в значение Ложь.
//
// Параметры:
// ПараметрыОбработчика - Структура - входящий служебный параметр. Зарезервирован для внутреннего использования.
// Применяется для получения состояния длительной операции.
// На вход следует передавать реквизит формы типа "Произвольный",
// который был использован при запуске настройки синхронизации
// вызовом метода ОбменДаннымиСервер.ПриНачалеСохраненияНастроекСинхронизации.
// СтатусЗавершения - Структура - исходящий параметр, возвращает состояние завершения длительной операции:
// * Отказ - Булево - Истина, если при запуске, или в ходе выполнения длительной операции произошла ошибка.
// * СообщениеОбОшибке - Строка - текст ошибки, произошедшей при выполнении длительной операции, если Отказ = Истина.
// * Результат - Структура - состояние сохранения настройки синхронизации:
// ** НастройкиСохранены - Булево - Истина, если настройка синхронизации успешно завершена.
// ** СообщениеОбОшибке - Строка - текст ошибки, возникшей непосредственно в транзакции сохранения настройки синхронизации.
//
Процедура ПриЗавершенииСохраненияНастроекСинхронизации(ПараметрыОбработчика, СтатусЗавершения) Экспорт
МодульПомощникСозданияОбменаДанными().ПриЗавершенииСохраненияНастроекСинхронизации(ПараметрыОбработчика,
СтатусЗавершения);
КонецПроцедуры
#КонецОбласти
#Область ОбщиеНастройкиУзловИнформационныхБаз
// Устанавливает признак завершения настройки синхронизации данных.
//
// Параметры:
// УзелОбмена - ПланОбменаСсылка - узел обмена, для которого необходимо установить признак.
//
Процедура ЗавершитьНастройкуСинхронизацииДанных(УзелОбмена) Экспорт
УстановитьПривилегированныйРежим(Истина);
Если УзелОбмена = ПланыОбмена[ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелОбмена)].ЭтотУзел() Тогда
Возврат;
КонецЕсли;
НачатьТранзакцию();
Попытка
Если Не НастройкаСинхронизацииЗавершена(УзелОбмена) Тогда
// Изменения, зарегистрированные до момента завершения настройки синхронизации,
// являются некорректными, т.к. еще не были установлены отборы.
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена);
// Необходимо сбросить ранее установленный признак регистрации изменений для повторной отправки сообщения в МС.
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса") Тогда
МенеджерКонстанты = ОбщегоНазначения.ОбщийМодуль("Константы.ЗарегистрированыИзмененияДанных");
МенеджерКонстанты.Установить(Ложь);
КонецЕсли;
КонецЕсли;
РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.УстановитьПризнакНастройкаЗавершена(УзелОбмена);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
// Возвращает признак завершения настройки синхронизации для узла обмена.
//
// Параметры:
// УзелОбмена - ПланОбменаСсылка - узел обмена, для которого необходимо получить признак.
//
// Возвращаемое значение:
// Булево - Истина, если настройка синхронизации для переданного узла завершена.
//
Функция НастройкаСинхронизацииЗавершена(УзелОбмена) Экспорт
Если ОбменДаннымиПовтИсп.ЭтоУзелОбменаСообщениями(УзелОбмена) Тогда
Возврат Истина;
Иначе
УстановитьПривилегированныйРежим(Истина);
Возврат РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.НастройкаЗавершена(УзелОбмена);
КонецЕсли;
КонецФункции
// Устанавливает признак успешного создания начального образа узла РИБ.
//
// Параметры:
// УзелОбмена - ПланОбменаСсылка - узел обмена, для которого необходимо установить признак.
//
Процедура ЗавершитьСозданиеНачальногоОбраза(УзелОбмена) Экспорт
РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.УстановитьПризнакНачальныйОбразСоздан(УзелОбмена);
КонецПроцедуры
#КонецОбласти
#Область ДляВызоваИзДругихПодсистем
// СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса
// Возвращает ссылку на узел плана обмена, найденный по его коду.
// Если узел не найден, возвращается Неопределено.
//
// Параметры:
// ИмяПланаОбмена - Строка - имя плана обмена, как оно задано в конфигураторе.
// КодУзла - Строка - код узла плана обмена.
//
// Возвращаемое значение:
// ПланОбменаСсылка - ссылка на найденный узел плана обмена.
// Неопределено - в случае, если узел плана обмена не найден.
//
Функция УзелПланаОбменаПоКоду(ИмяПланаОбмена, КодУзла) Экспорт
СсылкаУзел = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодУзла);
Если Не ЗначениеЗаполнено(СсылкаУзел) Тогда
Возврат Неопределено;
КонецЕсли;
Возврат СсылкаУзел;
КонецФункции
// Возвращает Истина, если сеанс запущен в автономном рабочем месте.
// Возвращаемое значение:
// Булево - признак запуска в автономном рабочем месте.
//
Функция ЭтоАвтономноеРабочееМесто() Экспорт
Возврат ОбменДаннымиПовтИсп.РежимАвтономногоРабочегоМеста();
КонецФункции
// Определяет, является ли переданный узел плана обмена автономным рабочим местом.
//
// Параметры:
// УзелИнформационнойБазы - ПланОбменаСсылка - проверяемый узел.
//
// Возвращаемое значение:
// Булево - признак того что переданный узел является автономным рабочим местом.
//
Функция ЭтоУзелАвтономногоРабочегоМеста(Знач УзелИнформационнойБазы) Экспорт
Возврат ОбменДаннымиПовтИсп.ЭтоУзелАвтономногоРабочегоМеста(УзелИнформационнойБазы);
КонецФункции
// Удаляет набор записей в регистре по переданным значениям структуры.
//
// Параметры:
// СтруктураЗаписи - Структура - структура, по значениям которой необходимо удалить набор записей.
//
Процедура УдалитьЗаписиСостоянияОбменовДанными(СтруктураЗаписи) Экспорт
ОбменДаннымиСлужебный.УдалитьНаборЗаписейВРегистреСведений(СтруктураЗаписи, "СостоянияОбменовДанными");
КонецПроцедуры
// Удаляет набор записей в регистре по переданным значениям структуры.
//
// Параметры:
// СтруктураЗаписи - Структура - структура, по значениям которой необходимо удалить набор записей.
//
Процедура УдалитьЗаписиСостоянияУспешныхОбменовДанными(СтруктураЗаписи) Экспорт
ОбменДаннымиСлужебный.УдалитьНаборЗаписейВРегистреСведений(СтруктураЗаписи, "СостоянияУспешныхОбменовДанными");
КонецПроцедуры
// Удаляет поставляемые правила для плана обмена (очищает данные в регистре).
//
// Параметры:
// ИмяПланаОбмена - Строка - имя плана обмена, для которого удаляются правила.
//
Процедура УдалитьПоставляемыеПравила(ИмяПланаОбмена) Экспорт
РегистрыСведений.ПравилаДляОбменаДанными.УдалитьПоставляемыеПравила(ИмяПланаОбмена);
КонецПроцедуры
// Загружает поставляемые правила для плана обмена.
//
// Параметры:
// ИмяПланаОбмена - Строка - имя плана обмена, для которого загружаются правила.
// ИмяФайлаПравил - Строка - полное имя файла правил обмена (*.zip).
//
Процедура ЗагрузитьПоставляемыеПравила(ИмяПланаОбмена, ИмяФайлаПравил) Экспорт
РегистрыСведений.ПравилаДляОбменаДанными.ЗагрузитьПоставляемыеПравила(ИмяПланаОбмена, ИмяФайлаПравил);
КонецПроцедуры
// Возвращает идентификатор настройки обмена, соответствующий конкретному корреспонденту.
//
// Параметры:
// ИмяПланаОбмена - Строка - имя плана обмена, который используется для настройки обмена.
// ВерсияКорреспондента - Строка - номер версии корреспондента, с которым настраивается обмен.
// ИмяКорреспондента - Строка - имя корреспондента (см. функцию ИмяКонфигурацииИсточника
// на стороне конфигурации-корреспондента).
//
// Возвращаемое значение:
// Массив из Строка - массив строк с идентификаторами настройки для корреспондента.
//
Функция ВариантыНастроекОбменаДляКорреспондента(ИмяПланаОбмена, ВерсияКорреспондента, ИмяКорреспондента) Экспорт
НастройкиПланаОбмена = НастройкиПланаОбмена(ИмяПланаОбмена, ВерсияКорреспондента, ИмяКорреспондента, Истина);
Если НастройкиПланаОбмена.ВариантыНастроекОбмена.Количество() = 0 Тогда
Возврат Новый Массив;
Иначе
Возврат НастройкиПланаОбмена.ВариантыНастроекОбмена.ВыгрузитьКолонку("ИдентификаторНастройки");
КонецЕсли;
КонецФункции
// Возвращает идентификатор настройки обмена, соответствующий конкретному корреспонденту.
//
// Параметры:
// ИмяПланаОбмена - Строка - имя плана обмена, который используется для настройки обмена.
// ИмяКорреспондента - Строка - имя корреспондента (см. функцию ИмяКонфигурацииИсточника
// на стороне конфигурации-корреспондента).
//
// Возвращаемое значение:
// Строка - идентификатор настройки обмена.
//
Функция ВариантНастройкиОбменаДляКорреспондента(ИмяПланаОбмена, ИмяКорреспондента) Экспорт
НастройкиПланаОбмена = НастройкиПланаОбмена(ИмяПланаОбмена, "", ИмяКорреспондента, Истина);
Если НастройкиПланаОбмена.ВариантыНастроекОбмена.Количество() = 0 Тогда
Возврат "";
Иначе
Возврат НастройкиПланаОбмена.ВариантыНастроекОбмена[0].ИдентификаторНастройки;
КонецЕсли;
КонецФункции
// Конец СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса
#КонецОбласти
#Область УстаревшиеПроцедурыИФункции
// Устарела. Выполняет добавление информации об установленном в константе количестве элементов в транзакции
// в структуру, содержащую параметры транспорта сообщений обмена.
//
// Параметры:
// Результат - Структура - содержит параметры транспорта сообщений обмена.
//
Процедура ДополнитьНастройкиТранспортаКоличествомЭлементовВТранзакции(Результат) Экспорт
ОбменДаннымиСлужебный.ДополнитьНастройкиТранспортаКоличествомЭлементовВТранзакции(Результат);
КонецПроцедуры
// Устарела. Возвращает номер области по коду узла плана обмена (обмен сообщениями).
//
// Параметры:
// КодУзла - Строка - код узла плана обмена.
//
// Возвращаемое значение:
// Число - номер области.
//
Функция НомерОбластиИзКодаУзлаПланаОбмена(Знач КодУзла) Экспорт
Возврат ОбменДаннымиСлужебный.НомерОбластиИзКодаУзлаПланаОбмена(КодУзла);
КонецФункции
// Устарела. Возвращает данные первой записи результата запроса в виде структуры.
//
// Параметры:
// РезультатЗапроса - РезультатЗапроса - результат запроса, содержащий данные для обработки.
//
// Возвращаемое значение:
// Структура - структура с результатом.
//
Функция РезультатЗапросаВСтруктуру(Знач РезультатЗапроса) Экспорт
Возврат ОбменДаннымиСлужебный.РезультатЗапросаВСтруктуру(РезультатЗапроса);
КонецФункции
// Устарела. Следует использовать функцию ЗначениеНастройкиПланаОбмена,
// установив параметру ИмяПараметра одно из следующих значений:
// - ЗаголовокКомандыДляСозданияНовогоОбменаДанными;
// - ЗаголовокПомощникаСозданияОбмена;
// - ЗаголовокУзлаПланаОбмена;
// - НаименованиеКонфигурацииКорреспондента.
//
// Возвращает, если оно задано, переопределяемое имя плана обмена,
// в зависимости от предопределенной настройки обмена.
// Параметры:
// УзелПланаОбмена - ПланОбменаСсылка - узел плана обмена, для которого необходимо получить переопределяемое
// имя.
// ИмяПараметраСИменемУзла - Строка - имя параметра, в настройках по умолчанию, из которого необходимо получить имя узла.
// ВариантНастройки - Строка - вариант настройки обмена.
//
// Возвращаемое значение:
// Строка - переопределяемое имя плана обмена как оно заданно в конфигураторе.
//
Функция ПереопределяемоеИмяУзлаПланаОбмена(Знач УзелПланаОбмена, ИмяПараметраСИменемУзла, ВариантНастройки = "") Экспорт
УстановитьПривилегированныйРежим(Истина);
ПредставлениеПланаОбмена = ЗначениеНастройкиПланаОбмена(
УзелПланаОбмена.Метаданные().Имя,
ИмяПараметраСИменемУзла,
ВариантНастройки);
УстановитьПривилегированныйРежим(Ложь);
Возврат ПредставлениеПланаОбмена;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныйПрограммныйИнтерфейс
#Область РазличногоНазначения
// Выполняет загрузку приоритетных данных, полученных из главного узла РИБ.
Процедура ЗагрузитьПриоритетныеДанныеВПодчиненныйУзелРИБ(Отказ = Ложь) Экспорт
Если ОбменДаннымиСлужебный.РежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском(
"ПропуститьЗагрузкуСообщенияОбменаДаннымиПередЗапуском") Тогда
Возврат;
КонецЕсли;
Если ОбменДаннымиСлужебный.РежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском(
"ПропуститьЗагрузкуПриоритетныхДанныхПередЗапуском") Тогда
Возврат;
КонецЕсли;
УстановитьПривилегированныйРежим(Истина);
УстановитьРежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском("ЗагрузкаРазрешена", Истина);
УстановитьПривилегированныйРежим(Ложь);
Попытка
Если НЕ ПолучитьФункциональнуюОпцию("ИспользоватьСинхронизациюДанных") Тогда
Если ОбщегоНазначения.РазделениеВключено() Тогда
ИспользоватьСинхронизациюДанных = Константы.ИспользоватьСинхронизациюДанных.СоздатьМенеджерЗначения();
ИспользоватьСинхронизациюДанных.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов");
ИспользоватьСинхронизациюДанных.ОбменДанными.Загрузка = Истина;
ИспользоватьСинхронизациюДанных.Значение = Истина;
ИспользоватьСинхронизациюДанных.Записать();
Иначе
Если ПолучитьИспользуемыеПланыОбмена().Количество() > 0 Тогда
ИспользоватьСинхронизациюДанных = Константы.ИспользоватьСинхронизациюДанных.СоздатьМенеджерЗначения();
ИспользоватьСинхронизациюДанных.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов");
ИспользоватьСинхронизациюДанных.ОбменДанными.Загрузка = Истина;
ИспользоватьСинхронизациюДанных.Значение = Истина;
ИспользоватьСинхронизациюДанных.Записать();
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПолучитьФункциональнуюОпцию("ИспользоватьСинхронизациюДанных") Тогда
УзелИнформационнойБазы = ГлавныйУзел();
Если УзелИнформационнойБазы <> Неопределено Тогда
РегистрыСведений.НастройкиТранспортаОбменаДанными.ПеренестиНастройкиТранспортаОбменаДаннымиКорреспондента(УзелИнформационнойБазы);
ВидТранспорта = РегистрыСведений.НастройкиТранспортаОбменаДанными.ВидТранспортаСообщенийОбменаПоУмолчанию(УзелИнформационнойБазы);
ИмяПараметра = "СтандартныеПодсистемы.ОбменДанными.ПравилаРегистрации."
+ ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелИнформационнойБазы);
ПравилаРегистрацииОбновлены = СтандартныеПодсистемыСервер.ПараметрРаботыПрограммы(ИмяПараметра);
Если ПравилаРегистрацииОбновлены = Неопределено Тогда
ВыполнитьОбновлениеПравилДляОбменаДанными();
КонецЕсли;
ПравилаРегистрацииОбновлены = СтандартныеПодсистемыСервер.ПараметрРаботыПрограммы(ИмяПараметра);
Если ПравилаРегистрацииОбновлены = Неопределено Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не выполнено обновление кэша правил регистрации данных для плана обмена ""%1""'"),
ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелИнформационнойБазы));
КонецЕсли;
// Загрузка только параметров работы программы.
ПараметрыОбмена = ПараметрыОбмена();
ПараметрыОбмена.ВидТранспортаСообщенийОбмена = ВидТранспорта;
ПараметрыОбмена.ВыполнятьЗагрузку = Истина;
ПараметрыОбмена.ВыполнятьВыгрузку = Ложь;
ПараметрыОбмена.ТолькоПараметры = Истина;
ВыполнитьОбменДаннымиДляУзлаИнформационнойБазы(УзелИнформационнойБазы, ПараметрыОбмена, Отказ);
КонецЕсли;
КонецЕсли;
Исключение
УстановитьПривилегированныйРежим(Истина);
УстановитьРежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском("ЗагрузкаРазрешена", Ложь);
УстановитьПривилегированныйРежим(Ложь);
ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
ЗаписьЖурналаРегистрации(
НСтр("ru = 'Обмен данными.Загрузка приоритетных данных'", ОбщегоНазначения.КодОсновногоЯзыка()),
УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение
НСтр("ru = 'Ошибка загрузки приоритетных данных из сообщения обмена.
|См. подробности в журнале регистрации.'");
КонецПопытки;
УстановитьПривилегированныйРежим(Истина);
УстановитьРежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском("ЗагрузкаРазрешена", Ложь);
УстановитьПривилегированныйРежим(Ложь);
Если Отказ Тогда
Если КонфигурацияИзменена() Тогда
ВызватьИсключение
НСтр("ru = 'Загружены изменения программы, полученные из главного узла.
|Завершите работу программы. Откройте программу в конфигураторе
|и выполните команду ""Обновить конфигурацию базы данных (F7)"".
|
|После этого запустите программу.'");
КонецЕсли;
ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
ВызватьИсключение
НСтр("ru = 'Ошибка загрузки приоритетных данных из сообщения обмена.
|См. подробности в журнале регистрации.'");
КонецЕсли;
КонецПроцедуры
// Устанавливает признак повторения загрузки при ошибке загрузки или обновления.
// Очищает хранилище сообщения обмена, полученного из главного узла РИБ.
//
Процедура ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском() Экспорт
ОчиститьСообщениеОбменаДаннымиИзГлавногоУзла();
Константы.ПовторитьЗагрузкуСообщенияОбменаДаннымиПередЗапуском.Установить(Истина);
КонецПроцедуры
// Выполняет инициализацию XML файла, для записи информации об объектах
// отмеченных к обработке обновления, для передачи их в подчиненный узел РИБ.
//
Процедура ИнициализироватьФайлСДаннымиОбновления(Параметры) Экспорт
ФайлДляЗаписиXML = Неопределено;
ИмяФайлаСИзменениями = Неопределено;
Если СтандартныеПодсистемыПовтИсп.ИспользуетсяРИБ("СФильтром") Тогда
ИмяФайлаСИзменениями = ПолноеИмяФайлаДанныхОтложенногоОбновления();
ФайлДляЗаписиXML = Новый ЗаписьFastInfoset;
ФайлДляЗаписиXML.ОткрытьФайл(ИмяФайлаСИзменениями);
ФайлДляЗаписиXML.ЗаписатьОбъявлениеXML();
ФайлДляЗаписиXML.ЗаписатьНачалоЭлемента("Objects");
КонецЕсли;
Параметры.ИмяФайлаСИзменениями = ИмяФайлаСИзменениями;
Параметры.ЗаписьИзмененийДляПодчиненногоУзлаРИБСФильтрами = ФайлДляЗаписиXML;
КонецПроцедуры
// Выполняет инициализацию XML файла, для записи информации об объектах.
//
Процедура ЗаписатьДанныеДляОбновленияВФайл(Параметры, Данные, ВидДанных, ПолноеИмяОбъекта = "") Экспорт
Если Не СтандартныеПодсистемыПовтИсп.ИспользуетсяРИБ("СФильтром") Тогда
Возврат;
КонецЕсли;
Если Параметры.ЗаписьИзмененийДляПодчиненногоУзлаРИБСФильтрами = Неопределено Тогда
ТекстИсключения = НСтр("ru = 'В обработчике неправильно организована работа с параметрами регистрации данных к обработке.'");
ВызватьИсключение ТекстИсключения;
КонецЕсли;
ЗаписьXML = Параметры.ЗаписьИзмененийДляПодчиненногоУзлаРИБСФильтрами;
ЗаписьXML.ЗаписатьНачалоЭлемента("Object");
ЗаписьXML.ЗаписатьАтрибут("Queue", Строка(Параметры.Очередь));
Если Не ЗначениеЗаполнено(ПолноеИмяОбъекта) Тогда
ПолноеИмяОбъекта = Данные.Метаданные().ПолноеИмя();
КонецЕсли;
ЗаписьXML.ЗаписатьАтрибут("Type", ПолноеИмяОбъекта);
Если ВРег(ВидДанных) = "ССЫЛКА" Тогда
ЗаписьXML.ЗаписатьАтрибут("Ref", XMLСтрока(Данные.Ссылка));
Иначе
Если ВРег(ВидДанных) = "НЕЗАВИСИМЫЙРЕГИСТР" Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("Filter");
Для Каждого ЭлементОтбора Из Данные.Отбор Цикл
Если ЗначениеЗаполнено(ЭлементОтбора.Значение) Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента(ЭлементОтбора.Имя);
ТипДанных = ТипЗнч(ЭлементОтбора.Значение);
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипДанных);
Если ОбъектМетаданных <> Неопределено Тогда
ЗаписьXML.ЗаписатьАтрибут("Type", ОбъектМетаданных.ПолноеИмя());
ИначеЕсли ТипДанных = Тип("УникальныйИдентификатор") Тогда
ЗаписьXML.ЗаписатьАтрибут("Type", "УникальныйИдентификатор");
Иначе
ЗаписьXML.ЗаписатьАтрибут("Type", Строка(ТипДанных));
КонецЕсли;
ЗаписьXML.ЗаписатьАтрибут("Val", XMLСтрока(ЭлементОтбора.Значение));
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЕсли;
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента();
Иначе
Регистратор = Данные.Отбор.Регистратор.Значение;
ЗаписьXML.ЗаписатьАтрибут("FilterType", Строка(Регистратор.Метаданные().ПолноеИмя()));
ЗаписьXML.ЗаписатьАтрибут("Ref", XMLСтрока(Регистратор.Ссылка));
КонецЕсли;
КонецЕсли;
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецПроцедуры
// Выполняет регистрацию в подчиненном узле РИБ с фильтрами
// объектов зарегистрированных для отложенного обновления в главном узле РИБ.
//
Процедура ОбработатьДанныеДляОбновленияВПодчиненномУзле(Знач ЗначениеКонстанты) Экспорт
Если Не СтандартныеПодсистемыПовтИсп.ИспользуетсяРИБ("СФильтром")
Или Не ЭтоПодчиненныйУзелРИБ()
Или НазначениеПланаОбмена(ГлавныйУзел().Метаданные().Имя) <> "РИБСФильтром" Тогда
Возврат;
КонецЕсли;
МассивЗначений = ЗначениеКонстанты.Значение.Получить();
Если ТипЗнч(МассивЗначений) <> Тип("Массив") Тогда
Возврат;
КонецЕсли;
Для Каждого ХранилищеЗначений Из МассивЗначений Цикл
ИмяФайла = ПолноеИмяФайлаДанныхОтложенногоОбновления();
Если ХранилищеЗначений = Неопределено Тогда
Возврат;
КонецЕсли;
ДвоичныеДанные = ХранилищеЗначений.Получить(); // ДвоичныеДанные
Если ДвоичныеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
Если ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОбновлениеИнформационнойБазы.Ссылка КАК Узел
|ИЗ
| ПланОбмена.ОбновлениеИнформационнойБазы КАК ОбновлениеИнформационнойБазы
|ГДЕ
| НЕ ОбновлениеИнформационнойБазы.ЭтотУзел";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ПланыОбмена.УдалитьРегистрациюИзменений(Выборка.Узел);
КонецЦикла;
КонецЕсли;
ДвоичныеДанные.Записать(ИмяФайла);
ЧтениеXML = Новый ЧтениеFastInfoset;
ЧтениеXML.ОткрытьФайл(ИмяФайла);
ПараметрыОбработчикаСтруктура = ОбновлениеИнформационнойБазы.ОсновныеПараметрыОтметкиКОбработке();
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.Имя = "Object"
И ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ПараметрыОбработчикаСтруктура.Очередь = Число(ЧтениеXML.ЗначениеАтрибута("Queue"));
ПолноеИмяОбъектаМетаданных = СокрЛП(ЧтениеXML.ЗначениеАтрибута("Type"));
ТипОбъектаМетаданных = Метаданные.НайтиПоПолномуИмени(ПолноеИмяОбъектаМетаданных);
МенеджерОбъекта = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмяОбъектаМетаданных);
ЭтоСсылочныйТипОбъекта = ОбщегоНазначения.ЭтоОбъектСсылочногоТипа(ТипОбъектаМетаданных);
Если ЭтоСсылочныйТипОбъекта Тогда
ОбъектКОбработке = МенеджерОбъекта.ПолучитьСсылку(Новый УникальныйИдентификатор(ЧтениеXML.ЗначениеАтрибута("Ref")));
Иначе
ОбъектКОбработке = МенеджерОбъекта.СоздатьНаборЗаписей();
Если ОбщегоНазначения.ЭтоРегистрСведений(ТипОбъектаМетаданных)
И ТипОбъектаМетаданных.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый Тогда
ЧтениеXML.Прочитать();
Если ЧтениеXML.Имя = "Filter"
И ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
ЧтениеОтбора = Истина;
Пока ЧтениеОтбора Цикл
ЧтениеXML.Прочитать();
Если ЧтениеXML.Имя = "Filter" И ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
ЧтениеОтбора = Ложь;
Продолжить;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
Продолжить;
Иначе
ЗначениеОтбора = ЧтениеXML.ЗначениеАтрибута("Val");
Если ЗначениеЗаполнено(ЗначениеОтбора) Тогда
ИмяОтбора = ЧтениеXML.Имя;
ТипЗначенияОтбора = ЧтениеXML.ЗначениеАтрибута("Type");
МетаданныеЗначенияОтбора = Метаданные.НайтиПоПолномуИмени(ТипЗначенияОтбора);
ЭлементОтбора = ОбъектКОбработке.Отбор.Найти(ИмяОтбора);
Если ЭлементОтбора <> Неопределено Тогда
Если МетаданныеЗначенияОтбора <> Неопределено Тогда
МенеджерОбъектаОтбора = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ТипЗначенияОтбора);
Если ОбщегоНазначения.ЭтоПеречисление(МетаданныеЗначенияОтбора) Тогда
СсылкаНаЗначение = МенеджерОбъектаОтбора[ЗначениеОтбора];
Иначе
СсылкаНаЗначение = МенеджерОбъектаОтбора.ПолучитьСсылку(Новый УникальныйИдентификатор(ЗначениеОтбора));
КонецЕсли;
ЭлементОтбора.Установить(СсылкаНаЗначение);
Иначе
Если ВРег(СтрЗаменить(ТипЗначенияОтбора, " ", "")) = "УНИКАЛЬНЫЙИДЕНТИФИКАТОР" Тогда
ЭлементОтбора.Установить(XMLЗначение(Тип("УникальныйИдентификатор"), ЗначениеОтбора));
Иначе
ЭлементОтбора.Установить(XMLЗначение(Тип(ТипЗначенияОтбора), ЗначениеОтбора));
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Иначе
ЗначениеРегистратора = Новый УникальныйИдентификатор(ЧтениеXML.ЗначениеАтрибута("Ref"));
ПолноеИмяРегистратора = ЧтениеXML.ЗначениеАтрибута("FilterType");
МенеджерРегистратора = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмяРегистратора);
СсылкаНаРегистратор = МенеджерРегистратора.ПолучитьСсылку(ЗначениеРегистратора);
ОбменДаннымиСлужебный.УстановитьЗначениеЭлементаОтбора(ОбъектКОбработке.Отбор, "Регистратор", СсылкаНаРегистратор);
КонецЕсли;
ОбъектКОбработке.Прочитать();
КонецЕсли;
ОбновлениеИнформационнойБазы.ОтметитьКОбработке(ПараметрыОбработчикаСтруктура, ОбъектКОбработке);
Иначе
Продолжить;
КонецЕсли;
КонецЦикла;
ЧтениеXML.Закрыть();
Файл = Новый Файл(ИмяФайла);
Если Файл.Существует() Тогда
УдалитьФайлы(ИмяФайла);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Выполняет закрытие XML файла с записанной информацией об объектах
// зарегистрированных для отложенного обновления.
//
Процедура ЗавершитьЗаписьФайлаСДаннымиОбновления(Параметры) Экспорт
ДанныеОбновления = ЗавершитьЗаписьФайлаИПолучитьДанныеОбновления(Параметры);
Если ДанныеОбновления <> Неопределено Тогда
СохранитьДанныеОбновления(ДанныеОбновления, Параметры.ИмяФайлаСИзменениями);
КонецЕсли;
КонецПроцедуры
// Выполняет закрытие XML файла с записанной информацией об объектах
// зарегистрированных для отложенного обновления и возвращает содержимое файла.
//
// Параметры:
// Параметры - см. ОбновлениеИнформационнойБазы.ОсновныеПараметрыОтметкиКОбработке
//
// Возвращаемое значение:
// ХранилищеЗначения - содержимое файла.
//
Функция ЗавершитьЗаписьФайлаИПолучитьДанныеОбновления(Параметры) Экспорт
Если Не СтандартныеПодсистемыПовтИсп.ИспользуетсяРИБ("СФильтром")
Или ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
Возврат Неопределено;
КонецЕсли;
Если Параметры.ЗаписьИзмененийДляПодчиненногоУзлаРИБСФильтрами = Неопределено Тогда
ТекстИсключения = НСтр("ru = 'В обработчике неправильно организована работа с параметрами регистрации данных к обработке.'");
ВызватьИсключение ТекстИсключения;
КонецЕсли;
ЗаписьXML = Параметры.ЗаписьИзмененийДляПодчиненногоУзлаРИБСФильтрами;
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.Закрыть();
ИмяФайлаСИзменениями = Параметры.ИмяФайлаСИзменениями;
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяФайлаСИзменениями);
Возврат Новый ХранилищеЗначения(ДвоичныеДанныеФайла, Новый СжатиеДанных(9));
КонецФункции
// Сохраняет содержимое файла из ЗавершитьЗаписьФайлаИПолучитьДанныеОбновления()
// в константу ДанныеДляОтложенногоОбновления.
//
// Параметры:
// ДанныеОбновления - ХранилищеЗначения - содержимое файла.
// ИмяФайлаСИзменениями - Строка - имя файла, в котором находились данные.
//
Процедура СохранитьДанныеОбновления(ДанныеОбновления, ИмяФайлаСИзменениями) Экспорт
Если ИмяФайлаСИзменениями = Неопределено Тогда
Возврат;
КонецЕсли;
НачатьТранзакцию();
Попытка
Блокировка = Новый БлокировкаДанных;
Блокировка.Добавить("Константа.ДанныеДляОтложенногоОбновления");
Блокировка.Заблокировать();
ЗначениеКонстанты = Константы.ДанныеДляОтложенногоОбновления.Получить().Получить();
Если ТипЗнч(ЗначениеКонстанты) <> Тип("Массив") Тогда
ЗначениеКонстанты = Новый Массив;
КонецЕсли;
ЗначениеКонстанты.Добавить(ДанныеОбновления);
Константы.ДанныеДляОтложенногоОбновления.Установить(Новый ХранилищеЗначения(ЗначениеКонстанты));
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
ФайлСДанными = Новый Файл(ИмяФайлаСИзменениями);
Если ФайлСДанными.Существует() Тогда
УдалитьФайлы(ИмяФайлаСИзменениями);
КонецЕсли;
КонецПроцедуры
// Сбрасывает значение константы ЗаписьИзмененийДляПодчиненногоУзлаРИБСФильтрами при обновлении.
//
Процедура СброситьЗначениеКонстантыСИзменениямиДляПодчиненногоУзлаРИБСФильтрами() Экспорт
Константы.ДанныеДляОтложенногоОбновления.Установить(Неопределено);
КонецПроцедуры
// Возвращает Истина, если настройка подчиненного узла РИБ не завершена и
// требуется обновления параметров работы программы, которые не участвуют в РИБ.
//
Функция НастройкаПодчиненногоУзлаРИБ() Экспорт
УстановитьПривилегированныйРежим(Истина);
Возврат ЭтоПодчиненныйУзелРИБ()
И НЕ Константы.НастройкаПодчиненногоУзлаРИБЗавершена.Получить();
КонецФункции
// Выполняет обновление правил конвертации/регистрации объектов.
// Обновление выполняется для всех планов обмена, подключенных к подсистеме.
// Обновление правил выполняется только для типовых правил.
// Если для плана обмена правила были загружены из файла, то такие правила не обновляются.
//
Процедура ВыполнитьОбновлениеПравилДляОбменаДанными() Экспорт
// Для сценария, когда в конфигурации был удален или переименован план обмена.
УдалитьНеактуальныеЗаписиВРегистреПравилДляОбменаДанными();
Если Не Константы.ИспользоватьСинхронизациюДанных.Получить()
И Не ОбщегоНазначения.РазделениеВключено() Тогда
Возврат;
КонецЕсли;
ПравилаОбменаЗагруженныеИзФайла = Новый Массив;
ПравилаРегистрацииЗагруженныеИзФайла = Новый Массив;
ВыполнитьПроверкуНаличияПравилОбменаЗагруженныхИзФайла(ПравилаОбменаЗагруженныеИзФайла, ПравилаРегистрацииЗагруженныеИзФайла);
ВыполнитьОбновлениеВерсииТиповыхПравилДляОбменаДанными(ПравилаОбменаЗагруженныеИзФайла, ПравилаРегистрацииЗагруженныеИзФайла);
КонецПроцедуры
// См. ОбменДаннымиПовтИсп.КаталогВременногоХранилищаФайлов()
Функция КаталогВременногоХранилищаФайлов() Экспорт
БезопасныйРежим = БезопасныйРежим();
Возврат ОбменДаннымиПовтИсп.КаталогВременногоХранилищаФайлов(БезопасныйРежим);
КонецФункции
// Выполняет проверку подключения обработки транспорта по заданным настройкам.
//
Процедура ПроверитьПодключениеОбработкиТранспортаСообщенийОбмена(Отказ,
СтруктураНастроек, ВидТранспорта, СообщениеОбОшибке = "", НовыеПароли = Неопределено) Экспорт
УстановитьПривилегированныйРежим(Истина);
// Создаем экземпляр объекта обработки.
ОбработкаОбъект = Обработки[ИмяОбработкиТранспортаСообщенийОбмена(ВидТранспорта)].Создать();
// Инициализация свойств обработки переданными параметрами настроек.
ЗаполнитьЗначенияСвойств(ОбработкаОбъект, СтруктураНастроек);
// Привилегированный режим установлен выше.
Если СтруктураНастроек.Свойство("Корреспондент") Тогда
Если НовыеПароли = Неопределено Тогда
Пароли = ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(СтруктураНастроек.Корреспондент,
"COMПарольПользователя, FTPСоединениеПароль, WSПароль, ПарольАрхиваСообщенияОбмена", Истина);
Иначе
Пароли = Новый Структура(
"COMПарольПользователя, FTPСоединениеПароль, WSПароль, ПарольАрхиваСообщенияОбмена");
ЗаполнитьЗначенияСвойств(Пароли, НовыеПароли);
КонецЕсли;
ЗаполнитьЗначенияСвойств(ОбработкаОбъект, Пароли);
КонецЕсли;
// Инициализация транспорта обмена.
ОбработкаОбъект.Инициализация();
// Выполняем проверку подключения.
Если Не ОбработкаОбъект.ПодключениеУстановлено() Тогда
Отказ = Истина;
СообщениеОбОшибке = ОбработкаОбъект.СтрокаСообщенияОбОшибке
+ Символы.ПС + НСтр("ru = 'Техническую информацию об ошибке см. в журнале регистрации.'");
ЗаписьЖурналаРегистрации(НСтр("ru = 'Транспорт сообщений обмена'", ОбщегоНазначения.КодОсновногоЯзыка()),
УровеньЖурналаРегистрации.Ошибка, , , ОбработкаОбъект.СтрокаСообщенияОбОшибкеЖР);
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьВозможностьАдминистрированияОбменов() Экспорт
Если Не ЕстьПраваНаАдминистрированиеОбменов() Тогда
ВызватьИсключение НСтр("ru = 'Недостаточно прав для администрирования синхронизации данных.'");
КонецЕсли;
КонецПроцедуры
// Получает узел распределенной информационной базы, являющийся главным для текущей информационной базы при условии,
// что распределенная информационная база создана на базе плана обмена, обслуживаемым подсистемой обмена данными БСП.
//
// Возвращаемое значение:
// ПланОбменаСсылка.<ИмяПланаОбмена>, Неопределено - если текущая информационная база не является
// узлом распределенной информационной базы
// или главный узел для нее не определен (она сама является корневым узлом)
// или распределенная информационная база создана на базе плана обмена, который не обслуживается подсистемой обмена
// данными БСП, то метод возвращает Неопределено.
//
Функция ГлавныйУзел() Экспорт
Результат = ПланыОбмена.ГлавныйУзел();
Если Результат <> Неопределено Тогда
Если Не ОбменДаннымиПовтИсп.ЭтоУзелОбменаДаннымиБСП(Результат) Тогда
Результат = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПриПродолженииНастройкиПодчиненногоУзлаРИБ() Экспорт
ИнтеграцияПодсистемБСП.ПриНастройкеПодчиненногоУзлаРИБ();
ОбменДаннымиПереопределяемый.ПриНастройкеПодчиненногоУзлаРИБ();
КонецПроцедуры
// Возвращает признак наличия у пользователя прав на выполнение синхронизации данных.
// Выполнять синхронизацию данных может, либо полноправный пользователь,
// либо пользователь с правами поставляемого профиля "Синхронизация данных с другими программами".
//
// Параметры:
// Пользователь - ПользовательИнформационнойБазы
// - Неопределено.
// Пользователь, для которого необходимо вычислить признак разрешения использования синхронизации данных.
// Если параметр не задан, то функция вычисляется для текущего пользователя информационной базы.
//
Функция СинхронизацияДанныхРазрешена(Знач Пользователь = Неопределено) Экспорт
Если Пользователь = Неопределено Тогда
Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
КонецЕсли;
Если Пользователь.Роли.Содержит(Метаданные.Роли.ПолныеПрава) Тогда
Возврат Истина;
КонецЕсли;
РолиПрофиля = СтрРазделить(РолиПрофиляДоступаСинхронизацияДанныхСДругимиПрограммами(), ",");
Для Каждого Роль Из РолиПрофиля Цикл
Если Не Пользователь.Роли.Содержит(Метаданные.Роли.Найти(СокрЛП(Роль))) Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
// Параметры:
// Приемник - ТаблицаЗначений
// - ТабличнаяЧасть - приемник данных.
// Источник - ТаблицаЗначений
// - ТабличнаяЧасть - источник данных.
//
Процедура ЗаполнитьТаблицуЗначений(Приемник, Знач Источник) Экспорт
Приемник.Очистить();
Если ТипЗнч(Источник)=Тип("ТаблицаЗначений") Тогда
КолонкиИсточника = Источник.Колонки;
Иначе
Времянка = Источник.Выгрузить(Новый Массив);
КолонкиИсточника = Времянка.Колонки;
КонецЕсли;
Если ТипЗнч(Приемник)=Тип("ТаблицаЗначений") Тогда
КолонкиПриемника = Приемник.Колонки;
КолонкиПриемника.Очистить();
Для Каждого Колонка Из КолонкиИсточника Цикл
ЗаполнитьЗначенияСвойств(КолонкиПриемника.Добавить(), Колонка);
КонецЦикла;
КонецЕсли;
Для Каждого Строка Из Источник Цикл
ЗаполнитьЗначенияСвойств(Приемник.Добавить(), Строка);
КонецЦикла;
КонецПроцедуры
Функция ПолученоСообщениеСДаннымиДляСопоставления(УзелОбмена) Экспорт
УстановитьПривилегированныйРежим(Истина);
Запрос = Новый Запрос(
"ВЫБРАТЬ
| СообщенияДляСопоставленияДанных.ПолученоСообщениеДляСопоставленияДанных КАК ПолученоСообщениеДляСопоставленияДанных
|ИЗ
| #ТаблицаПланаОбмена КАК ТаблицаПланаОбмена
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ СообщенияДляСопоставленияДанных КАК СообщенияДляСопоставленияДанных
| ПО (СообщенияДляСопоставленияДанных.УзелИнформационнойБазы = ТаблицаПланаОбмена.Ссылка)
|ГДЕ
| ТаблицаПланаОбмена.Ссылка = &УзелОбмена");
Запрос.УстановитьПараметр("УзелОбмена", УзелОбмена);
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ТаблицаПланаОбмена", "ПланОбмена." + ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелОбмена));
ПолучитьСообщенияДляСопоставленияДанных(Запрос.МенеджерВременныхТаблиц);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.ПолученоСообщениеДляСопоставленияДанных;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция КодУзлаПланаОбменаСтрокой(Значение) Экспорт
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Возврат СокрЛП(Значение);
ИначеЕсли ТипЗнч(Значение) = Тип("Число") Тогда
Возврат Формат(Значение, "ЧЦ=7; ЧВН=; ЧГ=0");
КонецЕсли;
Возврат Значение;
КонецФункции
// Получает параметр защищенного соединения.
//
Функция ЗащищенноеСоединение(Путь) Экспорт
Возврат ?(НРег(Лев(Путь, 4)) = "ftps", ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение(), Неопределено);
КонецФункции
Процедура ЗарегистрироватьДанныеДляНачальнойВыгрузки(УзелИнформационнойБазы, Данные = Неопределено, УдалитьРегистрациюСоответствий = Истина) Экспорт
УстановитьПривилегированныйРежим(Истина);
// Обновляем повторно используемые значения Механизма регистрации объектов.
ОбменДаннымиСлужебный.ПроверитьКэшМеханизмаРегистрацииОбъектов();
СтандартнаяОбработка = Истина;
ОбменДаннымиПереопределяемый.РегистрацияИзмененийНачальнойВыгрузкиДанных(УзелИнформационнойБазы, СтандартнаяОбработка, Данные);
Если СтандартнаяОбработка Тогда
Если ТипЗнч(Данные) = Тип("Массив") Тогда
Для Каждого ОбъектМетаданных Из Данные Цикл
ПланыОбмена.ЗарегистрироватьИзменения(УзелИнформационнойБазы, ОбъектМетаданных);
КонецЦикла;
Иначе
ПланыОбмена.ЗарегистрироватьИзменения(УзелИнформационнойБазы, Данные);
КонецЕсли;
КонецЕсли;
Если ОбменДаннымиПовтИсп.ПланОбменаСодержитОбъект(ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелИнформационнойБазы),
Метаданные.РегистрыСведений.СоответствияОбъектовИнформационныхБаз.ПолноеИмя())
И УдалитьРегистрациюСоответствий Тогда
ПланыОбмена.УдалитьРегистрациюИзменений(УзелИнформационнойБазы, Метаданные.РегистрыСведений.СоответствияОбъектовИнформационныхБаз);
КонецЕсли;
// Устанавливаем признак начальной выгрузки данных для узла.
РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.УстановитьПризнакНачальнойВыгрузкиДанных(УзелИнформационнойБазы);
КонецПроцедуры
Процедура ЗарегистрироватьТолькоСправочникиДляНачальнойВыгрузки(Знач УзелИнформационнойБазы) Экспорт
ЗарегистрироватьДанныеДляНачальнойВыгрузки(УзелИнформационнойБазы, СправочникиПланаОбмена(УзелИнформационнойБазы));
КонецПроцедуры
Процедура ЗарегистрироватьТолькоСправочникиДляНачальнойВыгрузкиВФоне(ПараметрыПроцедуры, АдресХранилища) Экспорт
ЗарегистрироватьТолькоСправочникиДляНачальнойВыгрузки(ПараметрыПроцедуры["УзелИнформационнойБазы"]);
КонецПроцедуры
Процедура ЗарегистрироватьВсеДанныеКромеСправочниковДляНачальнойВыгрузки(Знач УзелИнформационнойБазы) Экспорт
ЗарегистрироватьДанныеДляНачальнойВыгрузки(УзелИнформационнойБазы, ВсеДанныеПланаОбменаКромеСправочников(УзелИнформационнойБазы));
КонецПроцедуры
Процедура ЗарегистрироватьВсеДанныеКромеСправочниковДляНачальнойВыгрузкиВФоне(ПараметрыПроцедуры, АдресХранилища) Экспорт
ЗарегистрироватьВсеДанныеКромеСправочниковДляНачальнойВыгрузки(ПараметрыПроцедуры["УзелИнформационнойБазы"]);
КонецПроцедуры
Функция ДанныеДляТабличныхЧастейУзловЭтойИнформационнойБазы(Знач ИмяПланаОбмена, ВерсияКорреспондента = "", ИдентификаторНастройки = "") Экспорт
Результат = Новый Структура;
ОбщиеТаблицыУзлов = ОбменДаннымиПовтИсп.ТабличныеЧастиПланаОбмена(ИмяПланаОбмена, ВерсияКорреспондента, ИдентификаторНастройки)["ВсеТаблицыЭтойБазы"];
Для Каждого ИмяТабличнойЧасти Из ОбщиеТаблицыУзлов Цикл
ИмяТаблицы = ИмяТаблицыИзПервогоРеквизитаТабличнойЧастиПланаОбмена(ИмяПланаОбмена, ИмяТабличнойЧасти);
Если Не ЗначениеЗаполнено(ИмяТаблицы) Тогда
Продолжить;
КонецЕсли;
ДанныеТабличнойЧасти = Новый ТаблицаЗначений;
ДанныеТабличнойЧасти.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
ДанныеТабличнойЧасти.Колонки.Добавить("УникальныйИдентификаторСсылки", Новый ОписаниеТипов("Строка"));
ТекстЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 1000
| ИмяТаблицыПланаОбмена.Ссылка КАК Ссылка,
| ИмяТаблицыПланаОбмена.Представление КАК Представление
|ИЗ
| &ИмяТаблицыПланаОбмена КАК ИмяТаблицыПланаОбмена
|
|ГДЕ
| НЕ ИмяТаблицыПланаОбмена.ПометкаУдаления
|
|УПОРЯДОЧИТЬ ПО
| ИмяТаблицыПланаОбмена.Представление";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ИмяТаблицыПланаОбмена", ИмяТаблицы);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СтрокаТаблицы = ДанныеТабличнойЧасти.Добавить();
СтрокаТаблицы.Представление = Выборка.Представление;
СтрокаТаблицы.УникальныйИдентификаторСсылки = Строка(Выборка.Ссылка.УникальныйИдентификатор());
КонецЦикла;
Результат.Вставить(ИмяТабличнойЧасти, ДанныеТабличнойЧасти);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПолучитьЗначенияНастройкиОтборов(СтруктураНастроекВнешнегоСоединения) Экспорт
Результат = Новый Структура;
// объектные типы
Для Каждого НастройкаОтбора Из СтруктураНастроекВнешнегоСоединения Цикл
Если ТипЗнч(НастройкаОтбора.Значение) = Тип("Структура") Тогда
РезультатВложенный = Новый Структура;
Для Каждого Элемент Из НастройкаОтбора.Значение Цикл
Если СтрНайти(Элемент.Ключ, "_Ключ") > 0 Тогда
Ключ = СтрЗаменить(Элемент.Ключ, "_Ключ", "");
Массив = Новый Массив;
Для Каждого ЭлементМассива Из Элемент.Значение Цикл
Если Не ПустаяСтрока(ЭлементМассива) Тогда
Значение = ЗначениеИзСтрокиВнутр(ЭлементМассива);
Массив.Добавить(Значение);
КонецЕсли;
КонецЦикла;
РезультатВложенный.Вставить(Ключ, Массив);
КонецЕсли;
КонецЦикла;
Результат.Вставить(НастройкаОтбора.Ключ, РезультатВложенный);
Иначе
Если СтрНайти(НастройкаОтбора.Ключ, "_Ключ") > 0 Тогда
Ключ = СтрЗаменить(НастройкаОтбора.Ключ, "_Ключ", "");
Попытка
Если ПустаяСтрока(НастройкаОтбора.Значение) Тогда
Значение = Неопределено;
Иначе
Значение = ЗначениеИзСтрокиВнутр(НастройкаОтбора.Значение);
КонецЕсли;
Исключение
Значение = Неопределено;
КонецПопытки;
Результат.Вставить(Ключ, Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
// примитивные типы
Для Каждого НастройкаОтбора Из СтруктураНастроекВнешнегоСоединения Цикл
Если ТипЗнч(НастройкаОтбора.Значение) = Тип("Структура") Тогда
РезультатВложенный = Результат[НастройкаОтбора.Ключ];
Если РезультатВложенный = Неопределено Тогда
РезультатВложенный = Новый Структура;
КонецЕсли;
Для Каждого Элемент Из НастройкаОтбора.Значение Цикл
Если СтрНайти(Элемент.Ключ, "_Ключ") <> 0 Тогда
Продолжить;
ИначеЕсли НастройкаОтбора.Значение.Свойство(Элемент.Ключ + "_Ключ") Тогда
Продолжить;
КонецЕсли;
Массив = Новый Массив;
Для Каждого ЭлементМассива Из Элемент.Значение Цикл
Массив.Добавить(ЭлементМассива);
КонецЦикла;
РезультатВложенный.Вставить(Элемент.Ключ, Массив);
КонецЦикла;
Иначе
Если СтрНайти(НастройкаОтбора.Ключ, "_Ключ") <> 0 Тогда
Продолжить;
ИначеЕсли СтруктураНастроекВнешнегоСоединения.Свойство(НастройкаОтбора.Ключ + "_Ключ") Тогда
Продолжить;
КонецЕсли;
// Экранирование перечисления
Если ТипЗнч(НастройкаОтбора.Значение) = Тип("Строка")
И ( СтрНайти(НастройкаОтбора.Значение, "Перечисление.") <> 0
ИЛИ СтрНайти(НастройкаОтбора.Значение, "Enumeration.") <> 0) Тогда
Результат.Вставить(НастройкаОтбора.Ключ, ПредопределенноеЗначение(НастройкаОтбора.Значение));
Иначе
Результат.Вставить(НастройкаОтбора.Ключ, НастройкаОтбора.Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПараметрыИнформационнойБазы(Знач ИмяПланаОбмена, Знач КодУзла, СообщениеОбОшибке) Экспорт
Результат = Новый Структура;
Результат.Вставить("ПланОбменаСуществует", Ложь);
Результат.Вставить("ПрефиксИнформационнойБазы", "");
Результат.Вставить("ПрефиксИнформационнойБазыПоУмолчанию", "");
Результат.Вставить("НаименованиеИнформационнойБазы", "");
Результат.Вставить("НаименованиеИнформационнойБазыПоУмолчанию", "");
Результат.Вставить("НастройкиПараметровУчетаЗаданы", Ложь);
Результат.Вставить("КодЭтогоУзла", "");
// Начиная с версии БСП 2.1.5.1.
Результат.Вставить("ВерсияКонфигурации", Метаданные.Версия);
// Начиная с версии БСП 2.4.2(?).
Результат.Вставить("УзелСуществует", Ложь);
// Начиная с версии БСП 3.0.1.1.
Результат.Вставить("ВерсияФорматаНастроекОбменаДанными", МодульПомощникСозданияОбменаДанными().ВерсияФорматаНастроекОбменаДанными());
Результат.Вставить("ИспользоватьПрефиксыДляНастройкиОбмена", Истина);
Результат.Вставить("ФорматОбмена", "");
Результат.Вставить("ИмяПланаОбмена", ИмяПланаОбмена);
Результат.Вставить("ВерсииФорматаОбмена", Новый Массив);
Результат.Вставить("ПоддерживаемыеОбъектыФормата", Неопределено);
Результат.Вставить("НастройкаСинхронизацииДанныхЗавершена", Ложь);
Результат.Вставить("ПолученоСообщениеДляСопоставленияДанных", Ложь);
Результат.Вставить("ПоддерживаетсяСопоставлениеДанных", Истина);
УстановитьПривилегированныйРежим(Истина);
Результат.ПланОбменаСуществует = (Метаданные.ПланыОбмена.Найти(ИмяПланаОбмена) <> Неопределено);
Если Не Результат.ПланОбменаСуществует Тогда
// В качестве имени плана обмена м.б. передан формат обмена.
Для Каждого ПланОбмена Из ОбменДаннымиПовтИсп.ПланыОбменаБСП() Цикл
Если Не ОбменДаннымиПовтИсп.ЭтоПланОбменаXDTO(ПланОбмена) Тогда
Продолжить;
КонецЕсли;
ФорматОбмена = ЗначениеНастройкиПланаОбмена(ПланОбмена, "ФорматОбмена");
Если ИмяПланаОбмена = ФорматОбмена Тогда
Результат.ПланОбменаСуществует = Истина;
Результат.ИмяПланаОбмена = ПланОбмена;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Не Результат.ПланОбменаСуществует Тогда
Возврат Результат;
КонецЕсли;
ЭтотУзел = ПланыОбмена[Результат.ИмяПланаОбмена].ЭтотУзел();
СвойстваЭтогоУзла = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ЭтотУзел, "Код, Наименование");
ПрефиксИнформационнойБазы = Неопределено;
ОбменДаннымиПереопределяемый.ПриОпределенииПрефиксаИнформационнойБазыПоУмолчанию(ПрефиксИнформационнойБазы);
УзелКорреспондента = Неопределено;
Если ЗначениеЗаполнено(КодУзла) Тогда
УзелКорреспондента = УзелПланаОбменаПоКоду(Результат.ИмяПланаОбмена, КодУзла);
КонецЕсли;
Результат.ПрефиксИнформационнойБазы = ПолучитьФункциональнуюОпцию("ПрефиксИнформационнойБазы");
Результат.ПрефиксИнформационнойБазыПоУмолчанию = ПрефиксИнформационнойБазы;
Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
Результат.НаименованиеИнформационнойБазы = Константы.ЗаголовокСистемы.Получить();
КонецЕсли;
Если ПустаяСтрока(Результат.НаименованиеИнформационнойБазы) Тогда
Результат.НаименованиеИнформационнойБазы = СвойстваЭтогоУзла.Наименование;
КонецЕсли;
Результат.УзелСуществует = ЗначениеЗаполнено(УзелКорреспондента);
Результат.НастройкиПараметровУчетаЗаданы = Результат.УзелСуществует
И НастройкиПараметровУчетаВСистемеУстановлены(Результат.ИмяПланаОбмена, КодУзла, СообщениеОбОшибке);
Результат.КодЭтогоУзла = СвойстваЭтогоУзла.Код;
Результат.ВерсияКонфигурации = Метаданные.Версия;
Результат.НаименованиеИнформационнойБазыПоУмолчанию = ?(ОбщегоНазначения.РазделениеВключено(),
Метаданные.Синоним, ОбменДаннымиПовтИсп.ИмяЭтойИнформационнойБазы());
Если ОбменДаннымиПовтИсп.ЭтоПланОбменаXDTO(Результат.ИмяПланаОбмена) Тогда
Результат.ИспользоватьПрефиксыДляНастройкиОбмена =
Не ОбменДаннымиXDTOСервер.ПоддерживаетсяВерсияСИдентификаторомОбменаДанными(ЭтотУзел);
СвойстваПланаОбмена = ЗначениеНастройкиПланаОбмена(Результат.ИмяПланаОбмена, "ВерсииФорматаОбмена, ФорматОбмена");
Результат.ФорматОбмена = СвойстваПланаОбмена.ФорматОбмена;
Результат.ВерсииФорматаОбмена = ОбщегоНазначения.ВыгрузитьКолонку(СвойстваПланаОбмена.ВерсииФорматаОбмена, "Ключ", Истина);
Результат.Вставить("ПоддерживаемыеОбъектыФормата",
ОбменДаннымиXDTOСервер.ПоддерживаемыеОбъектыФормата(Результат.ИмяПланаОбмена, "ОтправкаПолучение", УзелКорреспондента));
КонецЕсли;
Если Результат.УзелСуществует Тогда
Результат.НастройкаСинхронизацииДанныхЗавершена = НастройкаСинхронизацииЗавершена(УзелКорреспондента);
Результат.ПолученоСообщениеДляСопоставленияДанных = ПолученоСообщениеСДаннымиДляСопоставления(УзелКорреспондента);
Результат.ПоддерживаетсяСопоставлениеДанных = ЗначениеНастройкиПланаОбмена(Результат.ИмяПланаОбмена,
"ПоддерживаетсяСопоставлениеДанных", СохраненныйВариантНастройкиУзлаПланаОбмена(УзелКорреспондента));
КонецЕсли;
Возврат Результат;
КонецФункции
// Возвращает Истина при необходимости обновления конфигурации информационной базы подчиненного узла РИБ.
// В главном узле всегда - Ложь.
//
// Копия функции ОбщегоНазначения.ТребуетсяОбновлениеКонфигурацииПодчиненногоУзлаРИБ.
//
Функция ТребуетсяУстановкаОбновления() Экспорт
Возврат ЭтоПодчиненныйУзелРИБ() И КонфигурацияИзменена();
КонецФункции
// Предназначена для подготовки структуры, для последующей передачи в обработчик получения описания варианта.
//
// Параметры:
// ИмяКорреспондента - Строка - имя конфигурации-корреспондента.
// ВерсияКорреспондента - Строка - версия конфигурации-корреспондента.
//
// Возвращаемое значение:
// Структура:
// * ИмяКорреспондента - Строка - имя конфигурации корреспондента.
// * ВерсияКорреспондента - Строка - номер версии конфигурации корреспондента.
//
Функция ПараметрыКонтекстаПолученияОписанияВариантаНастройки(ИмяКорреспондента, ВерсияКорреспондента) Экспорт
Результат = Новый Структура;
Результат.Вставить("ИмяКорреспондента", ИмяКорреспондента);
Результат.Вставить("ВерсияКорреспондента", ВерсияКорреспондента);
Возврат Результат;
КонецФункции
// Предназначена для подготовки структуры, для последующей передачи в обработчик получения вариантов настроек.
//
// Параметры:
// ИмяКорреспондента - Строка - имя конфигурации-корреспондента.
// ВерсияКорреспондента - Строка - версия конфигурации-корреспондента.
// КорреспондентВМоделиСервиса - Булево
// - Неопределено - признак того, что корреспондент находится в модели сервиса.
//
// Возвращаемое значение:
// Структура:
// * ВерсияКорреспондента - Строка - номер версии конфигурации корреспондента.
// * ИмяКорреспондента - Строка - имя конфигурации корреспондента.
// * КорреспондентВМоделиСервиса - Булево - Истина, если корреспондент работает в модели сервиса.
//
Функция ПараметрыКонтекстаПолученияВариантовНастроек(ИмяКорреспондента, ВерсияКорреспондента, КорреспондентВМоделиСервиса) Экспорт
Результат = Новый Структура;
Результат.Вставить("ИмяКорреспондента", ИмяКорреспондента);
Результат.Вставить("ВерсияКорреспондента", ВерсияКорреспондента);
Результат.Вставить("КорреспондентВМоделиСервиса", КорреспондентВМоделиСервиса);
Возврат Результат;
КонецФункции
// Возвращает пустую таблицу вариантов настройки обмена.
//
// Возвращаемое значение:
// ТаблицаЗначений:
// * ИдентификаторНастройки - Строка - идентификатор настройки.
// * КорреспондентВМоделиСервиса - Булево - Истина, если поддерживается настройка обмена
// с корреспондентом, работающим в модели сервиса.
// * КорреспондентВЛокальномРежиме - Булево - Истина, если поддерживается настройка обмена
// с корреспондентом, работающим в локальном режиме.
//
Функция КоллекцияВариантовНастроекОбмена() Экспорт
ВариантыНастроекОбмена = Новый ТаблицаЗначений;
ВариантыНастроекОбмена.Колонки.Добавить("ИдентификаторНастройки", Новый ОписаниеТипов("Строка"));
ВариантыНастроекОбмена.Колонки.Добавить("КорреспондентВМоделиСервиса", Новый ОписаниеТипов("Булево"));
ВариантыНастроекОбмена.Колонки.Добавить("КорреспондентВЛокальномРежиме", Новый ОписаниеТипов("Булево"));
Возврат ВариантыНастроекОбмена;
КонецФункции
// Определяет настройки по умолчанию для плана обмена, которые затем могут быть переопределены
// в модуле менеджера плана обмена в процедуре ПриПолученииНастроек().
//
// Возвращаемое значение:
// Структура:
// * ВариантыНастроекОбмена - см. КоллекцияВариантовНастроекОбмена
// * ВидГруппыДляВариантовНастроек - ВидГруппыФормы - вариант вида группы для отображения в
// дереве команд создания обмена вариантов настроек.
// * ИмяКонфигурацииИсточника - Строка - имя конфигурации источника, выводимое в
// пользовательском интерфейсе.
// * ИмяКонфигурацииПриемника - Структура - перечень идентификаторов конфигураций-корреспондентов,
// обмен с которыми возможен через данный план обмена.
// * ВерсииФорматаОбмена - Соответствие - соответствие номеров поддерживаемых версий формата
// и ссылок на общие модули с логикой обмена через формат.
// Используется только для обменов через универсальный формат.
// * ФорматОбмена - Строка - пространство имен XDTO пакета, в котором содержится
// универсальный формат, без указания версии формата.
// Используется только для обменов через универсальный формат.
// * РасширенияФорматаОбмена - СоответствиеизКлючИЗначение:
// ** Ключ - Строка - URI пространства имен схемы расширения формата.
// ** Значение - Строка - номер расширяемой версии формата.
// * ПланОбменаИспользуетсяВМоделиСервиса - Булево - признак использования плана обмена для организации
// обмена в модели сервиса.
// * ЭтоПланОбменаXDTO - Булево - признак того, что это план обмена через
// универсальный формат.
// * ПредупреждатьОНесоответствииВерсийПравилОбмена - Булево - признак необходимости проверки на
// расхождение версий в правилах конвертации.
// Проверка выполняется при загрузке комплекта
// правил, при отправке данных и при получении данных.
// * ИмяПланаОбменаДляПереходаНаНовыйОбмен - Строка - если для плана обмена свойство установлено, в
// рабочих местах управления настройками не будет
// предлагаться настроить этот вид обмена.
// Существующие обмены этого вида будут продолжать
// отображаться в списке настроенных обменов.
// Получении сообщения обмена в новом формате будет
// инициировать переход на новый вид обмена.
// * НазначениеПланаОбмена - Строка - вариант назначения плана обмена.
// * Алгоритмы - Структура - перечень экспортных процедур и функций, которые
// объявлены в модуле менеджера плана обмена
// и используются подсистемой обмена данными.
//
Функция НастройкиПланаОбменаПоУмолчанию(ИмяПланаОбмена) Экспорт
НазначениеПланаОбмена = "СинхронизацияСДругойПрограммой";
Если ОбменДаннымиПовтИсп.ЭтоПланОбменаРаспределеннойИнформационнойБазы(ИмяПланаОбмена) Тогда
НазначениеПланаОбмена = "РИБ";
КонецЕсли;
Алгоритмы = Новый Структура;
Алгоритмы.Вставить("ПриПолученииВариантовНастроекОбмена", Ложь);
Алгоритмы.Вставить("ПриПолученииОписанияВариантаНастройки", Ложь);
Алгоритмы.Вставить("ОписаниеОграниченийПередачиДанных", Ложь);
Алгоритмы.Вставить("ОписаниеЗначенийПоУмолчанию", Ложь);
Алгоритмы.Вставить("ПредставлениеОтбораИнтерактивнойВыгрузки", Ложь);
Алгоритмы.Вставить("НастроитьИнтерактивнуюВыгрузку", Ложь);
Алгоритмы.Вставить("НастроитьИнтерактивнуюВыгрузкуВМоделиСервиса", Ложь);
Алгоритмы.Вставить("ОбработчикПроверкиОграниченийПередачиДанных", Ложь);
Алгоритмы.Вставить("ОбработчикПроверкиЗначенийПоУмолчанию", Ложь);
Алгоритмы.Вставить("ОбработчикПроверкиПараметровУчета", Ложь);
Алгоритмы.Вставить("ПриПодключенииККорреспонденту", Ложь);
Алгоритмы.Вставить("ПриПолученииДанныхОтправителя", Ложь);
Алгоритмы.Вставить("ПриОтправкеДанныхОтправителя", Ложь);
Алгоритмы.Вставить("ПриСохраненииНастроекСинхронизацииДанных", Ложь);
Алгоритмы.Вставить("ПриОпределенииПоддерживаемыхОбъектовФормата", Ложь);
Алгоритмы.Вставить("ПриОпределенииПоддерживаемыхКорреспондентомОбъектовФормата", Ложь);
Алгоритмы.Вставить("ПередНастройкойСинхронизацииДанных", Ложь);
Параметры = Новый Структура;
Параметры.Вставить("ВариантыНастроекОбмена", КоллекцияВариантовНастроекОбмена());
Параметры.Вставить("ИмяКонфигурацииИсточника", "");
Параметры.Вставить("ИмяКонфигурацииПриемника", Новый Структура);
Параметры.Вставить("ВерсииФорматаОбмена", Новый Соответствие);
Параметры.Вставить("ФорматОбмена", "");
Параметры.Вставить("РасширенияФорматаОбмена", Новый Соответствие);
Параметры.Вставить("ПланОбменаИспользуетсяВМоделиСервиса", Ложь);
Параметры.Вставить("ЭтоПланОбменаXDTO", Ложь);
Параметры.Вставить("ИмяПланаОбменаДляПереходаНаНовыйОбмен", "");
Параметры.Вставить("ПредупреждатьОНесоответствииВерсийПравилОбмена", Истина);
Параметры.Вставить("НазначениеПланаОбмена", НазначениеПланаОбмена);
Параметры.Вставить("НаличиеПравилКонвертацииОбязательно", Истина);
Параметры.Вставить("Алгоритмы", Алгоритмы);
Возврат Параметры;
КонецФункции
// Определяет настройки по умолчанию варианта настройки обмена, которые затем могут быть переопределены
// в модуле менеджера плана обмена в процедуре ПриПолученииОписанияВариантаНастройки().
//
// Параметры:
// ИмяПланаОбмена - Строка - содержит имя плана обмена.
//
// Возвращаемое значение:
// Структура:
// * Отборы - Структура - отборы на узле плана обмена,
// подлежат заполнению значениями по умолчанию.
// * ЗначенияПоУмолчанию - Структура - значения по умолчанию на узле плана обмена.
// * ОбщиеДанныеУзлов - Строка - имена реквизитов и табличных частей плана обмена,
// через запятую, которые являются общими для пары
// обменивающихся конфигураций.
// * ИспользоватьПомощникСозданияОбменаДанными - Булево - признак, будет ли использоваться помощник для
// создания новых узлов плана обмена.
// * ИмяФормыСозданияНачальногоОбраза - Строка - имя используемой формы создания начального
// образа распределенной ИБ.
// * ИмяФормыПомощникаНастройкиСинхронизацииДанных - Строка - имя формы, которая будет использована для настройки
// правил отправки и получения данных вместо
// стандартной формы.
// * ПояснениеДляНастройкиПараметровУчета - Строка - пояснение о последовательности действий пользователя
// для настройки параметров учета в текущей
// информационной базе.
// * ПутьКФайлуКомплектаПравилНаПользовательскомСайте - Строка - путь к файлу комплекта правил в виде архива
// на пользовательском сайте в разделе конфигурации.
// * ПутьКФайлуКомплектаПравилВКаталогеШаблонов - Строка - относительный путь к файлу комплекта правил в
// каталоге шаблонов.
// * ЗаголовокКомандыДляСозданияНовогоОбменаДанными - Строка - представление команды, выводимое в пользовательском
// интерфейсе при создании новой настройки
// обмена данными.
// * ЗаголовокПомощникаСозданияОбмена - Строка - представление заголовка формы помощника
// создания обмена данными выводимое в
// пользовательском интерфейсе.
// * ЗаголовокУзлаПланаОбмена - Строка - представление узла плана обмена
// выводимое в пользовательском интерфейсе.
// * ИмяКонфигурацииКорреспондента - Строка - идентификатор конфигурации корреспондента.
// * НаименованиеКонфигурацииКорреспондента - Строка - представление наименования конфигурации корреспондента
// выводимое в пользовательском интерфейсе.
// * ИспользуемыеТранспортыСообщенийОбмена - Массив из
// ПеречислениеСсылка.ВидыТранспортаСообщенийОбмена - Перечень используемых транспортов сообщений. Если не заполнен, будут доступны все
// возможные виды транспорта.
// * КраткаяИнформацияПоОбмену - Строка - краткое описание обмена данными, которое
// выводится на первой странице помощника
// создания обмена.
// * ПодробнаяИнформацияПоОбмену - Строка - ссылка на веб-страницу или полный путь к
// форме внутри конфигурации строкой, для
// отображения в помощнике создания обмена.
// * ИмяФайлаНастроекДляПриемника - Строка - имя файла для сохранения настроек подключения
// при настройке обмена через offline-каналы.
// * ПоддерживаетсяСопоставлениеДанных - Булево - Истина, если для данного варианта настройки поддерживается
// интерактивное сопоставление данных. В
// противном случае полученные сообщения обмена
// будут сразу загружаться в информационную базу.
// * РасширениеФормата - Строка - имя расширения формата, применимое для
// данного варианта настройки. Образуется из URI
// пространства имен схемы расширения формата,
// без учета версии. Напр., для пространства
// имен
// "http://v8.1c.ru/edi/edi_stnd/_DemoEnterpriseDataExt/1.1" имя расширение формата будет "http://v8.1c.ru/edi/edi_stnd/_DemoEnterpriseDataExt";
//
Функция ОписаниеВариантаНастройкиОбменаПоУмолчанию(ИмяПланаОбмена) Экспорт
МетаданныеПланаОбмена = Метаданные.ПланыОбмена[ИмяПланаОбмена];
СинонимПланаОбмена = МетаданныеПланаОбмена.Синоним;
ЗаголовокФормыПомощника = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Синхронизация данных с %1 (настройка)'"),
СинонимПланаОбмена);
ОписаниеВарианта = Новый Структура;
ОписаниеВарианта.Вставить("Отборы", Новый Структура);
ОписаниеВарианта.Вставить("ЗначенияПоУмолчанию", Новый Структура);
ОписаниеВарианта.Вставить("ОбщиеДанныеУзлов", "");
ОписаниеВарианта.Вставить("ИспользоватьПомощникСозданияОбменаДанными", Истина);
ОписаниеВарианта.Вставить("ИмяФормыСозданияНачальногоОбраза", "");
ОписаниеВарианта.Вставить("ИмяФормыПомощникаНастройкиСинхронизацииДанных", "");
ОписаниеВарианта.Вставить("ПояснениеДляНастройкиПараметровУчета", "");
ОписаниеВарианта.Вставить("ПутьКФайлуКомплектаПравилНаПользовательскомСайте", "");
ОписаниеВарианта.Вставить("ПутьКФайлуКомплектаПравилВКаталогеШаблонов", "");
ОписаниеВарианта.Вставить("ЗаголовокКомандыДляСозданияНовогоОбменаДанными", СинонимПланаОбмена);
ОписаниеВарианта.Вставить("ЗаголовокПомощникаСозданияОбмена", ЗаголовокФормыПомощника);
ОписаниеВарианта.Вставить("ЗаголовокУзлаПланаОбмена", СинонимПланаОбмена);
ОписаниеВарианта.Вставить("ИмяКонфигурацииКорреспондента", "");
ОписаниеВарианта.Вставить("НаименованиеКонфигурацииКорреспондента", "");
ОписаниеВарианта.Вставить("ИспользуемыеТранспортыСообщенийОбмена", Новый Массив);
ОписаниеВарианта.Вставить("КраткаяИнформацияПоОбмену", "");
ОписаниеВарианта.Вставить("ПодробнаяИнформацияПоОбмену", "");
ОписаниеВарианта.Вставить("ИмяФайлаНастроекДляПриемника", "");
ОписаниеВарианта.Вставить("ПоддерживаетсяСопоставлениеДанных", Истина);
ОписаниеВарианта.Вставить("РасширениеФормата", "");
Возврат ОписаниеВарианта;
КонецФункции
// Получение файла по его идентификатору.
//
// Параметры:
// ИдентификаторФайла - УникальныйИдентификатор - идентификатор получаемого файла.
//
// Возвращаемое значение:
// ИмяФайла - Строка - имя файла.
//
Функция ПолучитьФайлИзХранилища(Знач ИдентификаторФайла) Экспорт
ИмяФайла = "";
Если ОбщегоНазначения.РазделениеВключено()
И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
МодульОбменДаннымиВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиВМоделиСервиса");
МодульОбменДаннымиВМоделиСервиса.ПриПолученииФайлаИзХранилища(ИдентификаторФайла, ИмяФайла);
Иначе
ПриПолученииФайлаИзХранилища(ИдентификаторФайла, ИмяФайла);
КонецЕсли;
Возврат ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогВременногоХранилищаФайлов(), ИмяФайла);
КонецФункции
// Сохранение файла.
//
// Параметры:
// ИмяФайла - Строка - наименование файла.
// ИдентификаторФайла - УникальныйИдентификатор - идентификатор файла. Если задан, то при сохранении файла
// будет использоваться это значение, иначе - сгенерируется новое.
//
// Возвращаемое значение:
// УникальныйИдентификатор - идентификатор файла.
//
Функция ПоместитьФайлВХранилище(Знач ИмяФайла, Знач ИдентификаторФайла = Неопределено) Экспорт
ИдентификаторФайла = ?(ИдентификаторФайла = Неопределено, Новый УникальныйИдентификатор, ИдентификаторФайла);
Файл = Новый Файл(ИмяФайла);
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("ИдентификаторСообщения", Строка(ИдентификаторФайла));
СтруктураЗаписи.Вставить("ИмяФайлаСообщения", Файл.Имя);
СтруктураЗаписи.Вставить("ДатаЗакладкиСообщения", ТекущаяУниверсальнаяДата());
Если ОбщегоНазначения.РазделениеВключено()
И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
МодульОбменДаннымиВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиВМоделиСервиса");
МодульОбменДаннымиВМоделиСервиса.ПриПомещенииФайлаВХранилище(СтруктураЗаписи);
Иначе
ПриПомещенииФайлаВХранилище(СтруктураЗаписи);
КонецЕсли;
Возврат ИдентификаторФайла;
КонецФункции
// Структура описания стандартных вариантов дополнения выгрузки.
//
// Возвращаемое значение:
// Структура - набор вариантов дополнения выгрузки:
// * ВариантБезДополнения - см. ОписаниеСтандартногоВариантаБезДополнения
// * ВариантВсеДокументы - см. ОписаниеСтандартногоВариантаВсеДокументы
// * ВариантПроизвольныйОтбор - см. ОписаниеСтандартногоВариантаПроизвольныйОтбор
// * ВариантДополнительно - см. ОписаниеСтандартногоВариантаДополнительно
//
Функция ОписаниеСтандартныхВариантовДополненияВыгрузки() Экспорт
Результат = Новый Структура;
Результат.Вставить("ВариантБезДополнения", ОписаниеСтандартногоВариантаБезДополнения());
Результат.Вставить("ВариантВсеДокументы", ОписаниеСтандартногоВариантаВсеДокументы());
Результат.Вставить("ВариантПроизвольныйОтбор", ОписаниеСтандартногоВариантаПроизвольныйОтбор());
Результат.Вставить("ВариантДополнительно", ОписаниеСтандартногоВариантаДополнительно());
Возврат Результат;
КонецФункции
Процедура ПроверитьВозможностьЗапускаОбмена(УзелОбмена, Отказ) Экспорт
Попытка
ЗаблокироватьДанныеДляРедактирования(УзелОбмена);
Исключение
Отказ = Истина;
СообщениеОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не удалось выполнить обмен данными с %1.
|Обмен данными уже выполняется. Повторите попытку позже.'"),
УзелОбмена);
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Предупреждение,
,
,
СообщениеОбОшибке);
КонецПопытки;
РазблокироватьДанныеДляРедактирования(УзелОбмена);
КонецПроцедуры
#КонецОбласти
#Область ОберткиДляРаботыСПрограммнымИнтерфейсомМенеджераПланаОбмена
Функция НастройкаОтборовНаУзле(Знач ИмяПланаОбмена, Знач ВерсияКорреспондента, ИдентификаторНастройки = "") Экспорт
Если ПустаяСтрока(ВерсияКорреспондента) Тогда
ВерсияКорреспондента = "0.0.0.0";
КонецЕсли;
ОписаниеВариантаНастройки = ОбменДаннымиПовтИсп.ОписаниеВариантаНастройки(ИмяПланаОбмена,
ИдентификаторНастройки, ВерсияКорреспондента);
Результат = Неопределено;
Если ЗначениеЗаполнено(ОписаниеВариантаНастройки.Отборы) Тогда
Результат = ОписаниеВариантаНастройки.Отборы;
КонецЕсли;
Если Результат = Неопределено Тогда
Результат = Новый Структура;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОписаниеОграниченийПередачиДанных(Знач ИмяПланаОбмена, Знач Настройка, Знач ВерсияКорреспондента,
ИдентификаторНастройки = "") Экспорт
Если НЕ ЕстьАлгоритмМенеджераПланаОбмена("ОписаниеОграниченийПередачиДанных", ИмяПланаОбмена) Тогда
Возврат "";
ИначеЕсли ПустаяСтрока(ВерсияКорреспондента) Тогда
ВерсияКорреспондента = "0.0.0.0";
КонецЕсли;
Возврат ПланыОбмена[ИмяПланаОбмена].ОписаниеОграниченийПередачиДанных(Настройка, ВерсияКорреспондента, ИдентификаторНастройки);
КонецФункции
// Возвращает признак, предусмотрен ли указанная процедура / функция в модуле менеджера плана обмена.
// Вычисляется по настройкам плана обмена, свойство Алгоритмы (см. комментарий НастройкиПланаОбменаПоУмолчанию).
// Параметры:
// ИмяАлгоритма - Строка - имя процедуры / функции.
// ИмяПланаОбмена - Строка - имя плана обмена.
// Возвращаемое значение:
// Булево.
//
Функция ЕстьАлгоритмМенеджераПланаОбмена(ИмяАлгоритма, ИмяПланаОбмена) Экспорт
НастройкиПланаОбмена = ОбменДаннымиПовтИсп.НастройкиПланаОбмена(ИмяПланаОбмена);
АлгоритмНайден = Неопределено;
НастройкиПланаОбмена.Алгоритмы.Свойство(ИмяАлгоритма, АлгоритмНайден);
Возврат (АлгоритмНайден = Истина);
КонецФункции
#КонецОбласти
#Область ПрогрессБар
// Рассчитывает процент выгрузки и записывает в виде сообщения пользователю.
//
// Параметры:
// КоличествоВыгруженных - Число - количество выгруженных на данный момент объектов.
// КоличествоОбъектовКВыгрузке - Число - количество объектов к выгрузке.
//
Процедура РассчитатьПроцентВыгрузки(КоличествоВыгруженных, КоличествоОбъектовКВыгрузке) Экспорт
// Сообщение о проценте выгрузки выдаем через каждые 100 объектов.
Если КоличествоВыгруженных = 0 ИЛИ КоличествоВыгруженных / 100 <> Цел(КоличествоВыгруженных / 100) Тогда
Возврат;
КонецЕсли;
Если КоличествоОбъектовКВыгрузке = 0 Или КоличествоВыгруженных > КоличествоОбъектовКВыгрузке Тогда
ПроцентВыполнения = 95;
Шаблон = НСтр("ru = 'Обработано: %1 объектов.'");
Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, Формат(КоличествоВыгруженных, "ЧН=0; ЧГ="));
Иначе
// 5% полосы резервируем под выгрузку по ссылкам, проценты по количеству считаем от 95.
ПроцентВыполнения = Окр(Мин(КоличествоВыгруженных * 95 / КоличествоОбъектовКВыгрузке, 95));
Шаблон = НСтр("ru = 'Обработано: %1 из %2 объектов.'");
Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
Шаблон,
Формат(КоличествоВыгруженных, "ЧН=0; ЧГ="),
Формат(КоличествоОбъектовКВыгрузке, "ЧН=0; ЧГ="));
КонецЕсли;
// Регистрация сообщения для чтения из клиентского сеанса.
ДополнительныеПараметры = Новый Структура;
ДополнительныеПараметры.Вставить("ОбменДанными", Истина);
ДлительныеОперации.СообщитьПрогресс(ПроцентВыполнения, Текст, ДополнительныеПараметры);
КонецПроцедуры
// Рассчитывает процент загрузки и записывает в виде сообщения пользователю.
//
// Параметры:
// КоличествоЗагруженных - Число - количество загруженных на данный момент объектов.
// КоличествоОбъектовКЗагрузке - Число - количество объектов к загрузке.
// РазмерФайлаСообщенияОбмена - Число - размер файла сообщения обмена в мегабайтах.
//
Процедура РассчитатьПроцентЗагрузки(КоличествоЗагруженных, КоличествоОбъектовКЗагрузке, РазмерФайлаСообщенияОбмена) Экспорт
// Сообщение о проценте загрузки выдаем через каждые 10 объектов.
Если КоличествоЗагруженных = 0 ИЛИ КоличествоЗагруженных / 10 <> Цел(КоличествоЗагруженных / 10) Тогда
Возврат;
КонецЕсли;
Если КоличествоОбъектовКЗагрузке = 0 Тогда
// Возможно при загрузке через com соединение если на другой стороне не встроен прогресс-бар.
ПроцентВыполнения = 95;
Шаблон = НСтр("ru = 'Обработано %1 объектов.'");
Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, Формат(КоличествоЗагруженных, "ЧН=0; ЧГ="));
Иначе
// 5% полосы резервируем под отложенное заполнение, проценты по количеству считаем от 95.
ПроцентВыполнения = Окр(Мин(КоличествоЗагруженных * 95 / КоличествоОбъектовКЗагрузке, 95));
Шаблон = НСтр("ru = 'Обработано: %1 из %2 объектов.'");
Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
Шаблон,
Формат(КоличествоЗагруженных, "ЧН=0; ЧГ="),
Формат(КоличествоОбъектовКЗагрузке, "ЧН=0; ЧГ="));
КонецЕсли;
// Дополняем размером файла.
Если РазмерФайлаСообщенияОбмена <> 0 Тогда
Шаблон = НСтр("ru = 'Размер сообщения %1 МБ'");
ТекстДополнение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, РазмерФайлаСообщенияОбмена);
Текст = Текст + " " + ТекстДополнение;
КонецЕсли;
// Регистрация сообщения для чтения из клиентского сеанса.
ДополнительныеПараметры = Новый Структура;
ДополнительныеПараметры.Вставить("ОбменДанными", Истина);
ДлительныеОперации.СообщитьПрогресс(ПроцентВыполнения, Текст, ДополнительныеПараметры);
КонецПроцедуры
// Увеличение счетчика выгруженных объектов и расчет процента выгрузки. Только для РИБ.
//
// Параметры:
// Получатель - ПланОбменаОбъект
// СозданиеНачальногоОбраза - Булево
//
Процедура РассчитатьПроцентВыгрузкиРИБ(Получатель, СозданиеНачальногоОбраза) Экспорт
Если Получатель = Неопределено
Или Не ОбменДаннымиПовтИсп.ЭтоУзелРаспределеннойИнформационнойБазы(Получатель.Ссылка) Тогда
Возврат;
КонецЕсли;
// Подсчет количества объектов к выгрузке.
Если НЕ Получатель.ДополнительныеСвойства.Свойство("КоличествоОбъектовКВыгрузке") Тогда
КоличествоОбъектовКВыгрузке = 0;
Если СозданиеНачальногоОбраза Тогда
КоличествоОбъектовКВыгрузке = РассчитатьКоличествоОбъектовВБазе(Получатель);
Иначе
// Извлечение общего количества объектов к выгрузке.
ТекущийПараметрСеанса = Неопределено;
УстановитьПривилегированныйРежим(Истина);
Попытка
ТекущийПараметрСеанса = ПараметрыСеанса.ПараметрыСеансаСинхронизацииДанных.Получить();
Исключение
Возврат;
КонецПопытки;
УстановитьПривилегированныйРежим(Ложь);
Если ТипЗнч(ТекущийПараметрСеанса) = Тип("Соответствие") Тогда
ДанныеСинхронизации = ТекущийПараметрСеанса.Получить(Получатель.Ссылка);
Если НЕ (ДанныеСинхронизации = Неопределено
ИЛИ ТипЗнч(ДанныеСинхронизации) <> Тип("Структура")) Тогда
КоличествоОбъектовКВыгрузке = ДанныеСинхронизации.КоличествоОбъектовКВыгрузке;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Получатель.ДополнительныеСвойства.Вставить("КоличествоОбъектовКВыгрузке", КоличествоОбъектовКВыгрузке);
Получатель.ДополнительныеСвойства.Вставить("СчетчикВыгруженныхОбъектов", 1);
Возврат; // % выгрузки в этом случае можно не считать - это самое начало выгрузки.
Иначе
Если Получатель.ДополнительныеСвойства.Свойство("СчетчикВыгруженныхОбъектов") Тогда
Получатель.ДополнительныеСвойства.СчетчикВыгруженныхОбъектов = Получатель.ДополнительныеСвойства.СчетчикВыгруженныхОбъектов + 1;
Иначе
Возврат;
КонецЕсли;
КонецЕсли;
РассчитатьПроцентВыгрузки(Получатель.ДополнительныеСвойства.СчетчикВыгруженныхОбъектов,
Получатель.ДополнительныеСвойства.КоличествоОбъектовКВыгрузке);
КонецПроцедуры
// Увеличение счетчика загруженных объектов и расчет процента загрузки. Только для РИБ.
//
// Параметры:
// Отправитель - ПланОбменаОбъект
//
Процедура РассчитатьПроцентЗагрузкиРИБ(Отправитель) Экспорт
Если Отправитель = Неопределено
Или Не ОбменДаннымиПовтИсп.ЭтоУзелРаспределеннойИнформационнойБазы(Отправитель.Ссылка) Тогда
Возврат;
КонецЕсли;
Если НЕ Отправитель.ДополнительныеСвойства.Свойство("КоличествоОбъектовКЗагрузке")
ИЛИ НЕ Отправитель.ДополнительныеСвойства.Свойство("РазмерФайлаСообщенияОбмена") Тогда
// Извлечение общего количества объектов к загрузке и размера файла сообщения обмена.
ТекущийПараметрСеанса = Неопределено;
УстановитьПривилегированныйРежим(Истина);
Попытка
ТекущийПараметрСеанса = ПараметрыСеанса.ПараметрыСеансаСинхронизацииДанных.Получить();
Исключение
Возврат;
КонецПопытки;
УстановитьПривилегированныйРежим(Ложь);
Если ТипЗнч(ТекущийПараметрСеанса) = Тип("Соответствие") Тогда
ДанныеСинхронизации = ТекущийПараметрСеанса.Получить(Отправитель.Ссылка);
Если ДанныеСинхронизации = Неопределено
ИЛИ ТипЗнч(ДанныеСинхронизации) <> Тип("Структура") Тогда
Возврат;
КонецЕсли;
Отправитель.ДополнительныеСвойства.Вставить("КоличествоОбъектовКЗагрузке",
ДанныеСинхронизации.КоличествоОбъектовКЗагрузке);
Отправитель.ДополнительныеСвойства.Вставить("РазмерФайлаСообщенияОбмена",
ДанныеСинхронизации.РазмерФайлаСообщенияОбмена);
КонецЕсли;
КонецЕсли;
Если Не Отправитель.ДополнительныеСвойства.Свойство("СчетчикЗагруженныхОбъектов") Тогда
Отправитель.ДополнительныеСвойства.Вставить("СчетчикЗагруженныхОбъектов", 1);
Иначе
Отправитель.ДополнительныеСвойства.СчетчикЗагруженныхОбъектов = Отправитель.ДополнительныеСвойства.СчетчикЗагруженныхОбъектов + 1;
КонецЕсли;
РассчитатьПроцентЗагрузки(Отправитель.ДополнительныеСвойства.СчетчикЗагруженныхОбъектов,
Отправитель.ДополнительныеСвойства.КоличествоОбъектовКЗагрузке,
Отправитель.ДополнительныеСвойства.РазмерФайлаСообщенияОбмена);
КонецПроцедуры
// Анализирует данные к загрузке:
// Вычисляет количество объектов к загрузке, размер файла сообщения обмена, другие служебные данные.
// Параметры:
// ИмяФайлаОбмена - Строка - имя файла сообщения обмена.
// ЭтоОбменXDTO - Булево - признак того, что выполняется обмен через универсальный формат.
//
// Возвращаемое значение:
// Структура:
// * РазмерФайлаСообщенияОбмена - Число - размер файла в мегабайтах, по умолчанию 0.
// * КоличествоОбъектовКЗагрузке - Число - количество объектов к загрузке, по умолчанию 0.
// * From - Строка - код узла-отправителя сообщения.
// * To - Строка - код узла-получателя сообщения.
// * NewFrom - Строка - код узла-отправителя в новом формате (для перевода существующих обменов на новую кодировку).
//
Функция РезультатАнализаДанныхКЗагрузке(Знач ИмяФайлаОбмена, ЭтоОбменXDTO, ЭтоОбменРИБ = Ложь) Экспорт
Результат = Новый Структура;
Результат.Вставить("РазмерФайлаСообщенияОбмена", 0);
Результат.Вставить("КоличествоОбъектовКЗагрузке", 0);
Результат.Вставить("From", "");
Результат.Вставить("NewFrom", "");
Результат.Вставить("To", "");
Если НЕ ЗначениеЗаполнено(ИмяФайлаОбмена) Тогда
Возврат Результат;
КонецЕсли;
ФайлСДанными = Новый Файл(ИмяФайлаОбмена);
Если Не ФайлСДанными.Существует() Тогда
Возврат Результат;
КонецЕсли;
ФайлОбмена = Новый ЧтениеXML;
Попытка
// Размер сразу переводим в мегабайты.
Результат.РазмерФайлаСообщенияОбмена = Окр(ФайлСДанными.Размер() / 1048576, 1);
ФайлОбмена.ОткрытьФайл(ИмяФайлаОбмена);
Исключение
Возврат Результат;
КонецПопытки;
// В зависимости от вида обмена используется разный алгоритм анализа файла обмена.
Если ЭтоОбменXDTO Тогда
ФайлОбмена.Прочитать(); // Message.
ФайлОбмена.Прочитать(); // Header начало.
НачатьСчетОбъектов = Ложь;
Пока ФайлОбмена.Прочитать() Цикл
Если ФайлОбмена.ЛокальноеИмя = "Header" Тогда
// Закончено чтение заголовка.
НачатьСчетОбъектов = Истина;
ФайлОбмена.Пропустить();
ИначеЕсли ФайлОбмена.ЛокальноеИмя = "Confirmation" Тогда
ФайлОбмена.Прочитать();
ИначеЕсли ФайлОбмена.ЛокальноеИмя = "From" Тогда
ФайлОбмена.Прочитать();
Результат.From = ФайлОбмена.Значение;
ФайлОбмена.Пропустить();
ИначеЕсли ФайлОбмена.ЛокальноеИмя = "To" Тогда
ФайлОбмена.Прочитать();
Результат.To = ФайлОбмена.Значение;
ФайлОбмена.Пропустить();
ИначеЕсли ФайлОбмена.ЛокальноеИмя = "NewFrom" Тогда
ФайлОбмена.Прочитать();
Результат.NewFrom = ФайлОбмена.Значение;
ФайлОбмена.Пропустить();
ИначеЕсли НачатьСчетОбъектов
И ФайлОбмена.ТипУзла = ТипУзлаXML.НачалоЭлемента
И ФайлОбмена.ЛокальноеИмя <> "УдалениеОбъекта"
И ФайлОбмена.ЛокальноеИмя <> "Body" Тогда
Результат.КоличествоОбъектовКЗагрузке = Результат.КоличествоОбъектовКЗагрузке + 1;
ФайлОбмена.Пропустить();
КонецЕсли;
КонецЦикла;
ИначеЕсли ЭтоОбменРИБ Тогда
ФайлОбмена.Прочитать(); // Message.
ФайлОбмена.Прочитать(); // Header начало.
ФайлОбмена.Пропустить(); // Header конец.
ФайлОбмена.Прочитать(); //Body начало.
Пока ФайлОбмена.Прочитать() Цикл
Если ФайлОбмена.ЛокальноеИмя = "Changes"
ИЛИ ФайлОбмена.ЛокальноеИмя = "Data" Тогда
Продолжить;
ИначеЕсли СтрНайти(ФайлОбмена.ЛокальноеИмя, "Config") = 0
И СтрНайти(ФайлОбмена.ЛокальноеИмя, "Signature") = 0
И СтрНайти(ФайлОбмена.ЛокальноеИмя, "Nodes") = 0
И ФайлОбмена.ЛокальноеИмя <> "Parameters"
И ФайлОбмена.ЛокальноеИмя <> "Body" Тогда
Результат.КоличествоОбъектовКЗагрузке = Результат.КоличествоОбъектовКЗагрузке + 1;
КонецЕсли;
ФайлОбмена.Пропустить();
КонецЦикла;
Иначе
ФайлОбмена.Прочитать(); // Файл обмена.
ФайлОбмена.Прочитать(); // ПравилаОбмена начало.
ФайлОбмена.Пропустить(); // ПравилаОбмена конец.
ФайлОбмена.Прочитать(); // Типы данных начало.
ФайлОбмена.Пропустить(); // ТипыДанных конец.
ФайлОбмена.Прочитать(); // Данные по обмену начало.
ФайлОбмена.Пропустить(); // Данные по обмену конец.
Пока ФайлОбмена.Прочитать() Цикл
Если ФайлОбмена.ЛокальноеИмя = "Объект"
ИЛИ ФайлОбмена.ЛокальноеИмя = "НаборЗаписейРегистра"
ИЛИ ФайлОбмена.ЛокальноеИмя = "УдалениеОбъекта"
ИЛИ ФайлОбмена.ЛокальноеИмя = "ИнформацияОРегистрацииОбъекта" Тогда
Результат.КоличествоОбъектовКЗагрузке = Результат.КоличествоОбъектовКЗагрузке + 1;
КонецЕсли;
ФайлОбмена.Пропустить();
КонецЦикла;
КонецЕсли;
ФайлОбмена.Закрыть();
Возврат Результат;
КонецФункции
#КонецОбласти
#Область РаботаСОбъектомFTPСоединение
Функция FTPСоединение(Знач Настройки) Экспорт
Возврат Новый FTPСоединение(
Настройки.Сервер,
Настройки.Порт,
Настройки.ИмяПользователя,
Настройки.ПарольПользователя,
НастройкиПроксиСервера(Настройки.ЗащищенноеСоединение),
Настройки.ПассивноеСоединение,
Настройки.Таймаут,
Настройки.ЗащищенноеСоединение);
КонецФункции
Функция FTPНастройкиСоединения(Знач Таймаут = 180) Экспорт
Результат = Новый Структура;
Результат.Вставить("Сервер", "");
Результат.Вставить("Порт", 21);
Результат.Вставить("ИмяПользователя", "");
Результат.Вставить("ПарольПользователя", "");
Результат.Вставить("ПассивноеСоединение", Ложь);
Результат.Вставить("Таймаут", Таймаут);
Результат.Вставить("ЗащищенноеСоединение", Неопределено);
Возврат Результат;
КонецФункции
// Возвращает имя сервера и путь на сервере FTP, полученные из строки подключения к FTP-ресурсу.
//
// Параметры:
// СтрокаПодключения - Строка - строка подключения к FTP-ресурсу.
//
// Возвращаемое значение:
// Структура - настройки подключения к FTP-ресурсу. Поля структуры:
// Сервер - Строка - имя сервера.
// Путь - Строка - путь на сервере.
//
// Пример (1):
// Результат = FTPИмяСервераИПуть("ftp://server");
// Результат.Сервер = "server";
// Результат.Путь = "/";
//
// Пример (2):
// Результат = FTPИмяСервераИПуть("ftp://server/saas/obmen");
// Результат.Сервер = "server";
// Результат.Путь = "/saas/obmen/";
//
Функция FTPИмяСервераИПуть(Знач СтрокаПодключения) Экспорт
Результат = Новый Структура("Сервер, Путь");
СтрокаПодключения = СокрЛП(СтрокаПодключения);
Если (ВРег(Лев(СтрокаПодключения, 6)) <> "FTP://"
И ВРег(Лев(СтрокаПодключения, 7)) <> "FTPS://")
ИЛИ СтрНайти(СтрокаПодключения, "@") <> 0 Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Строка подключения к FTP-ресурсу не соответствует формату: ""%1""'"), СтрокаПодключения);
КонецЕсли;
ПараметрыПодключения = СтрРазделить(СтрокаПодключения, "/");
Если ПараметрыПодключения.Количество() < 3 Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'В строке подключения к FTP-ресурсу не указано имя сервера: ""%1""'"), СтрокаПодключения);
КонецЕсли;
Результат.Сервер = ПараметрыПодключения[2];
ПараметрыПодключения.Удалить(0);
ПараметрыПодключения.Удалить(0);
ПараметрыПодключения.Удалить(0);
ПараметрыПодключения.Вставить(0, "@");
Если Не ПустаяСтрока(ПараметрыПодключения.Получить(ПараметрыПодключения.ВГраница())) Тогда
ПараметрыПодключения.Добавить("@");
КонецЕсли;
Результат.Путь = СтрСоединить(ПараметрыПодключения, "/");
Результат.Путь = СтрЗаменить(Результат.Путь, "@", "");
Возврат Результат;
КонецФункции
Функция ОткрытьПомощникСозданияОбменаДаннымиДляНастройкиПодчиненногоУзла() Экспорт
Возврат Не ОбщегоНазначения.РазделениеВключено()
И Не ЭтоАвтономноеРабочееМесто()
И ЭтоПодчиненныйУзелРИБ()
И Не Константы.НастройкаПодчиненногоУзлаРИБЗавершена.Получить();
КонецФункции
#КонецОбласти
#Область ПрофилиБезопасности
Функция ЗапросНаИспользованиеВнешнихРесурсовПриВключенииОбмена() Экспорт
Запросы = Новый Массив();
СформироватьЗапросыНаИспользованиеВнешнихРесурсов(Запросы);
Возврат Запросы;
КонецФункции
Функция ЗапросНаОчисткуРазрешенийИспользованияВнешнихРесурсов() Экспорт
Запросы = Новый Массив;
МодульРаботаВБезопасномРежиме = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежиме");
Для Каждого ИмяПланаОбмена Из ОбменДаннымиПовтИсп.ПланыОбменаБСП() Цикл
ТекстЗапроса =
"ВЫБРАТЬ
| ПланОбмена.Ссылка КАК Узел
|ИЗ
| ПланОбмена.[ИмяПланаОбмена] КАК ПланОбмена";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяПланаОбмена]", ИмяПланаОбмена);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Запросы.Добавить(МодульРаботаВБезопасномРежиме.ЗапросНаОчисткуРазрешенийИспользованияВнешнихРесурсов(Выборка.Узел));
КонецЦикла;
КонецЦикла;
Запросы.Добавить(МодульРаботаВБезопасномРежиме.ЗапросНаОчисткуРазрешенийИспользованияВнешнихРесурсов(
ОбщегоНазначения.ИдентификаторОбъектаМетаданных(Метаданные.Константы.КаталогСообщенийОбменаДаннымиДляLinux)));
Запросы.Добавить(МодульРаботаВБезопасномРежиме.ЗапросНаОчисткуРазрешенийИспользованияВнешнихРесурсов(
ОбщегоНазначения.ИдентификаторОбъектаМетаданных(Метаданные.Константы.КаталогСообщенийОбменаДаннымиДляWindows)));
Возврат Запросы;
КонецФункции
#КонецОбласти
#Область Прочее
Функция ИдентификаторЭтогоУзлаДляОбмена(УзелОбмена) Экспорт
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелОбмена);
КодУзла = СокрЛП(ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ПланыОбмена[ИмяПланаОбмена].ЭтотУзел(), "Код"));
Если ОбменДаннымиПовтИсп.ЭтоУзелРазделенногоОбменаДаннымиБСП(УзелОбмена) Тогда
ПрефиксыУзла = РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.ПрефиксыУзла(УзелОбмена);
ПрефиксЭтогоУзла = СокрЛП(ПрефиксыУзла.Префикс);
Если Не ПустаяСтрока(ПрефиксЭтогоУзла)
И СтрДлина(КодУзла) <= 2 Тогда
// В качестве кода для целей идентификации при обмене использует префикс,
// установленный при создании настройки подключения.
КодУзла = ПрефиксЭтогоУзла;
КонецЕсли;
КонецЕсли;
Возврат КодУзла;
КонецФункции
Функция ИдентификаторУзлаКорреспондентаДляОбмена(УзелОбмена) Экспорт
КодУзла = СокрЛП(ОбщегоНазначения.ЗначениеРеквизитаОбъекта(УзелОбмена, "Код"));
Если ОбменДаннымиПовтИсп.ЭтоУзелРазделенногоОбменаДаннымиБСП(УзелОбмена) Тогда
ПрефиксыУзла = РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.ПрефиксыУзла(УзелОбмена);
Если СтрДлина(КодУзла) <= 2
И Не ПустаяСтрока(ПрефиксыУзла.ПрефиксКорреспондента) Тогда
// В качестве кода для целей идентификации при обмене использует префикс,
// установленный при создании настройки подключения.
КодУзла = СокрЛП(ПрефиксыУзла.ПрефиксКорреспондента);
КонецЕсли;
КонецЕсли;
Возврат КодУзла;
КонецФункции
// Определяет является ли план обмена БСП разделенным.
//
// Параметры:
// ИмяПланаОбмена - Строка - имя проверяемого плана обмена.
//
// Возвращаемое значение:
// Тип - булево
//
Функция ЭтоРазделенныйПланОбменаБСП(Знач ИмяПланаОбмена) Экспорт
Возврат ОбменДаннымиПовтИсп.РазделенныеПланыОбменаБСП().Найти(ИмяПланаОбмена) <> Неопределено;
КонецФункции
// Формирует выборку измененных данных для передачи их в тот или иной узел плана обмена.
// Если обращение к методу выполняется в активной транзакции, то вызывает исключение.
// См. описание метода ПланыОбменаМенеджер.ВыбратьИзменения() в синтакс-помощнике.
//
Функция ВыбратьИзменения(Знач Узел, Знач НомерСообщения, Знач ФильтрВыборки = Неопределено) Экспорт
Если ТранзакцияАктивна() Тогда
ВызватьИсключение НСтр("ru = 'Выборка изменений данных запрещена в активной транзакции.'");
КонецЕсли;
Возврат ПланыОбмена.ВыбратьИзменения(Узел, НомерСообщения, ФильтрВыборки);
КонецФункции
Функция СтруктураПараметровWS() Экспорт
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("WSURLВебСервиса");
СтруктураПараметров.Вставить("WSИмяПользователя");
СтруктураПараметров.Вставить("WSПароль");
Возврат СтруктураПараметров;
КонецФункции
Функция ТаблицаМонитораОбменаДанными(Знач ПланыОбмена, Знач ДополнительныеСвойстваПланаОбмена = "") Экспорт
Запрос = Новый Запрос(
"ВЫБРАТЬ
| СценарииОбменовДаннымиНастройкиОбмена.УзелИнформационнойБазы КАК УзелИнформационнойБазы
|ПОМЕСТИТЬ СценарииСинхронизацииДанных
|ИЗ
| Справочник.СценарииОбменовДанными.НастройкиОбмена КАК СценарииОбменовДаннымиНастройкиОбмена
|ГДЕ
| СценарииОбменовДаннымиНастройкиОбмена.Ссылка.ИспользоватьРегламентноеЗадание = ИСТИНА
|
|СГРУППИРОВАТЬ ПО
| СценарииОбменовДаннымиНастройкиОбмена.УзелИнформационнойБазы
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПланыОбмена.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
|
| &ДополнительныеСвойстваПланаОбмена,
|
| ЕСТЬNULL(СостоянияОбменовДаннымиВыгрузка.РезультатВыполненияОбмена, 0) КАК РезультатПоследнейВыгрузкиДанных,
| ЕСТЬNULL(СостоянияОбменовДаннымиЗагрузка.РезультатВыполненияОбмена, 0) КАК РезультатПоследнейЗагрузкиДанных,
| ЕСТЬNULL(СостоянияОбменовДаннымиЗагрузка.ДатаНачала, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаНачалаПоследнейЗагрузки,
| ЕСТЬNULL(СостоянияОбменовДаннымиЗагрузка.ДатаОкончания, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаОкончанияПоследнейЗагрузки,
| ЕСТЬNULL(СостоянияОбменовДаннымиВыгрузка.ДатаНачала, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаНачалаПоследнейВыгрузки,
| ЕСТЬNULL(СостоянияОбменовДаннымиВыгрузка.ДатаОкончания, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаОкончанияПоследнейВыгрузки,
| ЕСТЬNULL(СостоянияУспешныхОбменовДаннымиЗагрузка.ДатаОкончания, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаОкончанияПоследнейУспешнойЗагрузки,
| ЕСТЬNULL(СостоянияУспешныхОбменовДаннымиВыгрузка.ДатаОкончания, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаОкончанияПоследнейУспешнойВыгрузки,
| ВЫБОР
| КОГДА СценарииСинхронизацииДанных.УзелИнформационнойБазы ЕСТЬ NULL
| ТОГДА 0
| ИНАЧЕ 1
| КОНЕЦ КАК РасписаниеНастроено,
| ОбщиеНастройкиУзловИнформационныхБаз.ВерсияКорреспондента КАК ВерсияКорреспондента,
| ОбщиеНастройкиУзловИнформационныхБаз.ПрефиксКорреспондента КАК ПрефиксКорреспондента,
| ОбщиеНастройкиУзловИнформационныхБаз.НастройкаЗавершена КАК НастройкаЗавершена,
| ВЫБОР
| КОГДА ЕСТЬNULL(СостоянияОбменовДаннымиВыгрузка.РезультатВыполненияОбмена, 0) = 0
| И ЕСТЬNULL(СостоянияОбменовДаннымиЗагрузка.РезультатВыполненияОбмена, 0) = 0
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ КАК ЕстьОшибки,
| ЕСТЬNULL(СообщенияДляСопоставленияДанных.ПолученоСообщениеДляСопоставленияДанных, ЛОЖЬ) КАК ПолученоСообщениеДляСопоставленияДанных,
| ЕСТЬNULL(СообщенияДляСопоставленияДанных.ДатаЗакладкиПоследнегоСообщения, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаСообщенияДляСопоставленияДанных
|ИЗ
| ПланыОбменаКонфигурации КАК ПланыОбмена
| ЛЕВОЕ СОЕДИНЕНИЕ ОбщиеНастройкиУзловИнформационныхБаз КАК ОбщиеНастройкиУзловИнформационныхБаз
| ПО (ОбщиеНастройкиУзловИнформационныхБаз.УзелИнформационнойБазы = ПланыОбмена.УзелИнформационнойБазы)
| ЛЕВОЕ СОЕДИНЕНИЕ СостоянияОбменовДаннымиЗагрузка КАК СостоянияОбменовДаннымиЗагрузка
| ПО (СостоянияОбменовДаннымиЗагрузка.УзелИнформационнойБазы = ПланыОбмена.УзелИнформационнойБазы)
| ЛЕВОЕ СОЕДИНЕНИЕ СостоянияОбменовДаннымиВыгрузка КАК СостоянияОбменовДаннымиВыгрузка
| ПО (СостоянияОбменовДаннымиВыгрузка.УзелИнформационнойБазы = ПланыОбмена.УзелИнформационнойБазы)
| ЛЕВОЕ СОЕДИНЕНИЕ СостоянияУспешныхОбменовДаннымиЗагрузка КАК СостоянияУспешныхОбменовДаннымиЗагрузка
| ПО (СостоянияУспешныхОбменовДаннымиЗагрузка.УзелИнформационнойБазы = ПланыОбмена.УзелИнформационнойБазы)
| ЛЕВОЕ СОЕДИНЕНИЕ СостоянияУспешныхОбменовДаннымиВыгрузка КАК СостоянияУспешныхОбменовДаннымиВыгрузка
| ПО (СостоянияУспешныхОбменовДаннымиВыгрузка.УзелИнформационнойБазы = ПланыОбмена.УзелИнформационнойБазы)
| ЛЕВОЕ СОЕДИНЕНИЕ СценарииСинхронизацииДанных КАК СценарииСинхронизацииДанных
| ПО (СценарииСинхронизацииДанных.УзелИнформационнойБазы = ПланыОбмена.УзелИнформационнойБазы)
| ЛЕВОЕ СОЕДИНЕНИЕ СообщенияДляСопоставленияДанных КАК СообщенияДляСопоставленияДанных
| ПО СообщенияДляСопоставленияДанных.УзелИнформационнойБазы = ПланыОбмена.УзелИнформационнойБазы
|
|УПОРЯДОЧИТЬ ПО
| ПланыОбмена.Наименование");
Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ДополнительныеСвойстваПланаОбмена,",
ДополнительныеСвойстваПланаОбменаСтрокой(ДополнительныеСвойстваПланаОбмена));
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
УстановитьПривилегированныйРежим(Истина);
ПолучитьПланыОбменаДляМонитора(МенеджерВременныхТаблиц, ПланыОбмена, ДополнительныеСвойстваПланаОбмена);
ПолучитьРезультатыОбменаДляМонитора(МенеджерВременныхТаблиц);
ПолучитьСостоянияОбменовДанными(МенеджерВременныхТаблиц);
ПолучитьСообщенияДляСопоставленияДанных(МенеджерВременныхТаблиц);
ПолучитьОбщиеНастройкиУзловИнформационныхБаз(МенеджерВременныхТаблиц);
НастройкиСинхронизации = Запрос.Выполнить().Выгрузить();
НастройкиСинхронизации.Колонки.Добавить("ВариантОбменаДанными", Новый ОписаниеТипов("Строка"));
НастройкиСинхронизации.Колонки.Добавить("ИмяПланаОбмена", Новый ОписаниеТипов("Строка"));
НастройкиСинхронизации.Колонки.Добавить("ДатаПоследнегоЗапуска", Новый ОписаниеТипов("Дата"));
НастройкиСинхронизации.Колонки.Добавить("ПредставлениеДатыПоследнегоЗапуска", Новый ОписаниеТипов("Строка"));
НастройкиСинхронизации.Колонки.Добавить("ПредставлениеДатыПоследнейЗагрузки", Новый ОписаниеТипов("Строка"));
НастройкиСинхронизации.Колонки.Добавить("ПредставлениеДатыПоследнейВыгрузки", Новый ОписаниеТипов("Строка"));
НастройкиСинхронизации.Колонки.Добавить("ПредставлениеДатыПоследнейУспешнойЗагрузки", Новый ОписаниеТипов("Строка"));
НастройкиСинхронизации.Колонки.Добавить("ПредставлениеДатыПоследнейУспешнойВыгрузки", Новый ОписаниеТипов("Строка"));
НастройкиСинхронизации.Колонки.Добавить("ПредставлениеДатыСообщенияДляСопоставленияДанных", Новый ОписаниеТипов("Строка"));
Для Каждого НастройкаСинхронизации Из НастройкиСинхронизации Цикл
НастройкаСинхронизации.ДатаПоследнегоЗапуска = Макс(НастройкаСинхронизации.ДатаНачалаПоследнейЗагрузки,
НастройкаСинхронизации.ДатаНачалаПоследнейВыгрузки);
НастройкаСинхронизации.ПредставлениеДатыПоследнегоЗапуска = ОтносительнаяДатаСинхронизации(
НастройкаСинхронизации.ДатаПоследнегоЗапуска);
НастройкаСинхронизации.ПредставлениеДатыПоследнейЗагрузки = ОтносительнаяДатаСинхронизации(
НастройкаСинхронизации.ДатаОкончанияПоследнейЗагрузки);
НастройкаСинхронизации.ПредставлениеДатыПоследнейВыгрузки = ОтносительнаяДатаСинхронизации(
НастройкаСинхронизации.ДатаОкончанияПоследнейВыгрузки);
НастройкаСинхронизации.ПредставлениеДатыПоследнейУспешнойЗагрузки = ОтносительнаяДатаСинхронизации(
НастройкаСинхронизации.ДатаОкончанияПоследнейУспешнойЗагрузки);
НастройкаСинхронизации.ПредставлениеДатыПоследнейУспешнойВыгрузки = ОтносительнаяДатаСинхронизации(
НастройкаСинхронизации.ДатаОкончанияПоследнейУспешнойВыгрузки);
НастройкаСинхронизации.ПредставлениеДатыСообщенияДляСопоставленияДанных = ОтносительнаяДатаСинхронизации(
МестноеВремя(НастройкаСинхронизации.ДатаСообщенияДляСопоставленияДанных));
НастройкаСинхронизации.ВариантОбменаДанными = ВариантОбменаДанными(НастройкаСинхронизации.УзелИнформационнойБазы);
НастройкаСинхронизации.ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(НастройкаСинхронизации.УзелИнформационнойБазы);
КонецЦикла;
Возврат НастройкиСинхронизации;
КонецФункции
Процедура ПроверитьВозможностьВыполненияОбменов(ПриложениеВИнтернете = Ложь) Экспорт
Если Не ПравоДоступа("Просмотр", Метаданные.ОбщиеКоманды.Синхронизировать) Тогда
Если ПриложениеВИнтернете Тогда
ВызватьИсключение НСтр("ru = 'Недостаточно прав для синхронизации данных с приложением в Интернете.'");
Иначе
ВызватьИсключение НСтр("ru = 'Недостаточно прав для синхронизации данных.'");
КонецЕсли;
ИначеЕсли ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы()
И Не ОбменДаннымиСлужебный.РежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском("ЗагрузкаРазрешена") Тогда
Если ПриложениеВИнтернете Тогда
ВызватьИсключение НСтр("ru = 'Приложение в Интернете находится в состоянии обновления.'");
Иначе
ВызватьИсключение НСтр("ru = 'Информационная база находится в состоянии обновления.'");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьИспользованиеОбменаДанными(УстановитьИспользование = Ложь) Экспорт
Если Не ПолучитьФункциональнуюОпцию("ИспользоватьСинхронизациюДанных") Тогда
Если Не ОбщегоНазначения.РазделениеВключено()
И УстановитьИспользование
И ПравоДоступа("Редактирование", Метаданные.Константы.ИспользоватьСинхронизациюДанных) Тогда
Попытка
Константы.ИспользоватьСинхронизациюДанных.Установить(Истина);
Исключение
ТекстСообщения = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(), УровеньЖурналаРегистрации.Ошибка,,,ТекстСообщения);
ВызватьИсключение ТекстСообщения;
КонецПопытки;
Иначе
ТекстСообщения = НСтр("ru = 'Синхронизация данных запрещена администратором.'");
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(), УровеньЖурналаРегистрации.Ошибка,,,ТекстСообщения);
ВызватьИсключение ТекстСообщения;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПараметрыОбмена() Экспорт
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("ВидТранспортаСообщенийОбмена", Неопределено);
СтруктураПараметров.Вставить("ВыполнятьЗагрузку", Истина);
СтруктураПараметров.Вставить("ВыполнятьВыгрузку", Истина);
СтруктураПараметров.Вставить("ТолькоПараметры", Ложь);
СтруктураПараметров.Вставить("ДлительнаяОперацияРазрешена", Ложь);
СтруктураПараметров.Вставить("ДлительнаяОперация", Ложь);
СтруктураПараметров.Вставить("ИдентификаторОперации", "");
СтруктураПараметров.Вставить("ИдентификаторФайла", "");
СтруктураПараметров.Вставить("ПараметрыАутентификации", Неопределено);
СтруктураПараметров.Вставить("СообщениеДляСопоставленияДанных", Ложь);
СтруктураПараметров.Вставить("ИнтервалОжиданияНаСервере", 0);
Возврат СтруктураПараметров;
КонецФункции
// Точка входа для выполнения итерации обмена данными - загрузки и выгрузки данных для узла плана обмена.
//
// Параметры:
// УзелИнформационнойБазы - ПланОбменаСсылка - узел плана обмена, для которого выполняется итерация обмена данными.
// ПараметрыОбменаДляУзла - Структура:
// * ВыполнятьЗагрузку - Булево - флаг необходимости выполнять загрузку данных.
// Необязательный, значение по умолчанию Истина.
// * ВыполнятьВыгрузку - Булево - флаг необходимости выполнять выгрузку данных.
// Необязательный, значение по умолчанию Истина.
// * ВидТранспортаСообщенийОбмена - ПеречислениеСсылка.ВидыТранспортаСообщенийОбмена - вид транспорта,
// который будет использоваться в процессе обмена данными.
// Если в РС значение не задано, то значение по умолчанию - Перечисления.ВидыТранспортаСообщенийОбмена.FILE.
// Необязательный, значение по умолчанию Неопределено.
// * ДлительнаяОперация - Булево - содержит сведения о том, является ли операция длительной.
// Необязательный, значение по умолчанию Ложь.
// * ИдентификаторОперации - Строка - содержит идентификатор длительной операции в виде строки.
// Необязательный, значение по умолчанию пустая строка.
// * ИдентификаторФайла - Строка - идентификатор файла сообщения в сервисе.
// Необязательный, значение по умолчанию пустая строка.
// * ДлительнаяОперацияРазрешена - Булево - содержит признак того, что длительная операция разрешена.
// Необязательный, значение по умолчанию Ложь.
// * ПараметрыАутентификации - Структура - содержит параметры аутентификации для обмена через Web-сервис.
// Необязательный, значение по умолчанию Неопределено.
// * ТолькоПараметры - Булево - содержит признак выборочной загрузки данных при обмене РИБ.
// Необязательный, значение по умолчанию Ложь.
// Отказ - Булево - флаг отказа; поднимается в случае возникновения ошибки при выполнении обмена.
// ДополнительныеПараметры - Структура - зарезервировано для служебного использования.
//
Процедура ВыполнитьОбменДаннымиДляУзлаИнформационнойБазы(УзелИнформационнойБазы,
ПараметрыОбмена, Отказ, ДополнительныеПараметры = Неопределено) Экспорт
Если ДополнительныеПараметры = Неопределено Тогда
ДополнительныеПараметры = Новый Структура;
КонецЕсли;
ДействиеЗагрузка = Перечисления.ДействияПриОбмене.ЗагрузкаДанных;
ДействиеВыгрузка = Перечисления.ДействияПриОбмене.ВыгрузкаДанных;
ПроверитьВозможностьВыполненияОбменов();
ПроверитьИспользованиеОбменаДанными();
// Обмен через внешнее соединение.
Если ПараметрыОбмена.ВидТранспортаСообщенийОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.COM Тогда
ПроверитьВозможностьВнешнегоСоединения();
Если ПараметрыОбмена.ВыполнятьЗагрузку Тогда
ВыполнитьДействиеОбменаДляУзлаИнформационнойБазыПоВнешнемуСоединению(Отказ,
УзелИнформационнойБазы, ДействиеЗагрузка, Неопределено);
КонецЕсли;
Если ПараметрыОбмена.ВыполнятьВыгрузку Тогда
ВыполнитьДействиеОбменаДляУзлаИнформационнойБазыПоВнешнемуСоединению(Отказ,
УзелИнформационнойБазы, ДействиеВыгрузка, Неопределено, ПараметрыОбмена.СообщениеДляСопоставленияДанных);
КонецЕсли;
ИначеЕсли ПараметрыОбмена.ВидТранспортаСообщенийОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.WS Тогда // Обмен через Web-сервис
Если ПараметрыОбмена.ВыполнятьЗагрузку Тогда
ВыполнитьДействиеОбменаДляУзлаИнформационнойБазыЧерезWebСервис(Отказ,
УзелИнформационнойБазы, ДействиеЗагрузка, ПараметрыОбмена);
КонецЕсли;
Если ПараметрыОбмена.ВыполнятьВыгрузку Тогда
ВыполнитьДействиеОбменаДляУзлаИнформационнойБазыЧерезWebСервис(Отказ,
УзелИнформационнойБазы, ДействиеВыгрузка, ПараметрыОбмена);
КонецЕсли;
Иначе // Обмен через обычные каналы связи.
ТолькоПараметры = ПараметрыОбмена.ТолькоПараметры;
ВидТранспортаСообщенийОбмена = ПараметрыОбмена.ВидТранспортаСообщенийОбмена;
Если ПараметрыОбмена.ВыполнятьЗагрузку Тогда
ВыполнитьДействиеОбменаДляУзлаИнформационнойБазы(Отказ, УзелИнформационнойБазы,
ДействиеЗагрузка, ВидТранспортаСообщенийОбмена, ТолькоПараметры, ДополнительныеПараметры);
КонецЕсли;
Если ПараметрыОбмена.ВыполнятьВыгрузку Тогда
ВыполнитьДействиеОбменаДляУзлаИнформационнойБазы(Отказ, УзелИнформационнойБазы,
ДействиеВыгрузка, ВидТранспортаСообщенийОбмена, ТолькоПараметры, ДополнительныеПараметры);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьWSПроксиПоПараметрамПодключения(
СтруктураНастроек,
СтрокаСообщенияОбОшибке = "",
СообщениеПользователю = "",
ДелатьКонтрольныйВызов = Ложь) Экспорт
Попытка
ПроверитьКорректностьФорматаАдресаWSПрокси(СтруктураНастроек.WSURLВебСервиса);
Исключение
СообщениеПользователю = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
СтрокаСообщенияОбОшибке = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису(), УровеньЖурналаРегистрации.Ошибка,,, СтрокаСообщенияОбОшибке);
Возврат Неопределено;
КонецПопытки;
Попытка
ПроверитьНедопустимыеСимволыВИмениПользователяWSПрокси(СтруктураНастроек.WSИмяПользователя);
Исключение
СообщениеПользователю = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
СтрокаСообщенияОбОшибке = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису(), УровеньЖурналаРегистрации.Ошибка,,, СтрокаСообщенияОбОшибке);
Возврат Неопределено;
КонецПопытки;
МестоположениеWSDL = "[URLВебСервиса]/ws/[ИмяСервиса]?wsdl";
МестоположениеWSDL = СтрЗаменить(МестоположениеWSDL, "[URLВебСервиса]", СтруктураНастроек.WSURLВебСервиса);
МестоположениеWSDL = СтрЗаменить(МестоположениеWSDL, "[ИмяСервиса]", СтруктураНастроек.WSИмяСервиса);
ПараметрыПодключения = ОбщегоНазначения.ПараметрыПодключенияWSПрокси();
ПараметрыПодключения.АдресWSDL = МестоположениеWSDL;
ПараметрыПодключения.URIПространстваИмен = СтруктураНастроек.WSURLПространстваИменСервиса;
ПараметрыПодключения.ИмяСервиса = СтруктураНастроек.WSИмяСервиса;
ПараметрыПодключения.ИмяПользователя = СтруктураНастроек.WSИмяПользователя;
ПараметрыПодключения.Пароль = СтруктураНастроек.WSПароль;
ПараметрыПодключения.Таймаут = СтруктураНастроек.WSТаймаут;
ПараметрыПодключения.ДелатьКонтрольныйВызов = ДелатьКонтрольныйВызов;
Попытка
WSПрокси = ОбщегоНазначения.СоздатьWSПрокси(ПараметрыПодключения);
Исключение
СообщениеПользователю = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
СтрокаСообщенияОбОшибке = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису(), УровеньЖурналаРегистрации.Ошибка,,, СтрокаСообщенияОбОшибке);
Возврат Неопределено;
КонецПопытки;
Возврат WSПрокси;
КонецФункции
// Выполняет действия по удалению настройки синхронизации данных.
//
// Параметры:
// УзелИнформационнойБазы - ПланОбменаСсылка - ссылка на удаляемый узел плана обмена.
//
Процедура УдалитьНастройкуСинхронизации(УзелИнформационнойБазы) Экспорт
ПроверитьВозможностьАдминистрированияОбменов();
Если Не ОбщегоНазначения.СсылкаСуществует(УзелИнформационнойБазы) Тогда
Возврат;
КонецЕсли;
УстановитьПривилегированныйРежим(Истина);
НачатьТранзакцию();
Попытка
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить(ОбщегоНазначения.ИмяТаблицыПоСсылке(УзелИнформационнойБазы));
ЭлементБлокировки.УстановитьЗначение("Ссылка", УзелИнформационнойБазы);
Блокировка.Заблокировать();
ОбщегоНазначения.УдалитьДанныеИзБезопасногоХранилища(УзелИнформационнойБазы);
ЗаблокироватьДанныеДляРедактирования(УзелИнформационнойБазы);
ОбъектУзла = УзелИнформационнойБазы.ПолучитьОбъект();
ОбъектУзла.Удалить();
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
// Выполняет действия по удалению настройки синхронизации данных с главным узлом РИБ.
//
// Параметры:
// УзелИнформационнойБазы - ПланОбменаСсылка - ссылка на главный узел.
//
Процедура УдалитьНастройкиСинхронизацииСГлавнымУзломРИБ(УзелИнформационнойБазы) Экспорт
УдалитьНастройкуСинхронизации(УзелИнформационнойБазы);
НастройкаПодчиненногоУзлаРИБЗавершена = Константы.НастройкаПодчиненногоУзлаРИБЗавершена.СоздатьМенеджерЗначения();
НастройкаПодчиненногоУзлаРИБЗавершена.Прочитать();
Если НастройкаПодчиненногоУзлаРИБЗавершена.Значение Тогда
НастройкаПодчиненногоУзлаРИБЗавершена.Значение = Ложь;
ОбновлениеИнформационнойБазы.ЗаписатьДанные(НастройкаПодчиненногоУзлаРИБЗавершена);
КонецЕсли;
КонецПроцедуры
// Устанавливает значение параметра "Загрузка" для свойства объекта "ОбменДанными".
//
// Параметры:
// Объект - Произвольный - объект, для которого устанавливается свойство.
// Значение - Булево - значение устанавливаемого свойства "Загрузка".
// ОтправкаНазад - Булево - признак необходимости регистрации данных к обратной отправке.
// УзелОбмена - ПланОбменаСсылка - признак необходимости регистрации данных к обратной отправке.
//
Процедура УстановитьОбменДаннымиЗагрузка(Объект, Значение = Истина, ОтправкаНазад = Ложь, УзелОбмена = Неопределено) Экспорт
Объект.ОбменДанными.Загрузка = Значение;
Если Не ОтправкаНазад
И УзелОбмена <> Неопределено
И НЕ УзелОбмена.Пустая() Тогда
ТипЗначенияОбъекта = ТипЗнч(Объект);
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗначенияОбъекта);
Если Метаданные.ПланыОбмена[УзелОбмена.Метаданные().Имя].Состав.Содержит(ОбъектМетаданных) Тогда
Объект.ОбменДанными.Отправитель = УзелОбмена;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция НазначениеПланаОбмена(ИмяПланаОбмена) Экспорт
Возврат ОбменДаннымиПовтИсп.НазначениеПланаОбмена(ИмяПланаОбмена);
КонецФункции
// Процедура удаления существующих движений документа при перепроведении (отмене проведения).
//
// Параметры:
// ДокументОбъект - ДокументОбъект - документ, движения которого требуется удалить.
//
Процедура УдалитьДвиженияУДокумента(ДокументОбъект) Экспорт
МассивОбрабатываемыхСтрокТаблицыДвижений = Новый Массив;
// Получение списка регистров, по которым существуют движения.
ТаблицаДвижений = ОпределитьНаличиеДвиженийПоДокументу(ДокументОбъект.Ссылка);
Для Каждого СтрокаДвижения Из ТаблицаДвижений Цикл
// Имя регистра передается как значение, полученное с помощью
// функции ПолноеИмя() метаданных регистра.
ПолноеИмяРегистра = СтрокаДвижения.ИмяТаблицыРегистра;
МассивОбрабатываемыхСтрокТаблицыДвижений.Добавить(СтрокаДвижения);
Набор = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмяРегистра).СоздатьНаборЗаписей();
Если Не ПравоДоступа("Изменение", Набор.Метаданные()) Тогда
// Отсутствуют права на всю таблицу регистра.
ТекстИсключения = НСтр("ru = 'Нарушение прав доступа: %1'");
ТекстИсключения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстИсключения, ПолноеИмяРегистра);
ВызватьИсключение ТекстИсключения;
КонецЕсли;
ОбменДаннымиСлужебный.УстановитьЗначениеЭлементаОтбора(Набор.Отбор, "Регистратор", ДокументОбъект.Ссылка);
// Набор не записывается сразу, чтобы не откатывать транзакцию, если впоследствии
// выяснится, что на один из регистров не хватает прав.
СтрокаДвижения.НаборЗаписей = Набор;
КонецЦикла;
ПроверкаДатЗапретаОтключена = ПроверкаДатЗапретаОтключена();
ОтключитьПроверкуДатЗапрета(Истина);
Попытка
Для Каждого СтрокаДвижения Из МассивОбрабатываемыхСтрокТаблицыДвижений Цикл
Попытка
Набор = СтрокаДвижения.НаборЗаписей; // РегистрНакопленияНаборЗаписей и т.п.
Набор.Записать();
Исключение
// Возможно "сработало" ограничение на уровне записей или подсистема даты запрета изменения.
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Операция не выполнена: %1
|%2'"),
СтрокаДвижения.ИмяТаблицыРегистра,
КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЦикла;
Исключение
ОтключитьПроверкуДатЗапрета(ПроверкаДатЗапретаОтключена);
ВызватьИсключение;
КонецПопытки;
ОтключитьПроверкуДатЗапрета(ПроверкаДатЗапретаОтключена);
Для Каждого Движение Из ДокументОбъект.Движения Цикл
Если Движение.Количество() > 0 Тогда
Движение.Очистить();
КонецЕсли;
КонецЦикла;
// Удаление записей регистрации из всех последовательностей.
Если ДокументОбъект.Метаданные().ЗаполнениеПоследовательностей = Метаданные.СвойстваОбъектов.ЗаполнениеПоследовательностей.ЗаполнятьАвтоматически Тогда
Для Каждого НаборЗаписейПоследовательности Из ДокументОбъект.ПринадлежностьПоследовательностям Цикл
Если НаборЗаписейПоследовательности.Количество() > 0 Тогда
НаборЗаписейПоследовательности.Очистить();
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
// Возвращает признак необходимости загрузки сообщения обмена данными.
//
// Возвращаемое значение:
// Булево - если Истина, то необходимо загрузить сообщение; Ложь - нет.
//
Функция ЗагрузитьСообщениеОбменаДанными() Экспорт
УстановитьПривилегированныйРежим(Истина);
Возврат Константы.ЗагрузитьСообщениеОбменаДанными.Получить();
КонецФункции
#КонецОбласти
#Область ОбработчикиСобытийПодсистемКонфигурации
// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления.
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
Обработчик = Обработчики.Добавить();
Обработчик.НачальноеЗаполнение = Истина;
Обработчик.Процедура = "ОбменДаннымиСервер.УстановитьКоличествоЭлементовВТранзакцииЗагрузкиДанныхПоУмолчанию";
Обработчик.ОбщиеДанные = Истина;
Обработчик = Обработчики.Добавить();
Обработчик.Версия = "*";
Обработчик.Процедура = "ОбменДаннымиСервер.УстановитьКодыПредопределенныхУзлов";
Обработчик.РежимВыполнения = "Оперативно";
Обработчик = Обработчики.Добавить();
Обработчик.Версия = "2.4.1.1";
Обработчик.Процедура = "ОбменДаннымиСервер.УдалитьРольНастройкаСинхронизацииДанных";
Обработчик.РежимВыполнения = "Оперативно";
Обработчик = Обработчики.Добавить();
Обработчик.Версия = "3.1.2.172";
Обработчик.Процедура = "ОбменДаннымиСервер.УстановитьКоличествоЭлементовВТранзакцииЗагрузкиДанныхПоУмолчанию";
Обработчик.РежимВыполнения = "Оперативно";
Обработчик.ОбщиеДанные = Истина;
Обработчик = Обработчики.Добавить();
Обработчик.Версия = "3.0.1.91";
Обработчик.Комментарий =
НСтр("ru = 'Перенос настроек подключения обменов данными в новый регистр ""Настройки транспорта обмена данными"".'");
Обработчик.Идентификатор = Новый УникальныйИдентификатор("8d5f1092-f569-4c03-aca9-65625809b853");
Обработчик.Процедура = "РегистрыСведений.НастройкиТранспортаОбменаДанными.ОбработатьДанныеДляПереходаНаНовуюВерсию";
Обработчик.РежимВыполнения = "Отложенно";
Обработчик.ЧитаемыеОбъекты = "РегистрСведений.УдалитьНастройкиТранспортаОбмена";
Обработчик.ИзменяемыеОбъекты = "РегистрСведений.УдалитьНастройкиТранспортаОбмена,РегистрСведений.НастройкиТранспортаОбменаДанными";
Обработчик.ОчередьОтложеннойОбработки = 1;
Обработчик.ЗапускатьИВПодчиненномУзлеРИБСФильтрами = Истина;
Обработчик.ПроцедураЗаполненияДанныхОбновления = "РегистрыСведений.НастройкиТранспортаОбменаДанными.ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию";
Обработчик.ПроцедураПроверки = "ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы";
Обработчик.БлокируемыеОбъекты = "РегистрСведений.УдалитьНастройкиТранспортаОбмена,РегистрСведений.НастройкиТранспортаОбменаДанными";
Обработчик = Обработчики.Добавить();
Обработчик.Версия = "3.0.1.91";
Обработчик.Комментарий =
НСтр("ru = 'Первоначальное заполнение настроек обмена данными XDTO.'");
Обработчик.Идентификатор = Новый УникальныйИдентификатор("2ea5ec7e-547b-4e8b-9c3f-d2d8652c8cdf");
Обработчик.Процедура = "РегистрыСведений.НастройкиОбменаДаннымиXDTO.ОбработатьДанныеДляПереходаНаНовуюВерсию";
Обработчик.РежимВыполнения = "Отложенно";
Обработчик.ЧитаемыеОбъекты = "РегистрСведений.НастройкиОбменаДаннымиXDTO";
Обработчик.ИзменяемыеОбъекты = "РегистрСведений.НастройкиОбменаДаннымиXDTO";
Обработчик.ОчередьОтложеннойОбработки = 1;
Обработчик.ЗапускатьИВПодчиненномУзлеРИБСФильтрами = Истина;
Обработчик.ПроцедураЗаполненияДанныхОбновления = "РегистрыСведений.НастройкиОбменаДаннымиXDTO.ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию";
Обработчик.ПроцедураПроверки = "ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы";
Обработчик.БлокируемыеОбъекты = "РегистрСведений.НастройкиОбменаДаннымиXDTO";
Обработчик = Обработчики.Добавить();
Обработчик.Версия = "3.0.1.281";
Обработчик.Комментарий =
НСтр("ru = 'Заполнение вспомогательных настроек обмена данными в регистре ""Общие настройки узлов информационных баз"".'");
Обработчик.Идентификатор = Новый УникальныйИдентификатор("e1cd64f1-3df9-4ea6-8076-1ba0627ba104");
Обработчик.Процедура = "РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.ОбработатьДанныеДляПереходаНаНовуюВерсию";
Обработчик.РежимВыполнения = "Отложенно";
Обработчик.ЧитаемыеОбъекты = "РегистрСведений.ОбщиеНастройкиУзловИнформационныхБаз";
Обработчик.ИзменяемыеОбъекты = "РегистрСведений.ОбщиеНастройкиУзловИнформационныхБаз";
Обработчик.ОчередьОтложеннойОбработки = 1;
Обработчик.ЗапускатьИВПодчиненномУзлеРИБСФильтрами = Истина;
Обработчик.ПроцедураЗаполненияДанныхОбновления = "РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию";
Обработчик.ПроцедураПроверки = "ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы";
Обработчик.БлокируемыеОбъекты = "РегистрСведений.ОбщиеНастройкиУзловИнформационныхБаз";
Обработчик = Обработчики.Добавить();
Обработчик.Версия = "3.1.1.22";
Обработчик.Комментарий =
НСтр("ru = 'Перенос результатов выполнения обменов данными в новый регистр.'");
Обработчик.Идентификатор = Новый УникальныйИдентификатор("012c28d7-bbe8-494f-87f7-620ffe5c99e2");
Обработчик.Процедура = "РегистрыСведений.РезультатыОбменаДанными.ОбработатьДанныеДляПереходаНаНовуюВерсию";
Обработчик.РежимВыполнения = "Отложенно";
Обработчик.ЧитаемыеОбъекты = "РегистрСведений.УдалитьРезультатыОбменаДанными";
Обработчик.ИзменяемыеОбъекты = "РегистрСведений.УдалитьРезультатыОбменаДанными,РегистрСведений.РезультатыОбменаДанными";
Обработчик.ОчередьОтложеннойОбработки = 1;
Обработчик.ЗапускатьИВПодчиненномУзлеРИБСФильтрами = Истина;
Обработчик.ПроцедураЗаполненияДанныхОбновления = "РегистрыСведений.РезультатыОбменаДанными.ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию";
Обработчик.ПроцедураПроверки = "ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы";
Обработчик.БлокируемыеОбъекты = "РегистрСведений.УдалитьРезультатыОбменаДанными,РегистрСведений.РезультатыОбменаДанными";
КонецПроцедуры
// См. ОбновлениеИнформационнойБазыБСП.ПередОбновлениемИнформационнойБазы.
Процедура ПередОбновлениемИнформационнойБазы(ПриЗапускеКлиентскогоПриложения, Перезапустить) Экспорт
Если ОбщегоНазначения.РазделениеВключено() Тогда
Возврат;
КонецЕсли;
Если НЕ ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы() Тогда
ВыполнитьСинхронизациюПриОтсутствииОбновленияИнформационнойБазы(ПриЗапускеКлиентскогоПриложения, Перезапустить);
Иначе
ЗагрузитьСообщениеПередОбновлениемИнформационнойБазы();
КонецЕсли;
КонецПроцедуры
// См. ОбновлениеИнформационнойБазыБСП.ПослеОбновленияИнформационнойБазы.
Процедура ПослеОбновленияИнформационнойБазы() Экспорт
Если ОбщегоНазначения.РазделениеВключено() Тогда
Возврат;
КонецЕсли;
РегистрыСведений.ОбработчикиСобытийСинхронизацииДанных.ЗарегистрироватьОбновлениеДанныхИнформационнойБазы();
ВыгрузитьСообщениеПослеОбновленияИнформационнойБазы();
КонецПроцедуры
// См. ГрупповоеИзменениеОбъектовПереопределяемый.ПриОпределенииОбъектовСРедактируемымиРеквизитами.
Процедура ПриОпределенииОбъектовСРедактируемымиРеквизитами(Объекты) Экспорт
Объекты.Вставить(Метаданные.Справочники.СценарииОбменовДанными.ПолноеИмя(), "РеквизитыНеРедактируемыеВГрупповойОбработке");
КонецПроцедуры
// См. РаботаВМоделиСервисаПереопределяемый.ПриВключенииРазделенияПоОбластямДанных.
Процедура ПриВключенииРазделенияПоОбластямДанных() Экспорт
Если Не Константы.ИспользоватьСинхронизациюДанных.Получить() Тогда
Константы.ИспользоватьСинхронизациюДанных.Установить(Истина);
КонецЕсли;
ВыполнитьОбновлениеПравилДляОбменаДанными();
КонецПроцедуры
// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииОбработчиковУстановкиПараметровСеанса.
Процедура ПриДобавленииОбработчиковУстановкиПараметровСеанса(Обработчики) Экспорт
Обработчики.Вставить("РежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском", "ОбменДаннымиСлужебный.УстановкаПараметровСеанса");
Обработчики.Вставить("ДатаОбновленияПовторноИспользуемыхЗначенийМРО", "ОбменДаннымиСлужебный.УстановкаПараметровСеанса");
Обработчики.Вставить("ПравилаВыборочнойРегистрацииОбъектов", "ОбменДаннымиСлужебный.УстановкаПараметровСеанса");
Обработчики.Вставить("ПравилаРегистрацииОбъектов", "ОбменДаннымиСлужебный.УстановкаПараметровСеанса");
Обработчики.Вставить("ПаролиСинхронизацииДанных", "ОбменДаннымиСлужебный.УстановкаПараметровСеанса");
Обработчики.Вставить("ПриоритетныеДанныеОбмена", "ОбменДаннымиСлужебный.УстановкаПараметровСеанса");
Обработчики.Вставить("ОшибкаРасхожденияВерсийПриПолученииДанных", "ОбменДаннымиСлужебный.УстановкаПараметровСеанса");
Обработчики.Вставить("ПараметрыСеансаСинхронизацииДанных", "ОбменДаннымиСлужебный.УстановкаПараметровСеанса");
КонецПроцедуры
// См. ОбщегоНазначенияПереопределяемый.ПриОпределенииПоддерживаемыхВерсийПрограммныхИнтерфейсов.
Процедура ПриОпределенииПоддерживаемыхВерсийПрограммныхИнтерфейсов(Знач СтруктураПоддерживаемыхВерсий) Экспорт
МассивВерсий = Новый Массив;
МассивВерсий.Добавить("2.0.1.6");
МассивВерсий.Добавить("2.1.1.7");
МассивВерсий.Добавить("3.0.1.1");
СтруктураПоддерживаемыхВерсий.Вставить("ОбменДанными", МассивВерсий);
КонецПроцедуры
// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииПараметровРаботыКлиентаПриЗапуске.
Процедура ПриДобавленииПараметровРаботыКлиентаПриЗапуске(Параметры) Экспорт
УстановитьПривилегированныйРежим(Истина);
Параметры.Вставить("ИмяПланаОбменаРИБ", ?(ЭтоПодчиненныйУзелРИБ(), ГлавныйУзел().Метаданные().Имя, ""));
Параметры.Вставить("ГлавныйУзел", ГлавныйУзел());
Если ОткрытьПомощникСозданияОбменаДаннымиДляНастройкиПодчиненногоУзла() Тогда
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Взаимодействия") Тогда
МодульВзаимодействия = ОбщегоНазначения.ОбщийМодуль("Взаимодействия");
МодульВзаимодействия.ВыполнитьПолныйПерерасчетСостояний();
КонецЕсли;
Параметры.Вставить("ОткрытьПомощникСозданияОбменаДаннымиДляНастройкиПодчиненногоУзла");
КонецЕсли;
УстановитьПривилегированныйРежим(Ложь);
Если Параметры.Свойство("ОткрытьПомощникСозданияОбменаДаннымиДляНастройкиПодчиненногоУзла") Тогда
ЭтотУзел = ПланыОбмена[Параметры.ИмяПланаОбменаРИБ].ЭтотУзел();
Параметры.Вставить("ИдентификаторНастройкиУзлаРИБ", СохраненныйВариантНастройкиУзлаПланаОбмена(ЭтотУзел));
КонецЕсли;
Если Не Параметры.Свойство("ОткрытьПомощникСозданияОбменаДаннымиДляНастройкиПодчиненногоУзла")
И ПравоДоступа("Просмотр", Метаданные.ОбщиеКоманды.Синхронизировать) Тогда
Параметры.Вставить("ПроверитьНеобходимостьОбновленияКонфигурацииПодчиненногоУзла");
КонецЕсли;
КонецПроцедуры
// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииПараметровРаботыКлиента.
Процедура ПриДобавленииПараметровРаботыКлиента(Параметры) Экспорт
УстановитьПривилегированныйРежим(Истина);
Параметры.Вставить("ГлавныйУзел", ГлавныйУзел());
КонецПроцедуры
// См. УправлениеДоступомПереопределяемый.ПриЗаполненииПоставляемыхПрофилейГруппДоступа
Процедура ПриЗаполненииПоставляемыхПрофилейГруппДоступа(ОписанияПрофилей, ПараметрыОбновления) Экспорт
// Профиль "Синхронизация данных с другими программами".
ОписаниеПрофиля = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступом").НовоеОписаниеПрофиляГруппДоступа();
ОписаниеПрофиля.Идентификатор = ПрофильДоступаСинхронизацияДанныхСДругимиПрограммами();
ОписаниеПрофиля.Наименование =
НСтр("ru = 'Синхронизация данных с другими программами'", ОбщегоНазначения.КодОсновногоЯзыка());
ОписаниеПрофиля.Описание =
НСтр("ru = 'Дополнительно назначается тем пользователям, которым должны быть доступны средства
|для мониторинга и синхронизации данных с другими программами.'");
// Основные возможности профиля.
РолиПрофиля = СтрРазделить(РолиПрофиляДоступаСинхронизацияДанныхСДругимиПрограммами(), ",");
Для Каждого Роль Из РолиПрофиля Цикл
ОписаниеПрофиля.Роли.Добавить(СокрЛП(Роль));
КонецЦикла;
ОписанияПрофилей.Добавить(ОписаниеПрофиля);
КонецПроцедуры
// Параметры:
// ТекущиеДела - см. ТекущиеДелаСервер.ТекущиеДела.
//
Процедура ПриЗаполненииСпискаТекущихДел(ТекущиеДела) Экспорт
Если Не ПолучитьФункциональнуюОпцию("ИспользоватьСинхронизациюДанных") Тогда
Возврат;
КонецЕсли;
ПриЗаполненииСпискаТекущихДелПредупрежденияСинхронизации(ТекущиеДела);
ПриЗаполненииСпискаТекущихДелНеобходимоОбновление(ТекущиеДела);
ПриЗаполненииСпискаТекущихДелПроверитьСовместимостьСТекущейВерсией(ТекущиеДела);
КонецПроцедуры
// См. РегламентныеЗаданияПереопределяемый.ПриОпределенииНастроекРегламентныхЗаданий
Процедура ПриОпределенииНастроекРегламентныхЗаданий(Зависимости) Экспорт
Зависимость = Зависимости.Добавить();
Зависимость.РегламентноеЗадание = Метаданные.РегламентныеЗадания.УдалениеНеактуальнойИнформацииСинхронизации;
Зависимость.ФункциональнаяОпция = Метаданные.ФункциональныеОпции.ИспользоватьСинхронизациюДанных;
Зависимость.РаботаетСВнешнимиРесурсами = Истина;
Зависимость = Зависимости.Добавить();
Зависимость.РегламентноеЗадание = Метаданные.РегламентныеЗадания.СинхронизацияДанных;
Зависимость.РаботаетСВнешнимиРесурсами = Истина;
Зависимость.Параметризуется = Истина;
КонецПроцедуры
// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииПереименованийОбъектовМетаданных.
Процедура ПриДобавленииПереименованийОбъектовМетаданных(Итог) Экспорт
Библиотека = "СтандартныеПодсистемы";
ОбщегоНазначения.ДобавитьПереименование(
Итог, "2.1.2.5", "Роль.ВыполнениеОбменовДанными", "Роль.ВыполнениеСинхронизацииДанных", Библиотека);
КонецПроцедуры
// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииИсключенийПоискаСсылок.
Процедура ПриДобавленииИсключенийПоискаСсылок(ИсключенияПоискаСсылок) Экспорт
ИсключенияПоискаСсылок.Добавить(Метаданные.РегистрыСведений.РезультатыОбменаДанными.ПолноеИмя());
КонецПроцедуры
// См. РаботаВБезопасномРежимеПереопределяемый.ПриЗаполненииРазрешенийНаДоступКВнешнимРесурсам.
Процедура ПриЗаполненииРазрешенийНаДоступКВнешнимРесурсам(ЗапросыРазрешений) Экспорт
Если Не Константы.ИспользоватьСинхронизациюДанных.Получить() Тогда
Возврат;
КонецЕсли;
СформироватьЗапросыНаИспользованиеВнешнихРесурсов(ЗапросыРазрешений);
КонецПроцедуры
// См. ИнтеграцияПодсистемБСП.ПриРегистрацииМенеджеровВнешнихМодулей
Процедура ПриРегистрацииМенеджеровВнешнихМодулей(Менеджеры) Экспорт
Менеджеры.Добавить(ОбменДаннымиСервер);
КонецПроцедуры
// См. ОчередьЗаданийПереопределяемый.ПриОпределенииПсевдонимовОбработчиков.
Процедура ПриОпределенииПсевдонимовОбработчиков(СоответствиеИменПсевдонимам) Экспорт
СоответствиеИменПсевдонимам.Вставить("ОбменДаннымиСервер.ВыполнитьОбменДаннымиСВнешнейСистемой");
КонецПроцедуры
// См. ИнтеграцияПодсистемБСП.ПриОпределенииОбъектовИсключаемыхИзПроверки.
Процедура ПриОпределенииОбъектовИсключаемыхИзПроверки(Объекты) Экспорт
Объекты.Добавить(Метаданные.РегистрыСведений.СоответствияОбъектовИнформационныхБаз);
КонецПроцедуры
#КонецОбласти
#Область ФункцииСвойства
// Возвращаемое значение:
// Строка
//
Функция СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису() Экспорт
Возврат НСтр("ru = 'Обмен данными.Установка подключения к web-сервису'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
// Возвращаемое значение:
// Строка
//
Функция СобытиеЖурналаРегистрацииЗагрузкаПравилДляОбменаДанными() Экспорт
Возврат НСтр("ru = 'Обмен данными.Загрузка правил'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
// Возвращаемое значение:
// Строка
//
Функция СобытиеЖурналаРегистрацииСозданиеОбменаДанными() Экспорт
Возврат НСтр("ru = 'Обмен данными.Создание обмена данными'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
// Возвращаемое значение:
// Строка
//
Функция СобытиеЖурналаРегистрацииУдалениеОбменаДанными() Экспорт
Возврат НСтр("ru = 'Обмен данными.Удаление обмена данными'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
// Возвращаемое значение:
// Строка
//
Функция СобытиеЖурналаРегистрацииРегистрацияДанныхДляНачальнойВыгрузки() Экспорт
Возврат НСтр("ru = 'Обмен данными.Регистрация данных для начальной выгрузки'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
// Возвращаемое значение:
// Строка
//
Функция СобытиеЖурналаРегистрацииВыгрузкаДанныхДляСопоставления() Экспорт
Возврат НСтр("ru = 'Обмен данными.Выгрузка данных для сопоставления'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
// Возвращаемое значение:
// Строка
//
Функция СобытиеЖурналаРегистрацииУдалениеВременногоФайла() Экспорт
Возврат НСтр("ru = 'Обмен данными.Удаление временного файла'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
// Возвращаемое значение:
// Строка
//
Функция СобытиеЖурналаРегистрацииОбменДанными() Экспорт
Возврат НСтр("ru = 'Обмен данными'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
// Возвращаемое значение:
// Строка
//
Функция СобытиеЖурналаРегистрацииВыгрузкаДанныхВСервисПередачиФайлов() Экспорт
Возврат НСтр("ru = 'Обмен данными.Сервис передачи файлов.Выгрузка данных'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
// Возвращаемое значение:
// Строка
//
Функция СобытиеЖурналаРегистрацииЗагрузкаДанныхИзСервисаПередачиФайлов() Экспорт
Возврат НСтр("ru = 'Обмен данными.Сервис передачи файлов.Загрузка данных'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции
#КонецОбласти
#Область ИнициализацияСтруктурыНастроекОбмена
Функция ПсевдонимПредопределенногоУзла(УзелКорреспондента) Экспорт
Если Не ЭтоПланОбменаXDTO(УзелКорреспондента) Тогда
Возврат "";
КонецЕсли;
Запрос = Новый Запрос(
"ВЫБРАТЬ
| ПсевдонимыПредопределенныхУзлов.КодУзла КАК КодУзла
|ИЗ
| РегистрСведений.ПсевдонимыПредопределенныхУзлов КАК ПсевдонимыПредопределенныхУзлов
|ГДЕ
| ПсевдонимыПредопределенныхУзлов.Корреспондент = &УзелИнформационнойБазы");
Запрос.УстановитьПараметр("УзелИнформационнойБазы", УзелКорреспондента);
ПсевдонимПредопределенногоУзла = "";
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ПсевдонимПредопределенногоУзла = СокрЛП(Выборка.КодУзла);
КонецЕсли;
Возврат ПсевдонимПредопределенногоУзла;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция МодульПомощникНастройкиСинхронизацииДанныхМеждуПриложениямиВИнтернете() Экспорт
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса") Тогда
Возврат ОбщегоНазначения.ОбщийМодуль("Обработки.ПомощникНастройкиСинхронизацииДанныхМеждуПриложениямиВИнтернете");
КонецЕсли;
Возврат Неопределено;
КонецФункции
Функция МодульПомощникИнтерактивногоОбменаДаннымиВМоделиСервиса() Экспорт
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса") Тогда
Возврат ОбщегоНазначения.ОбщийМодуль("Обработки.ПомощникИнтерактивногоОбменаДаннымиВМоделиСервиса");
КонецЕсли;
Возврат Неопределено;
КонецФункции
Функция МодульПомощникСозданияОбменаДанными() Экспорт
Возврат ОбщегоНазначения.ОбщийМодуль("Обработки.ПомощникСозданияОбменаДанными");
КонецФункции
Функция МодульПомощникИнтерактивногоОбменаДанными() Экспорт
Возврат ОбщегоНазначения.ОбщийМодуль("Обработки.ПомощникИнтерактивногоОбменаДанными");
КонецФункции
Функция ПредопределенныеУзлыПлановОбменаБСП()
Результат = Новый Массив;
Для Каждого ИмяПланаОбмена Из ОбменДаннымиПовтИсп.ПланыОбменаБСП() Цикл
Результат.Добавить(ПланыОбмена[ИмяПланаОбмена].ЭтотУзел());
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ОтключитьПроверкуДатЗапрета(Отключить = Истина)
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ДатыЗапретаИзменения") Тогда
МодульДатыЗапретаИзменения = ОбщегоНазначения.ОбщийМодуль("ДатыЗапретаИзменения");
МодульДатыЗапретаИзменения.ОтключитьПроверкуДатЗапрета(Отключить);
КонецЕсли;
КонецПроцедуры
Функция ПроверкаДатЗапретаОтключена()
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ДатыЗапретаИзменения") Тогда
МодульДатыЗапретаИзменения = ОбщегоНазначения.ОбщийМодуль("ДатыЗапретаИзменения");
Возврат МодульДатыЗапретаИзменения.ПроверкаДатЗапретаОтключена();
КонецЕсли;
Возврат Ложь;
КонецФункции
Процедура ПроверитьНедопустимыеСимволыВИмениПользователяWSПрокси(Знач ИмяПользователя)
НедопустимыеСимволы = НедопустимыеСимволыВИмениПользователяWSПрокси();
Если СтрокаСодержитСимвол(ИмяПользователя, НедопустимыеСимволы) Тогда
СтрокаСообщения = НСтр("ru = 'В имени пользователя %1 содержатся недопустимые символы.
|Имя пользователя не должно содержать символы %2.'");
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, ИмяПользователя, НедопустимыеСимволы);
ВызватьИсключение СтрокаСообщения;
КонецЕсли;
КонецПроцедуры
Процедура ПроверитьКорректностьФорматаАдресаWSПрокси(Знач АдресWSПрокси)
ЭтоИнтернетАдрес = Ложь;
ДопустимыеПрефиксыWSПрокси = ДопустимыеПрефиксыWSПрокси();
Для Каждого Префикс Из ДопустимыеПрефиксыWSПрокси Цикл
Если Лев(НРег(АдресWSПрокси), СтрДлина(Префикс)) = НРег(Префикс) Тогда
ЭтоИнтернетАдрес = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ЭтоИнтернетАдрес Тогда
СтрокаПрефиксов = "";
Для Каждого Префикс Из ДопустимыеПрефиксыWSПрокси Цикл
СтрокаПрефиксов = СтрокаПрефиксов + ?(ПустаяСтрока(СтрокаПрефиксов), """", " или """) + Префикс + """";
КонецЦикла;
СтрокаСообщения = НСтр("ru = 'Неверный формат адреса ""%1"".
|Адрес должен начинаться с префикса Интернет протокола %2 (например: ""http://myserver.com/service"").'");
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, АдресWSПрокси, СтрокаПрефиксов);
ВызватьИсключение СтрокаСообщения;
КонецЕсли;
КонецПроцедуры
Функция СтрокаСодержитСимвол(Знач Строка, Знач СтрокаСимволов)
Для Индекс = 1 По СтрДлина(СтрокаСимволов) Цикл
Символ = Сред(СтрокаСимволов, Индекс, 1);
Если СтрНайти(Строка, Символ) <> 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
Функция ДопустимыеПрефиксыWSПрокси()
Результат = Новый Массив();
Результат.Добавить("http");
Результат.Добавить("https");
Возврат Результат;
КонецФункции
Процедура ВыполнитьОбновлениеНастроекОбмена(УзелИнформационнойБазы)
Если ОбменДаннымиПовтИсп.ЭтоУзелОбменаСообщениями(УзелИнформационнойБазы) Тогда
Возврат;
КонецЕсли;
НаборУдалитьНастройкиТранспортаОбмена = РегистрыСведений.УдалитьНастройкиТранспортаОбмена.СоздатьНаборЗаписей();
НаборУдалитьНастройкиТранспортаОбмена.Отбор.УзелИнформационнойБазы.Установить(УзелИнформационнойБазы);
НаборУдалитьНастройкиТранспортаОбмена.Прочитать();
СостояниеОбработки = ОбновлениеИнформационнойБазы.ОбъектОбработан(НаборУдалитьНастройкиТранспортаОбмена);
Если Не СостояниеОбработки.Обработан Тогда
РегистрыСведений.НастройкиТранспортаОбменаДанными.ПеренестиНастройкиТранспортаОбменаДаннымиКорреспондента(УзелИнформационнойБазы);
КонецЕсли;
НаборОбщиеНастройкиУзловИнформационныхБаз = РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.СоздатьНаборЗаписей();
НаборОбщиеНастройкиУзловИнформационныхБаз.Отбор.УзелИнформационнойБазы.Установить(УзелИнформационнойБазы);
НаборОбщиеНастройкиУзловИнформационныхБаз.Прочитать();
Если НаборОбщиеНастройкиУзловИнформационныхБаз.Количество() = 0 Тогда
РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.ОбновитьОбщиеНастройкиКорреспондента(УзелИнформационнойБазы);
Иначе
СостояниеОбработки = ОбновлениеИнформационнойБазы.ОбъектОбработан(НаборОбщиеНастройкиУзловИнформационныхБаз);
Если Не СостояниеОбработки.Обработан Тогда
РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.ОбновитьОбщиеНастройкиКорреспондента(УзелИнформационнойБазы);
КонецЕсли;
КонецЕсли;
Если ЭтоПланОбменаXDTO(УзелИнформационнойБазы) Тогда
НаборНастройкиОбменаДаннымиXDTO = РегистрыСведений.НастройкиОбменаДаннымиXDTO.СоздатьНаборЗаписей();
НаборНастройкиОбменаДаннымиXDTO.Отбор.УзелИнформационнойБазы.Установить(УзелИнформационнойБазы);
НаборНастройкиОбменаДаннымиXDTO.Прочитать();
Если НаборНастройкиОбменаДаннымиXDTO.Количество() = 0 Тогда
РегистрыСведений.НастройкиОбменаДаннымиXDTO.ОбновитьНастройкиОбменаДаннымиXDTOКорреспондента(УзелИнформационнойБазы);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
#Область ОбщиеПроцедурыМеханизмовКонвертацииДанных
Процедура ВыполнитьОтложенноеПроведениеДокументов(
ДокументыДляОтложенногоПроведения,
УзелКорреспондента,
ДополнительныеСвойстваДляОтложенногоПроведения = Неопределено) Экспорт
Если ДокументыДляОтложенногоПроведения.Количество() = 0 Тогда
Возврат; // нет документов в очереди
КонецЕсли;
// Сворачиваем таблицу по уникальным полям.
ДокументыДляОтложенногоПроведения.Свернуть("ДокументСсылка, ДатаДокумента");
// Сортируем документы по возрастанию даты документов.
ОбъектСравнения = Новый СравнениеЗначений;
ДокументыДляОтложенногоПроведения.Сортировать("ДатаДокумента, ДокументСсылка", ОбъектСравнения);
ПроверкаДатЗапретаОтключена = ПроверкаДатЗапретаОтключена();
ОтключитьПроверкуДатЗапрета(Истина);
Попытка
Для Каждого СтрокаТаблицы Из ДокументыДляОтложенногоПроведения Цикл
Если СтрокаТаблицы.ДокументСсылка.Пустая() Тогда
Продолжить;
КонецЕсли;
Если Не ОбщегоНазначения.СсылкаСуществует(СтрокаТаблицы.ДокументСсылка) Тогда
Продолжить;
КонецЕсли;
ДополнительныеСвойстваОбъекта = Неопределено;
Если ДополнительныеСвойстваДляОтложенногоПроведения <> Неопределено Тогда
ДополнительныеСвойстваОбъекта = ДополнительныеСвойстваДляОтложенногоПроведения.Получить(СтрокаТаблицы.ДокументСсылка);
КонецЕсли;
ВыполнитьПроведениеДокументаПриЗагрузке(
УзелКорреспондента,
СтрокаТаблицы.ДокументСсылка,
Истина,
ДополнительныеСвойстваОбъекта);
КонецЦикла;
Исключение
ОтключитьПроверкуДатЗапрета(ПроверкаДатЗапретаОтключена);
ВызватьИсключение;
КонецПопытки;
ОтключитьПроверкуДатЗапрета(ПроверкаДатЗапретаОтключена);
КонецПроцедуры
Процедура ВыполнитьПроведениеДокументаПриЗагрузке(
УзелКорреспондента,
ДокументСсылка,
РегистрироватьПроблемыВРезультатахОбмена,
ДополнительныеСвойстваОбъекта = Неопределено) Экспорт
ОписаниеОшибки = "";
ДокументПроведенУспешно = Ложь;
НачатьТранзакцию();
Попытка
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить(ОбщегоНазначения.ИмяТаблицыПоСсылке(ДокументСсылка));
ЭлементБлокировки.УстановитьЗначение("Ссылка", ДокументСсылка);
Блокировка.Заблокировать();
Объект = ДокументСсылка.ПолучитьОбъект();
// Устанавливаем узел-отправитель для предотвращения регистрации объекта на узле, для которого производим загрузку
// проведение выполняем не в режиме загрузки.
УстановитьОбменДаннымиЗагрузка(Объект, Ложь, Ложь, УзелКорреспондента);
Если ДополнительныеСвойстваОбъекта <> Неопределено Тогда
Для Каждого Свойство Из ДополнительныеСвойстваОбъекта Цикл
Объект.ДополнительныеСвойства.Вставить(Свойство.Ключ, Свойство.Значение);
КонецЦикла;
КонецЕсли;
Объект.ДополнительныеСвойства.Вставить("ОтложенноеПроведение");
Если Объект.ПроверитьЗаполнение() Тогда
// При проведении документа снимаем запрет на выполнение ПРО,
// т.к. ПРО были проигнорированы при обычной записи документа с целью оптимизации скорости загрузки данных.
Если Объект.ДополнительныеСвойства.Свойство("ОтключитьМеханизмРегистрацииОбъектов") Тогда
Объект.ДополнительныеСвойства.Удалить("ОтключитьМеханизмРегистрацииОбъектов");
КонецЕсли;
Объект.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения");
// Выполняем попытку проведения документа.
Объект.Записать(РежимЗаписиДокумента.Проведение);
ДокументПроведенУспешно = Объект.Проведен;
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ОписаниеОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
ДокументПроведенУспешно = Ложь;
КонецПопытки;
Если Не ДокументПроведенУспешно Тогда
ЗарегистрироватьОшибкуПроведенияДокумента(
Объект, УзелКорреспондента, ОписаниеОшибки, РегистрироватьПроблемыВРезультатахОбмена);
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьОтложеннуюЗаписьОбъектов(ОбъектыДляОтложеннойЗаписи, УзелКорреспондента) Экспорт
Если ОбъектыДляОтложеннойЗаписи.Количество() = 0 Тогда
Возврат; // Нет объектов в очереди
КонецЕсли;
ПроверкаДатЗапретаОтключена = ПроверкаДатЗапретаОтключена();
ОтключитьПроверкуДатЗапрета(Истина);
Попытка
Для Каждого ОбъектСоответствия Из ОбъектыДляОтложеннойЗаписи Цикл
Если ОбъектСоответствия.Ключ.Пустая() Тогда
Продолжить;
КонецЕсли;
Если Не ОбщегоНазначения.СсылкаСуществует(ОбъектСоответствия.Ключ) Тогда
Продолжить;
КонецЕсли;
ОписаниеОшибки = "";
ОбъектЗаписанУспешно = Ложь;
НачатьТранзакцию();
Попытка
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить(ОбщегоНазначения.ИмяТаблицыПоСсылке(ОбъектСоответствия.Ключ));
ЭлементБлокировки.УстановитьЗначение("Ссылка", ОбъектСоответствия.Ключ);
Блокировка.Заблокировать();
Объект = ОбъектСоответствия.Ключ.ПолучитьОбъект();
// Устанавливаем узел-отправитель для предотвращения регистрации объекта на узле, для которого производим загрузку
// проведение выполняем не в режиме загрузки.
УстановитьОбменДаннымиЗагрузка(Объект, Ложь, Ложь, УзелКорреспондента);
ДополнительныеСвойства = ОбъектСоответствия.Значение;
Для Каждого Свойство Из ДополнительныеСвойства Цикл
Объект.ДополнительныеСвойства.Вставить(Свойство.Ключ, Свойство.Значение);
КонецЦикла;
Объект.ДополнительныеСвойства.Вставить("ОтложеннаяЗапись");
Если Объект.ПроверитьЗаполнение() Тогда
// При проведении документа снимаем запрет на выполнение ПРО,
// т.к. ПРО были проигнорированы при обычной записи с целью оптимизации скорости загрузки данных.
Если Объект.ДополнительныеСвойства.Свойство("ОтключитьМеханизмРегистрацииОбъектов") Тогда
Объект.ДополнительныеСвойства.Удалить("ОтключитьМеханизмРегистрацииОбъектов");
КонецЕсли;
Объект.ДополнительныеСвойства.Вставить("ПропуститьПроверкуЗапретаИзменения");
// Выполняем попытку записи объекта.
СведенияОВерсииОбъекта = Неопределено;
Если Объект.ДополнительныеСвойства.Свойство("СведенияОВерсииОбъекта", СведенияОВерсииОбъекта) Тогда
ОбменДаннымиСобытия.ПриСозданииВерсииОбъекта(Объект, СведенияОВерсииОбъекта, Истина, УзелКорреспондента);
КонецЕсли;
Объект.Записать();
ОбъектЗаписанУспешно = Истина;
Иначе
ОбъектЗаписанУспешно = Ложь;
ОписаниеОшибки = НСтр("ru = 'Ошибка проверки заполнения реквизитов'");
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ОписаниеОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
ОбъектЗаписанУспешно = Ложь;
КонецПопытки;
Если Не ОбъектЗаписанУспешно Тогда
ЗарегистрироватьОшибкуЗаписиОбъекта(Объект, УзелКорреспондента, ОписаниеОшибки);
КонецЕсли;
КонецЦикла;
Исключение
ОтключитьПроверкуДатЗапрета(ПроверкаДатЗапретаОтключена);
ВызватьИсключение;
КонецПопытки;
ОтключитьПроверкуДатЗапрета(ПроверкаДатЗапретаОтключена);
КонецПроцедуры
#КонецОбласти
#Область ОбновлениеИнформационнойБазы
Процедура УстановитьКоличествоЭлементовВТранзакцииЗагрузкиДанныхПоУмолчанию() Экспорт
Если Не ОбщегоНазначения.РазделениеВключено()
И КоличествоЭлементовВТранзакцииЗагрузкиДанных() = 0 Тогда
УстановитьКоличествоЭлементовВТранзакцииЗагрузкиДанных(1);
КонецЕсли;
КонецПроцедуры
Процедура УстановитьКодыПредопределенныхУзлов() Экспорт
КодИзМоделиСервиса = "";
Если ОбщегоНазначения.РазделениеВключено()
И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных()
И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса") Тогда
МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
МодульОбменДаннымиВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиВМоделиСервиса");
КодИзМоделиСервиса = СокрЛП(МодульОбменДаннымиВМоделиСервиса.КодУзлаПланаОбменаВСервисе(МодульРаботаВМоделиСервиса.ЗначениеРазделителяСеанса()));
КонецЕсли;
КоллекцияУзлов = Новый Массив;
Для Каждого УзелСсылка Из ПредопределенныеУзлыПлановОбменаБСП() Цикл
Если Не ЭтоПланОбменаXDTO(УзелСсылка) Тогда
Продолжить;
ИначеЕсли Не ОбменДаннымиXDTOСервер.ПоддерживаетсяВерсияСИдентификаторомОбменаДанными(УзелСсылка) Тогда
Продолжить;
КонецЕсли;
КоллекцияУзлов.Добавить(УзелСсылка);
КонецЦикла;
НачатьТранзакцию();
Попытка
Блокировка = Новый БлокировкаДанных;
Для Каждого УзелСсылка Из КоллекцияУзлов Цикл
ЭлементБлокировки = Блокировка.Добавить(ОбщегоНазначения.ИмяТаблицыПоСсылке(УзелСсылка));
ЭлементБлокировки.УстановитьЗначение("Ссылка", УзелСсылка);
КонецЦикла;
Блокировка.Заблокировать();
ВиртуальныеКоды = РегистрыСведений.ПсевдонимыПредопределенныхУзлов.СоздатьНаборЗаписей();
Для Каждого УзелСсылка Из КоллекцияУзлов Цикл
КодПредопределенногоУзла = СокрЛП(ОбщегоНазначения.ЗначениеРеквизитаОбъекта(УзелСсылка, "Код"));
Если Не ЗначениеЗаполнено(КодПредопределенногоУзла)
// Не был выполнен переход на новую кодировку узлов.
Или СтрДлина(КодПредопределенногоУзла) < 36
// Требуется перекодировка в связи с тем, что код сформирован по логике БТС.
Или КодПредопределенногоУзла = КодИзМоделиСервиса Тогда
УникальныйИдентификаторОбменаДанными = Строка(Новый УникальныйИдентификатор);
ЗаблокироватьДанныеДляРедактирования(УзелСсылка);
УзелОбъект = УзелСсылка.ПолучитьОбъект();
УзелОбъект.Код = УникальныйИдентификаторОбменаДанными;
УзелОбъект.ОбменДанными.Загрузка = Истина;
УзелОбъект.Записать();
Если ЗначениеЗаполнено(КодПредопределенногоУзла) Тогда
// Сохранение предыдущего кода узла в регистре виртуальных кодов.
ТекстЗапроса =
"ВЫБРАТЬ
| Т.Ссылка КАК Ссылка
|ИЗ
| #ТаблицаПланаОбмена КАК Т
|ГДЕ
| НЕ Т.ЭтотУзел
| И НЕ Т.ПометкаУдаления";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,
"#ТаблицаПланаОбмена", "ПланОбмена." + ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелСсылка));
Запрос = Новый Запрос(ТекстЗапроса);
КорреспондентыПланаОбмена = Запрос.Выполнить().Выбрать();
Пока КорреспондентыПланаОбмена.Следующий() Цикл
ВиртуальныйКод = ВиртуальныеКоды.Добавить();
ВиртуальныйКод.Корреспондент = КорреспондентыПланаОбмена.Ссылка;
ВиртуальныйКод.КодУзла = КодПредопределенногоУзла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ВиртуальныеКоды.Количество() > 0 Тогда
ВиртуальныеКоды.Записать();
КонецЕсли;
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
// Удаляет роль НастройкаСинхронизацииДанных из всех профилей, в которые она входит.
Процедура УдалитьРольНастройкаСинхронизацииДанных() Экспорт
Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда
Возврат;
КонецЕсли;
МодульУправлениеДоступом = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступом");
НовыеРоли = Новый Массив;
ЗаменяемыеРоли = Новый Соответствие;
ЗаменяемыеРоли.Вставить("? НастройкаСинхронизацииДанных", НовыеРоли);
МодульУправлениеДоступом.ЗаменитьРолиВПрофилях(ЗаменяемыеРоли);
КонецПроцедуры
#КонецОбласти
#Область ВыполнениеОбменаДанными
// Выполняет процесс обмена данными отдельно для каждой строки настройки обмена.
// Процесс обмена данными состоит из двух стадий:
// - инициализация обмена - подготовка подсистемы обмена данными к процессу обмена
// - обмен данными - процесс зачитывания файла сообщения с последующей загрузкой этих данных в ИБ
// или выгрузки изменений в файл сообщения.
// Стадия инициализации выполняется один раз за сеанс и сохраняется в кэше сеанса на сервере
// до перезапуска сеанса или сброса повторно-используемых значений подсистемы обмена данными.
// Сброс повторно-используемых значений происходит при изменении данных, влияющих на процесс обмена данными
// (настройки транспорта, настройка выполнения обмена, настройка отборов на узлах планов обмена).
//
// Обмен может быть выполнен полностью для всех строк сценария,
// а может быть выполнен для отдельной строки ТЧ сценария обмена.
//
// Параметры:
// Отказ - Булево - флаг отказа; поднимается в случае возникновения ошибки при выполнении сценария.
// НастройкаВыполненияОбмена - СправочникСсылка.СценарииОбменовДанными - элемент справочника,
// по значениям реквизитов которого будет выполнен обмен данными.
// НомерСтроки - Число - номер строки по которой будет выполнен обмен данными.
// Если не указан, то обмен данными будет выполнен для всех строк.
//
Процедура ВыполнитьОбменДаннымиПоСценариюОбменаДанными(Отказ, НастройкаВыполненияОбмена, НомерСтроки = Неопределено) Экспорт
ПроверитьВозможностьВыполненияОбменов();
ПроверитьИспользованиеОбменаДанными();
УстановитьПривилегированныйРежим(Истина);
ТекстЗапроса = "
|ВЫБРАТЬ
| НастройкиВыполненияОбменаНастройкиОбмена.Ссылка КАК НастройкаВыполненияОбмена,
| НастройкиВыполненияОбменаНастройкиОбмена.НомерСтроки КАК НомерСтроки,
| НастройкиВыполненияОбменаНастройкиОбмена.ВыполняемоеДействие КАК ВыполняемоеДействие,
| НастройкиВыполненияОбменаНастройкиОбмена.ВидТранспортаОбмена КАК ВидТранспортаОбмена,
| НастройкиВыполненияОбменаНастройкиОбмена.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
|
| ВЫБОР КОГДА НастройкиВыполненияОбменаНастройкиОбмена.ВидТранспортаОбмена = ЗНАЧЕНИЕ(Перечисление.ВидыТранспортаСообщенийОбмена.COM)
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК ОбменЧерезВнешнееСоединение,
|
| ВЫБОР КОГДА НастройкиВыполненияОбменаНастройкиОбмена.ВидТранспортаОбмена = ЗНАЧЕНИЕ(Перечисление.ВидыТранспортаСообщенийОбмена.WS)
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК ОбменЧерезВебСервис,
|
| ВЫБОР КОГДА НастройкиВыполненияОбменаНастройкиОбмена.ВидТранспортаОбмена = ЗНАЧЕНИЕ(Перечисление.ВидыТранспортаСообщенийОбмена.ВнешняяСистема)
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК ОбменСВнешнейСистемой
|ИЗ
| Справочник.СценарииОбменовДанными.НастройкиОбмена КАК НастройкиВыполненияОбменаНастройкиОбмена
|ГДЕ
| НастройкиВыполненияОбменаНастройкиОбмена.Ссылка = &НастройкаВыполненияОбмена
| И &УсловиеПоНомеруСтроки
|УПОРЯДОЧИТЬ ПО
| НастройкиВыполненияОбменаНастройкиОбмена.НомерСтроки
|";
УсловиеПоНомеруСтроки = ?(НомерСтроки = Неопределено, "", "И НастройкиВыполненияОбменаНастройкиОбмена.НомерСтроки = &НомерСтроки");
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "И &УсловиеПоНомеруСтроки", УсловиеПоНомеруСтроки);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("НастройкаВыполненияОбмена", НастройкаВыполненияОбмена);
Запрос.УстановитьПараметр("НомерСтроки", НомерСтроки);
Выборка = Запрос.Выполнить().Выбрать();
ЭтоПодчиненныйУзелРИБТребующийУстановкиОбновления =
ЭтоПодчиненныйУзелРИБ() И ТребуетсяУстановкаОбновления();
Пока Выборка.Следующий() Цикл
ОтказПоСтрокеСценария = Ложь;
Если ЭтоПодчиненныйУзелРИБТребующийУстановкиОбновления
И ОбменДаннымиПовтИсп.ЭтоУзелРаспределеннойИнформационнойБазы(Выборка.УзелИнформационнойБазы) Тогда
// Обмен по расписанию не выполняется.
Продолжить;
ИначеЕсли Не НастройкаСинхронизацииЗавершена(Выборка.УзелИнформационнойБазы)
И Не Выборка.ОбменСВнешнейСистемой Тогда
Продолжить;
КонецЕсли;
ОтказБлокировки = Ложь;
ПроверитьВозможностьЗапускаОбмена(Выборка.УзелИнформационнойБазы, ОтказБлокировки);
Если ОтказБлокировки Тогда
Продолжить;
КонецЕсли;
Если Выборка.ОбменЧерезВнешнееСоединение Тогда
ПроверитьВозможностьВнешнегоСоединения();
КоличествоЭлементовВТранзакции = КоличествоЭлементовВТранзакцииВыполняемогоДействия(Выборка.ВыполняемоеДействие);
ВыполнитьДействиеОбменаДляУзлаИнформационнойБазыПоВнешнемуСоединению(ОтказПоСтрокеСценария,
Выборка.УзелИнформационнойБазы, Выборка.ВыполняемоеДействие, КоличествоЭлементовВТранзакции);
ИначеЕсли Выборка.ОбменЧерезВебСервис Тогда
ПараметрыОбмена = ПараметрыОбмена();
ПараметрыОбмена.ДлительнаяОперацияРазрешена = Истина;
ПараметрыОбмена.ИнтервалОжиданияНаСервере = 30;
ВыполнитьДействиеОбменаДляУзлаИнформационнойБазыЧерезWebСервис(ОтказПоСтрокеСценария,
Выборка.УзелИнформационнойБазы, Выборка.ВыполняемоеДействие, ПараметрыОбмена);
Иначе
// ИНИЦИАЛИЗАЦИЯ ОБМЕНА ДАННЫМИ
СтруктураНастроекОбмена = НастройкиОбменаДанными(Выборка.НастройкаВыполненияОбмена, Выборка.НомерСтроки);
// Если настройка содержит ошибки, то обмен не производим; статус "Отменено".
Если СтруктураНастроекОбмена.Отказ Тогда
ОтказПоСтрокеСценария = Истина;
// Фиксируем в ЖР лог по обмену данными.
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Продолжить;
КонецЕсли;
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено;
// Добавляем в ЖР информацию о процессе обмена данными.
СтрокаСообщения = НСтр("ru = 'Начало процесса обмена данными по настройке %1'", ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, СтруктураНастроекОбмена.НастройкаВыполненияОбменаНаименование);
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщения, СтруктураНастроекОбмена);
// ОБМЕН ДАННЫМИ
ВыполнитьОбменДаннымиЧерезФайловыйРесурс(СтруктураНастроекОбмена);
// Фиксируем в ЖР лог по обмену данными.
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Если Не РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена) Тогда
ОтказПоСтрокеСценария = Истина;
КонецЕсли;
КонецЕсли;
Если ОтказПоСтрокеСценария Тогда
Отказ = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Точка входа для выполнения обмена данными по сценарию обмена регламентным заданием.
//
// Параметры:
// КодСценарияОбмена - Строка - код элемента справочника "Сценарии обменов данными", для которого будет выполнен обмен
// данными.
//
Процедура ВыполнитьОбменДаннымиПоРегламентномуЗаданию(КодСценарияОбмена) Экспорт
ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.СинхронизацияДанных);
ПроверитьВозможностьВыполненияОбменов();
ПроверитьИспользованиеОбменаДанными();
Если Не ЗначениеЗаполнено(КодСценарияОбмена) Тогда
ВызватьИсключение НСтр("ru = 'Не задан сценарий обмена данными.'");
КонецЕсли;
ТекстЗапроса = "
|ВЫБРАТЬ
| СценарииОбменовДанными.Ссылка КАК Ссылка
|ИЗ
| Справочник.СценарииОбменовДанными КАК СценарииОбменовДанными
|ГДЕ
| СценарииОбменовДанными.Код = &Код
| И НЕ СценарииОбменовДанными.ПометкаУдаления
|";
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Код", КодСценарияОбмена);
Запрос.Текст = ТекстЗапроса;
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
// Выполняем обмен по сценарию.
ВыполнитьОбменДаннымиПоСценариюОбменаДанными(Ложь, Выборка.Ссылка);
Иначе
СтрокаСообщения = НСтр("ru = 'Сценарий обмена данными с кодом %1 не найден.'");
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, КодСценарияОбмена);
ВызватьИсключение СтрокаСообщения;
КонецЕсли;
КонецПроцедуры
// Получает сообщение обмена во временный каталог пользователя ОС.
//
// Параметры:
// Отказ - Булево - флаг отказа; поднимается в случае возникновения ошибки.
// УзелИнформационнойБазы - ПланОбменаСсылка - узел плана обмена, для которого выполняется получение сообщения
// обмена.
// ВидТранспортаСообщенийОбмена - ПеречислениеСсылка.ВидыТранспортаСообщенийОбмена - вид транспорта для получения
// сообщения обмена.
// ВыводитьСообщения - Булево - если Истина, то выводятся сообщения пользователю.
//
// Возвращаемое значение:
// Структура со следующими ключи:
// * ИмяВременногоКаталогаСообщенийОбмена - полное имя каталога обмена, в которое было загружено сообщение обмена.
// * ИмяФайлаСообщенияОбмена - полное имя файла сообщения обмена.
// * ИдентификаторФайлаПакетаДанных - дата изменения файла сообщения обмена.
//
Функция ПолучитьСообщениеОбменаВоВременныйКаталог(Отказ, УзелИнформационнойБазы, ВидТранспортаСообщенийОбмена, ВыводитьСообщения = Истина) Экспорт
// Возвращаемое значение функции.
Результат = Новый Структура;
Результат.Вставить("ИмяВременногоКаталогаСообщенийОбмена", "");
Результат.Вставить("ИмяФайлаСообщенияОбмена", "");
Результат.Вставить("ИдентификаторФайлаПакетаДанных", Неопределено);
СтруктураНастроекОбмена = НастройкиТранспортаОбмена(УзелИнформационнойБазы, ВидТранспортаСообщенийОбмена);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено;
// Если настройка содержит ошибки, то получение сообщения обмена не производим; статус "Отменено".
Если СтруктураНастроекОбмена.Отказ Тогда
Если ВыводитьСообщения Тогда
НСтрока = НСтр("ru = 'При инициализации обработки транспорта сообщений обмена возникли ошибки.'");
ОбщегоНазначения.СообщитьПользователю(НСтрока,,,, Отказ);
КонецЕсли;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Возврат Результат;
КонецЕсли;
// создаем временный каталог
ВыполнитьТранспортСообщенияОбменаПередОбработкой(СтруктураНастроекОбмена);
Если СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено Тогда
// Получаем сообщение во временный каталог.
ВыполнитьТранспортСообщенияОбменаПолучение(СтруктураНастроекОбмена);
КонецЕсли;
Если СтруктураНастроекОбмена.РезультатВыполненияОбмена <> Неопределено Тогда
Если ВыводитьСообщения Тогда
НСтрока = НСтр("ru = 'При получении сообщений обмена возникли ошибки.'");
ОбщегоНазначения.СообщитьПользователю(НСтрока,,,, Отказ);
КонецЕсли;
// Удаляем временный каталог и все его содержимое.
ВыполнитьТранспортСообщенияОбменаПослеОбработки(СтруктураНастроекОбмена);
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Возврат Результат;
КонецЕсли;
Результат.ИмяВременногоКаталогаСообщенийОбмена = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена.ИмяКаталогаСообщенияОбмена();
Результат.ИмяФайлаСообщенияОбмена = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена.ИмяФайлаСообщенияОбмена();
Результат.ИдентификаторФайлаПакетаДанных = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена.ДатаФайлаСообщенияОбмена();
Возврат Результат;
КонецФункции
// Получает сообщение обмена из информационной базы корреспондента во временный каталог пользователя ОС.
//
// Параметры:
// Отказ - Булево - флаг отказа; поднимается в случае возникновения ошибки.
// УзелИнформационнойБазы - ПланОбменаСсылка - узел плана обмена, для которого выполняется получение сообщения
// обмена.
// ВыводитьСообщения - Булево - если Истина, то выводятся сообщения пользователю.
//
// Возвращаемое значение:
// Структура со следующими ключи:
// * ИмяВременногоКаталогаСообщенийОбмена - полное имя каталога обмена, в которое было загружено сообщение обмена.
// * ИмяФайлаСообщенияОбмена - полное имя файла сообщения обмена.
// * ИдентификаторФайлаПакетаДанных - дата изменения файла сообщения обмена.
//
Функция ПолучитьСообщениеОбменаВоВременныйКаталогИзИнформационнойБазыКорреспондента(Отказ, УзелИнформационнойБазы, ВыводитьСообщения = Истина) Экспорт
// Возвращаемое значение функции.
Результат = Новый Структура;
Результат.Вставить("ИмяВременногоКаталогаСообщенийОбмена", "");
Результат.Вставить("ИмяФайлаСообщенияОбмена", "");
Результат.Вставить("ИдентификаторФайлаПакетаДанных", Неопределено);
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелИнформационнойБазы);
ТекущийУзелПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьЭтотУзелПланаОбмена(ИмяПланаОбмена);
КодТекущегоУзлаПланаОбмена = ИдентификаторЭтогоУзлаДляОбмена(УзелИнформационнойБазы);
ШаблонИмениФайлаСообщения = ШаблонИмениФайлаСообщения(ТекущийУзелПланаОбмена, УзелИнформационнойБазы, Ложь);
// Параметры, которые будут определены в функции.
ДатаФайлаСообщенияОбмена = Дата('00010101');
ИмяКаталогаСообщенияОбмена = "";
СтрокаСообщенияОбОшибке = "";
Попытка
ИмяКаталогаСообщенияОбмена = СоздатьВременныйКаталогСообщенийОбмена();
Исключение
Если ВыводитьСообщения Тогда
Сообщение = НСтр("ru = 'Не удалось произвести обмен: %1'");
Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ОбщегоНазначения.СообщитьПользователю(Сообщение,,,, Отказ);
КонецЕсли;
Возврат Результат;
КонецПопытки;
// Получаем внешнее соединение для узла информационной базы.
ДанныеСоединения = ОбменДаннымиПовтИсп.ВнешнееСоединениеДляУзлаИнформационнойБазы(УзелИнформационнойБазы);
ВнешнееСоединение = ДанныеСоединения.Соединение;
Если ВнешнееСоединение = Неопределено Тогда
Сообщение = НСтр("ru = 'Не удалось произвести обмен: %1'");
Если ВыводитьСообщения Тогда
СообщениеДляПользователя = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ДанныеСоединения.КраткоеОписаниеОшибки);
ОбщегоНазначения.СообщитьПользователю(СообщениеДляПользователя,,,, Отказ);
КонецЕсли;
// Добавляем две записи в ЖР: одну для загрузки данных, другую для выгрузки данных.
СтруктураНастроекОбмена = Новый Структура("КлючСообщенияЖурналаРегистрации");
СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации = КлючСообщенияЖурналаРегистрации(УзелИнформационнойБазы, Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ДанныеСоединения.ПодробноеОписаниеОшибки);
ЗаписьЖурналаРегистрацииОбменаДанными(Сообщение, СтруктураНастроекОбмена, Истина);
Возврат Результат;
КонецЕсли;
ИмяФайлаСообщенияОбмена = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(ИмяКаталогаСообщенияОбмена, ШаблонИмениФайлаСообщения + ".xml");
ПсевдонимУзла = ПсевдонимПредопределенногоУзла(УзелИнформационнойБазы);
Если ЗначениеЗаполнено(ПсевдонимУзла) Тогда
// Надо проверить код узла в корреспонденте - он может быть уже перекодирован.
// Тогда псевдоним больше не нужен.
ПланОбменаМенеджер = ВнешнееСоединение.ПланыОбмена[ИмяПланаОбмена];
Если ПланОбменаМенеджер.НайтиПоКоду(ПсевдонимУзла) <> ПланОбменаМенеджер.ПустаяСсылка() Тогда
КодТекущегоУзлаПланаОбмена = ПсевдонимУзла;
КонецЕсли;
КонецЕсли;
ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.ВыполнитьВыгрузкуДляУзлаИнформационнойБазы(Отказ, ИмяПланаОбмена, КодТекущегоУзлаПланаОбмена, ИмяФайлаСообщенияОбмена, СтрокаСообщенияОбОшибке);
Если Отказ Тогда
Если ВыводитьСообщения Тогда
// Выводим сообщение об ошибке.
Сообщение = НСтр("ru = 'Не удалось выгрузить данные: %1'");
Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ДанныеСоединения.КраткоеОписаниеОшибки);
ОбщегоНазначения.СообщитьПользователю(Сообщение,,,, Отказ);
КонецЕсли;
Возврат Результат;
КонецЕсли;
ФайлСообщенияОбмена = Новый Файл(ИмяФайлаСообщенияОбмена);
Если ФайлСообщенияОбмена.Существует() Тогда
ДатаФайлаСообщенияОбмена = ФайлСообщенияОбмена.ПолучитьВремяИзменения();
КонецЕсли;
Результат.ИмяВременногоКаталогаСообщенийОбмена = ИмяКаталогаСообщенияОбмена;
Результат.ИмяФайлаСообщенияОбмена = ИмяФайлаСообщенияОбмена;
Результат.ИдентификаторФайлаПакетаДанных = ДатаФайлаСообщенияОбмена;
Возврат Результат;
КонецФункции
// Получает сообщение обмена из информационной базы корреспондента через веб-сервис во временный каталог пользователя
// ОС.
//
// Параметры:
// Отказ - Булево - флаг отказа; поднимается в случае возникновения ошибки.
// УзелИнформационнойБазы - ПланОбменаСсылка - узел плана обмена, для которого выполняется получение сообщения обмена.
// ИдентификаторФайла - УникальныйИдентификатор - идентификатор файла.
// ДлительнаяОперация - Булево - признак использования длительное операции.
// ИдентификаторОперации - УникальныйИдентификатор - уникальный идентификатор длительной операции.
// ПараметрыАутентификации - Структура - содержит параметры аутентификации на веб-сервисе (Пользователь, Пароль).
//
// Возвращаемое значение:
// Структура со следующими ключи:
// * ИмяВременногоКаталогаСообщенийОбмена - полное имя каталога обмена, в которое было загружено сообщение обмена.
// * ИмяФайлаСообщенияОбмена - полное имя файла сообщения обмена.
// * ИдентификаторФайлаПакетаДанных - дата изменения файла сообщения обмена.
//
Функция ПолучитьСообщениеОбменаВоВременныйКаталогИзИнформационнойБазыКорреспондентаЧерезВебСервис(
Отказ,
УзелИнформационнойБазы,
ИдентификаторФайла,
ДлительнаяОперация,
ИдентификаторОперации,
ПараметрыАутентификации = Неопределено) Экспорт
ПроверитьВозможностьВыполненияОбменов();
ПроверитьИспользованиеОбменаДанными();
УстановитьПривилегированныйРежим(Истина);
// Возвращаемое значение функции.
Результат = Новый Структура;
Результат.Вставить("ИмяВременногоКаталогаСообщенийОбмена", "");
Результат.Вставить("ИмяФайлаСообщенияОбмена", "");
Результат.Вставить("ИдентификаторФайлаПакетаДанных", Неопределено);
// Параметры, которые будут определены в функции.
ИмяКаталогаСообщенияОбмена = "";
ИмяФайлаСообщенияОбмена = "";
ДатаФайлаСообщенияОбмена = Дата('00010101');
СтруктураНастроекОбмена = Новый Структура;
СтруктураНастроекОбмена.Вставить("ИмяПланаОбмена", ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелИнформационнойБазы));
СтруктураНастроекОбмена.Вставить("УзелИнформационнойБазы", УзелИнформационнойБазы);
СтруктураНастроекОбмена.Вставить("КлючСообщенияЖурналаРегистрации",
КлючСообщенияЖурналаРегистрации(УзелИнформационнойБазы, Перечисления.ДействияПриОбмене.ЗагрузкаДанных));
СтруктураНастроекОбмена.Вставить("ТекущийУзелПланаОбмена",
ОбменДаннымиПовтИсп.ПолучитьЭтотУзелПланаОбмена(СтруктураНастроекОбмена.ИмяПланаОбмена));
СтруктураНастроекОбмена.Вставить("ТекущийУзелПланаОбменаКод",
ИдентификаторЭтогоУзлаДляОбмена(УзелИнформационнойБазы));
СтруктураНастроекОбмена.Вставить("ДействиеПриОбмене", Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
ПараметрыПрокси = Новый Структура;
ПараметрыПрокси.Вставить("ПараметрыАутентификации", ПараметрыАутентификации);
Прокси = Неопределено;
СостояниеНастройки = Неопределено;
СообщениеОбОшибке = "";
ИнициализироватьWSПроксиДляУправленияОбменомДанными(Прокси, СтруктураНастроекОбмена, ПараметрыПрокси, Отказ, СостояниеНастройки, СообщениеОбОшибке);
Если Отказ Тогда
ЗаписьЖурналаРегистрацииОбменаДанными(СообщениеОбОшибке, СтруктураНастроекОбмена, Истина);
Возврат Результат;
КонецЕсли;
Попытка
Прокси.UploadData(
СтруктураНастроекОбмена.ИмяПланаОбмена,
СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
ИдентификаторФайла,
ДлительнаяОперация,
ИдентификаторОперации,
Истина);
Исключение
Отказ = Истина;
Сообщение = НСтр("ru = 'При выгрузке данных возникли ошибки во второй информационной базе: %1'", ОбщегоНазначения.КодОсновногоЯзыка());
Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ЗаписьЖурналаРегистрацииОбменаДанными(Сообщение, СтруктураНастроекОбмена, Истина);
Возврат Результат;
КонецПопытки;
Если ДлительнаяОперация Тогда
ЗаписьЖурналаРегистрацииОбменаДанными(НСтр("ru = 'Ожидание получения данных от базы-корреспондента...'",
ОбщегоНазначения.КодОсновногоЯзыка()), СтруктураНастроекОбмена);
Возврат Результат;
КонецЕсли;
Попытка
ИмяФайлаИзСервисаПередачиФайлов = ПолучитьФайлИзХранилищаВСервисе(Новый УникальныйИдентификатор(ИдентификаторФайла),
СтруктураНастроекОбмена.УзелИнформационнойБазы,, ПараметрыАутентификации);
Исключение
Отказ = Истина;
Сообщение = НСтр("ru = 'Возникли ошибки при получении сообщения обмена из сервиса передачи файлов: %1'", ОбщегоНазначения.КодОсновногоЯзыка());
Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ЗаписьЖурналаРегистрацииОбменаДанными(Сообщение, СтруктураНастроекОбмена, Истина);
Возврат Результат;
КонецПопытки;
Попытка
ИмяКаталогаСообщенияОбмена = СоздатьВременныйКаталогСообщенийОбмена();
Исключение
Отказ = Истина;
Сообщение = НСтр("ru = 'При получении сообщения обмена возникли ошибки: %1'", ОбщегоНазначения.КодОсновногоЯзыка());
Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ЗаписьЖурналаРегистрацииОбменаДанными(Сообщение, СтруктураНастроекОбмена, Истина);
Возврат Результат;
КонецПопытки;
ШаблонИмениФайлаСообщения = ШаблонИмениФайлаСообщения(СтруктураНастроекОбмена.ТекущийУзелПланаОбмена,
СтруктураНастроекОбмена.УзелИнформационнойБазы, Ложь);
ИмяФайлаСообщенияОбмена = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(ИмяКаталогаСообщенияОбмена, ШаблонИмениФайлаСообщения + ".xml");
ПереместитьФайл(ИмяФайлаИзСервисаПередачиФайлов, ИмяФайлаСообщенияОбмена);
ФайлСообщенияОбмена = Новый Файл(ИмяФайлаСообщенияОбмена);
Если ФайлСообщенияОбмена.Существует() Тогда
ДатаФайлаСообщенияОбмена = ФайлСообщенияОбмена.ПолучитьВремяИзменения();
КонецЕсли;
Результат.ИмяВременногоКаталогаСообщенийОбмена = ИмяКаталогаСообщенияОбмена;
Результат.ИмяФайлаСообщенияОбмена = ИмяФайлаСообщенияОбмена;
Результат.ИдентификаторФайлаПакетаДанных = ДатаФайлаСообщенияОбмена;
Возврат Результат;
КонецФункции
// Получает сообщение обмена из базы-корреспондента через веб-сервис.
// Сохраняет полученное сообщение обмена во временный каталог.
// Используется в том случае, если получение сообщения обмена выполнялось в контексте фонового задания в
// базе-корреспонденте.
//
// Параметры:
// Отказ - Булево - флаг отказа; поднимается в случае возникновения ошибки.
// УзелИнформационнойБазы - ПланОбменаСсылка - узел плана обмена, для которого выполняется получение сообщения обмена.
// ИдентификаторФайла - УникальныйИдентификатор - идентификатор файла.
// ПараметрыАутентификации - Структура - содержит параметры аутентификации на веб-сервисе (Пользователь, Пароль).
//
// Возвращаемое значение:
// Структура со следующими ключи:
// * ИмяВременногоКаталогаСообщенийОбмена - полное имя каталога обмена, в которое было загружено сообщение обмена.
// * ИмяФайлаСообщенияОбмена - полное имя файла сообщения обмена.
// * ИдентификаторФайлаПакетаДанных - дата изменения файла сообщения обмена.
//
Функция ПолучитьСообщениеОбменаВоВременныйКаталогИзИнформационнойБазыКорреспондентаЧерезВебСервисЗавершениеДлительнойОперации(
Отказ,
УзелИнформационнойБазы,
ИдентификаторФайла,
Знач ПараметрыАутентификации = Неопределено) Экспорт
// Возвращаемое значение функции.
Результат = Новый Структура;
Результат.Вставить("ИмяВременногоКаталогаСообщенийОбмена", "");
Результат.Вставить("ИмяФайлаСообщенияОбмена", "");
Результат.Вставить("ИдентификаторФайлаПакетаДанных", Неопределено);
// Параметры, которые будут определены в функции.
ИмяКаталогаСообщенияОбмена = "";
ИмяФайлаСообщенияОбмена = "";
ДатаФайлаСообщенияОбмена = Дата('00010101');
Попытка
ИмяФайлаИзСервисаПередачиФайлов = ПолучитьФайлИзХранилищаВСервисе(Новый УникальныйИдентификатор(ИдентификаторФайла), УзелИнформационнойБазы,, ПараметрыАутентификации);
Исключение
Отказ = Истина;
Сообщение = НСтр("ru = 'Возникли ошибки при получении сообщения обмена из сервиса передачи файлов: %1'", ОбщегоНазначения.КодОсновногоЯзыка());
Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
СтруктураНастроекОбмена = Новый Структура("КлючСообщенияЖурналаРегистрации");
СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации = КлючСообщенияЖурналаРегистрации(УзелИнформационнойБазы, Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
ЗаписьЖурналаРегистрацииОбменаДанными(Сообщение, СтруктураНастроекОбмена, Истина);
Возврат Результат;
КонецПопытки;
Попытка
ИмяКаталогаСообщенияОбмена = СоздатьВременныйКаталогСообщенийОбмена();
Исключение
Отказ = Истина;
Сообщение = НСтр("ru = 'При получении сообщения обмена возникли ошибки: %1'", ОбщегоНазначения.КодОсновногоЯзыка());
Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
СтруктураНастроекОбмена = Новый Структура("КлючСообщенияЖурналаРегистрации");
СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации = КлючСообщенияЖурналаРегистрации(УзелИнформационнойБазы, Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
ЗаписьЖурналаРегистрацииОбменаДанными(Сообщение, СтруктураНастроекОбмена, Истина);
Возврат Результат;
КонецПопытки;
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелИнформационнойБазы);
ТекущийУзелПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьЭтотУзелПланаОбмена(ИмяПланаОбмена);
ШаблонИмениФайлаСообщения = ШаблонИмениФайлаСообщения(ТекущийУзелПланаОбмена, УзелИнформационнойБазы, Ложь);
ИмяФайлаСообщенияОбмена = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(ИмяКаталогаСообщенияОбмена, ШаблонИмениФайлаСообщения + ".xml");
ФайлСообщенияОбмена = Новый Файл(ИмяФайлаСообщенияОбмена);
Если НЕ ФайлСообщенияОбмена.Существует() Тогда
// Возможно, файл удастся получить если применить виртуальный код узла.
ШаблонИмениФайлаСообщенияСтарый = ШаблонИмениФайлаСообщения;
ШаблонИмениФайлаСообщения = ШаблонИмениФайлаСообщения(ТекущийУзелПланаОбмена, УзелИнформационнойБазы, Ложь,, Истина);
Если ШаблонИмениФайлаСообщения <> ШаблонИмениФайлаСообщенияСтарый Тогда
ИмяФайлаСообщенияОбмена = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(ИмяКаталогаСообщенияОбмена, ШаблонИмениФайлаСообщения + ".xml");
ФайлСообщенияОбмена = Новый Файл(ИмяФайлаСообщенияОбмена);
КонецЕсли;
КонецЕсли;
ПереместитьФайл(ИмяФайлаИзСервисаПередачиФайлов, ИмяФайлаСообщенияОбмена);
Если ФайлСообщенияОбмена.Существует() Тогда
ДатаФайлаСообщенияОбмена = ФайлСообщенияОбмена.ПолучитьВремяИзменения();
КонецЕсли;
Результат.ИмяВременногоКаталогаСообщенийОбмена = ИмяКаталогаСообщенияОбмена;
Результат.ИмяФайлаСообщенияОбмена = ИмяФайлаСообщенияОбмена;
Результат.ИдентификаторФайлаПакетаДанных = ДатаФайлаСообщенияОбмена;
Возврат Результат;
КонецФункции
// Выполняет получение файла сообщения обмена из базы-корреспондента через веб-сервис.
// Выполняет загрузку полученного файла сообщения обмена в эту базу.
//
// Параметры:
// Отказ - Булево - флаг отказа; поднимается в случае возникновения ошибки.
// УзелИнформационнойБазы - ПланОбменаСсылка - узел плана обмена, для которого выполняется получение сообщения обмена.
// ИдентификаторФайла - УникальныйИдентификатор - идентификатор файла.
// ДатаНачалаОперации - Дата - дата начала загрузки.
// ПараметрыАутентификации - Структура - содержит параметры аутентификации на веб-сервисе (Пользователь, Пароль).
//
Процедура ВыполнитьОбменДаннымиДляУзлаИнформационнойБазыЗавершениеДлительнойОперации(
Отказ,
Знач УзелИнформационнойБазы,
Знач ИдентификаторФайла,
Знач ДатаНачалаОперации,
Знач ПараметрыАутентификации = Неопределено,
ВыдаватьОшибку = Ложь) Экспорт
ПроверитьВозможностьВыполненияОбменов();
ПроверитьИспользованиеОбменаДанными();
УстановитьПривилегированныйРежим(Истина);
Попытка
ФайлСообщенияОбмена = ПолучитьФайлИзХранилищаВСервисе(Новый УникальныйИдентификатор(ИдентификаторФайла), УзелИнформационнойБазы,, ПараметрыАутентификации);
Исключение
ЗафиксироватьЗавершениеОбменаСОшибкой(УзелИнформационнойБазы,
Перечисления.ДействияПриОбмене.ЗагрузкаДанных,
ДатаНачалаОперации,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
Если ВыдаватьОшибку Тогда
ВызватьИсключение;
Иначе
Отказ = Истина;
КонецЕсли;
Возврат;
КонецПопытки;
// Загрузка файла сообщения обмена в эту базу.
ПараметрыОбменаДанными = ПараметрыОбменаДаннымиЧерезФайлИлиСтроку();
ПараметрыОбменаДанными.УзелИнформационнойБазы = УзелИнформационнойБазы;
ПараметрыОбменаДанными.ПолноеИмяФайлаСообщенияОбмена = ФайлСообщенияОбмена;
ПараметрыОбменаДанными.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ЗагрузкаДанных;
ПараметрыОбменаДанными.ДатаНачалаОперации = ДатаНачалаОперации;
Попытка
ВыполнитьОбменДаннымиДляУзлаИнформационнойБазыЧерезФайлИлиСтроку(ПараметрыОбменаДанными);
Исключение
ЗафиксироватьЗавершениеОбменаСОшибкой(УзелИнформационнойБазы,
Перечисления.ДействияПриОбмене.ЗагрузкаДанных,
ДатаНачалаОперации,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
Если ВыдаватьОшибку Тогда
ВызватьИсключение;
Иначе
Отказ = Истина;
КонецЕсли;
КонецПопытки;
Попытка
УдалитьФайлы(ФайлСообщенияОбмена);
Исключение
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
// Выполняет удаление файлов сообщений обмена, которые не были удалены из-за сбоев в работе системы.
// Удалению подлежат файлы обмена с датой размещения более суток от текущей универсальной даты,
// и файлы для сопоставления с датой размещения более 7 суток от текущей универсальной даты.
// Анализируется РС.СообщенияОбменаДанными и РС.СообщенияОбменаДаннымиОбластейДанных.
//
// Параметры:
// Нет.
//
Процедура УдалитьНеактуальныеСообщенияОбмена() Экспорт
ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.УдалениеНеактуальнойИнформацииСинхронизации);
Если Не ПолучитьФункциональнуюОпцию("ИспользоватьСинхронизациюДанных") Тогда
Возврат;
КонецЕсли;
ПроверитьВозможностьАдминистрированияОбменов();
УстановитьПривилегированныйРежим(Истина);
Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
// Удаляем неактуальные сообщения обмена, отмеченные в РС.СообщенияОбменаДанными.
ТекстЗапроса =
"ВЫБРАТЬ
| СообщенияОбменаДанными.ИдентификаторСообщения КАК ИдентификаторСообщения,
| СообщенияОбменаДанными.ИмяФайлаСообщения КАК ИмяФайла,
| СообщенияОбменаДанными.ДатаЗакладкиСообщения КАК ДатаЗакладкиСообщения,
| ОбщиеНастройкиУзловИнформационныхБаз.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| ВЫБОР
| КОГДА ОбщиеНастройкиУзловИнформационныхБаз.УзелИнформационнойБазы ЕСТЬ NULL
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ КАК СообщениеДляСопоставления
|ПОМЕСТИТЬ ВТСообщенияОбмена
|ИЗ
| РегистрСведений.СообщенияОбменаДанными КАК СообщенияОбменаДанными
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ОбщиеНастройкиУзловИнформационныхБаз КАК ОбщиеНастройкиУзловИнформационныхБаз
| ПО (ОбщиеНастройкиУзловИнформационныхБаз.СообщениеДляСопоставленияДанных = СообщенияОбменаДанными.ИдентификаторСообщения)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТСообщенияОбмена.ИдентификаторСообщения КАК ИдентификаторСообщения,
| ВТСообщенияОбмена.ИмяФайла КАК ИмяФайла,
| ВТСообщенияОбмена.СообщениеДляСопоставления КАК СообщениеДляСопоставления,
| ВТСообщенияОбмена.УзелИнформационнойБазы КАК УзелИнформационнойБазы
|ИЗ
| ВТСообщенияОбмена КАК ВТСообщенияОбмена
|ГДЕ
| ВЫБОР
| КОГДА ВТСообщенияОбмена.СообщениеДляСопоставления
| ТОГДА ВТСообщенияОбмена.ДатаЗакладкиСообщения < &ДатаАктуальностиДляСопоставления
| ИНАЧЕ ВТСообщенияОбмена.ДатаЗакладкиСообщения < &ДатаАктуальности
| КОНЕЦ";
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДатаАктуальности", ТекущаяУниверсальнаяДата() - 60 * 60 * 24);
Запрос.УстановитьПараметр("ДатаАктуальностиДляСопоставления", ТекущаяУниверсальнаяДата() - 60 * 60 * 24 * 7);
Запрос.Текст = ТекстЗапроса;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ПолноеИмяФайлаСообщения = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогВременногоХранилищаФайлов(), Выборка.ИмяФайла);
ФайлСообщения = Новый Файл(ПолноеИмяФайлаСообщения);
Если ФайлСообщения.Существует() Тогда
Попытка
УдалитьФайлы(ФайлСообщения.ПолноеИмя);
Исключение
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
Продолжить;
КонецПопытки;
КонецЕсли;
// Удаляем информацию о файле сообщения обмена из хранилища.
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("ИдентификаторСообщения", Строка(Выборка.ИдентификаторСообщения));
РегистрыСведений.СообщенияОбменаДанными.УдалитьЗапись(СтруктураЗаписи);
Если Выборка.СообщениеДляСопоставления Тогда
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("УзелИнформационнойБазы", Выборка.УзелИнформационнойБазы);
СтруктураЗаписи.Вставить("СообщениеДляСопоставленияДанных", "");
ОбменДаннымиСлужебный.ОбновитьЗаписьВРегистрСведений(СтруктураЗаписи, "ОбщиеНастройкиУзловИнформационныхБаз");
КонецЕсли;
КонецЦикла;
КонецЕсли;
// Удаляем неактуальные сообщения обмена, отмеченные в РС.СообщенияОбменаДаннымиОбластейДанных.
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса") Тогда
МодульОбменДаннымиВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиВМоделиСервиса");
МодульОбменДаннымиВМоделиСервиса.ПриУдаленииНеактуальныхСообщенийОбмена();
КонецЕсли;
КонецПроцедуры
Функция КоличествоЭлементовВТранзакцииВыполняемогоДействия(Действие)
Если Действие = Перечисления.ДействияПриОбмене.ВыгрузкаДанных Тогда
КоличествоЭлементов = КоличествоЭлементовВТранзакцииВыгрузкиДанных();
Иначе
КоличествоЭлементов = КоличествоЭлементовВТранзакцииЗагрузкиДанных();
КонецЕсли;
Возврат КоличествоЭлементов;
КонецФункции
// Выполняет выгрузку сообщения обмена, которое содержало
// изменения конфигурации, до обновления информационной базы.
//
Процедура ВыгрузитьСообщениеПослеОбновленияИнформационнойБазы()
// После успешной загрузки и обновления ИБ режим повтора можно отключить.
ОтключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
Попытка
Если ПолучитьФункциональнуюОпцию("ИспользоватьСинхронизациюДанных") Тогда
УзелИнформационнойБазы = ГлавныйУзел();
Если УзелИнформационнойБазы <> Неопределено Тогда
ВыполнитьВыгрузку = Истина;
НастройкиТранспорта = РегистрыСведений.НастройкиТранспортаОбменаДанными.НастройкиТранспорта(УзелИнформационнойБазы);
ВидТранспорта = НастройкиТранспорта.ВидТранспортаСообщенийОбменаПоУмолчанию;
Если ВидТранспорта = Перечисления.ВидыТранспортаСообщенийОбмена.WS
И Не НастройкиТранспорта.WSЗапомнитьПароль Тогда
ВыполнитьВыгрузку = Ложь;
РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.УстановитьПризнакОтправкиДанных(УзелИнформационнойБазы);
КонецЕсли;
Если ВыполнитьВыгрузку Тогда
// Только выгрузка.
Отказ = Ложь;
ПараметрыОбмена = ПараметрыОбмена();
ПараметрыОбмена.ВидТранспортаСообщенийОбмена = ВидТранспорта;
ПараметрыОбмена.ВыполнятьЗагрузку = Ложь;
ПараметрыОбмена.ВыполнятьВыгрузку = Истина;
ВыполнитьОбменДаннымиДляУзлаИнформационнойБазы(УзелИнформационнойБазы, ПараметрыОбмена, Отказ);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
#КонецОбласти
#Область ДляРаботыЧерезВнешнееСоединение
Процедура ВыполнитьВыгрузкуДляУзлаИнформационнойБазыВоВременноеХранилище(Знач ИмяПланаОбмена, Знач КодУзлаИнформационнойБазы, Адрес) Экспорт
ПолноеИмяФайлаСообщенияОбмена = ПолучитьИмяВременногоФайла("xml");
ПараметрыОбменаДанными = ПараметрыОбменаДаннымиЧерезФайлИлиСтроку();
ПараметрыОбменаДанными.ПолноеИмяФайлаСообщенияОбмена = ПолноеИмяФайлаСообщенияОбмена;
ПараметрыОбменаДанными.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ВыгрузкаДанных;
ПараметрыОбменаДанными.ИмяПланаОбмена = ИмяПланаОбмена;
ПараметрыОбменаДанными.КодУзлаИнформационнойБазы = КодУзлаИнформационнойБазы;
ВыполнитьОбменДаннымиДляУзлаИнформационнойБазыЧерезФайлИлиСтроку(ПараметрыОбменаДанными);
Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ПолноеИмяФайлаСообщенияОбмена));
УдалитьФайлы(ПолноеИмяФайлаСообщенияОбмена);
КонецПроцедуры
Процедура ВыполнитьВыгрузкуДляУзлаИнформационнойБазыВСервисПередачиФайлов(ПараметрыПроцедуры, АдресХранилища) Экспорт
ИмяПланаОбмена = ПараметрыПроцедуры["ИмяПланаОбмена"];
КодУзлаИнформационнойБазы = ПараметрыПроцедуры["КодУзлаИнформационнойБазы"];
ИдентификаторФайла = ПараметрыПроцедуры["ИдентификаторФайла"];
ИспользоватьСжатие = ПараметрыПроцедуры.Свойство("ИспользоватьСжатие") И ПараметрыПроцедуры["ИспользоватьСжатие"];
УстановитьПривилегированныйРежим(Истина);
ИмяФайлаСообщения = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(
КаталогВременногоХранилищаФайлов(),
УникальноеИмяФайлаСообщенияОбмена());
ПараметрыОбменаДанными = ПараметрыОбменаДаннымиЧерезФайлИлиСтроку();
ПараметрыОбменаДанными.ПолноеИмяФайлаСообщенияОбмена = ИмяФайлаСообщения;
ПараметрыОбменаДанными.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ВыгрузкаДанных;
ПараметрыОбменаДанными.ИмяПланаОбмена = ИмяПланаОбмена;
ПараметрыОбменаДанными.КодУзлаИнформационнойБазы = КодУзлаИнформационнойБазы;
ВыполнитьОбменДаннымиДляУзлаИнформационнойБазыЧерезФайлИлиСтроку(ПараметрыОбменаДанными);
ИмяФайлаДляПомещенияВХранилище = ИмяФайлаСообщения;
Если ИспользоватьСжатие Тогда
ИмяФайлаДляПомещенияВХранилище = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(
КаталогВременногоХранилищаФайлов(),
УникальноеИмяФайлаСообщенияОбмена("zip"));
Архиватор = Новый ЗаписьZipФайла(ИмяФайлаДляПомещенияВХранилище, , , , УровеньСжатияZIP.Максимальный);
Архиватор.Добавить(ИмяФайлаСообщения);
Архиватор.Записать();
УдалитьФайлы(ИмяФайлаСообщения);
КонецЕсли;
ПоместитьФайлВХранилище(ИмяФайлаДляПомещенияВХранилище, ИдентификаторФайла);
КонецПроцедуры
Процедура ВыполнитьВыгрузкуДляУзлаИнформационнойБазыЧерезФайл(Знач ИмяПланаОбмена,
Знач КодУзлаИнформационнойБазы,
Знач ПолноеИмяФайлаСообщенияОбмена) Экспорт
ПараметрыОбменаДанными = ПараметрыОбменаДаннымиЧерезФайлИлиСтроку();
ПараметрыОбменаДанными.ПолноеИмяФайлаСообщенияОбмена = ПолноеИмяФайлаСообщенияОбмена;
ПараметрыОбменаДанными.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ВыгрузкаДанных;
ПараметрыОбменаДанными.ИмяПланаОбмена = ИмяПланаОбмена;
ПараметрыОбменаДанными.КодУзлаИнформационнойБазы = КодУзлаИнформационнойБазы;
ВыполнитьОбменДаннымиДляУзлаИнформационнойБазыЧерезФайлИлиСтроку(ПараметрыОбменаДанными);
КонецПроцедуры
Процедура ВыполнитьВыгрузкуДляУзлаИнформационнойБазыЧерезСтроку(Знач ИмяПланаОбмена, Знач КодУзлаИнформационнойБазы, СообщениеОбмена) Экспорт
ПараметрыОбменаДанными = ПараметрыОбменаДаннымиЧерезФайлИлиСтроку();
ПараметрыОбменаДанными.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ВыгрузкаДанных;
ПараметрыОбменаДанными.ИмяПланаОбмена = ИмяПланаОбмена;
ПараметрыОбменаДанными.КодУзлаИнформационнойБазы = КодУзлаИнформационнойБазы;
ПараметрыОбменаДанными.СообщениеОбмена = СообщениеОбмена;
ВыполнитьОбменДаннымиДляУзлаИнформационнойБазыЧерезФайлИлиСтроку(ПараметрыОбменаДанными);
СообщениеОбмена = ПараметрыОбменаДанными.СообщениеОбмена;
КонецПроцедуры
Процедура ВыполнитьЗагрузкуДляУзлаИнформационнойБазыЧерезСтроку(Знач ИмяПланаОбмена, Знач КодУзлаИнформационнойБазы, СообщениеОбмена) Экспорт
ПараметрыОбменаДанными = ПараметрыОбменаДаннымиЧерезФайлИлиСтроку();
ПараметрыОбменаДанными.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ЗагрузкаДанных;
ПараметрыОбменаДанными.ИмяПланаОбмена = ИмяПланаОбмена;
ПараметрыОбменаДанными.КодУзлаИнформационнойБазы = КодУзлаИнформационнойБазы;
ПараметрыОбменаДанными.СообщениеОбмена = СообщениеОбмена;
ВыполнитьОбменДаннымиДляУзлаИнформационнойБазыЧерезФайлИлиСтроку(ПараметрыОбменаДанными);
СообщениеОбмена = ПараметрыОбменаДанными.СообщениеОбмена;
КонецПроцедуры
Процедура ВыполнитьЗагрузкуДляУзлаИнформационнойБазыИзСервисаПередачиФайлов(ПараметрыПроцедуры, АдресХранилища) Экспорт
ИмяПланаОбмена = ПараметрыПроцедуры["ИмяПланаОбмена"];
КодУзлаИнформационнойБазы = ПараметрыПроцедуры["КодУзлаИнформационнойБазы"];
ИдентификаторФайла = ПараметрыПроцедуры["ИдентификаторФайла"];
УстановитьПривилегированныйРежим(Истина);
ИмяВременногоФайла = ПолучитьФайлИзХранилища(ИдентификаторФайла);
ПараметрыОбменаДанными = ПараметрыОбменаДаннымиЧерезФайлИлиСтроку();
ПараметрыОбменаДанными.ПолноеИмяФайлаСообщенияОбмена = ИмяВременногоФайла;
ПараметрыОбменаДанными.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ЗагрузкаДанных;
ПараметрыОбменаДанными.ИмяПланаОбмена = ИмяПланаОбмена;
ПараметрыОбменаДанными.КодУзлаИнформационнойБазы = КодУзлаИнформационнойБазы;
Попытка
ВыполнитьОбменДаннымиДляУзлаИнформационнойБазыЧерезФайлИлиСтроку(ПараметрыОбменаДанными);
Исключение
ПредставлениеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
УдалитьФайлы(ИмяВременногоФайла);
ВызватьИсключение ПредставлениеОшибки;
КонецПопытки;
УдалитьФайлы(ИмяВременногоФайла);
КонецПроцедуры
Функция ПараметрыОбменаДаннымиЧерезФайлИлиСтроку() Экспорт
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("УзелИнформационнойБазы");
СтруктураПараметров.Вставить("ПолноеИмяФайлаСообщенияОбмена", "");
СтруктураПараметров.Вставить("ДействиеПриОбмене");
СтруктураПараметров.Вставить("ИмяПланаОбмена", "");
СтруктураПараметров.Вставить("КодУзлаИнформационнойБазы", "");
СтруктураПараметров.Вставить("СообщениеОбмена", "");
СтруктураПараметров.Вставить("ДатаНачалаОперации");
Возврат СтруктураПараметров;
КонецФункции
Процедура ВыполнитьОбменДаннымиДляУзлаИнформационнойБазыЧерезФайлИлиСтроку(ПараметрыОбмена) Экспорт
ПроверитьВозможностьВыполненияОбменов();
ПроверитьИспользованиеОбменаДанными();
УстановитьПривилегированныйРежим(Истина);
Если ПараметрыОбмена.УзелИнформационнойБазы = Неопределено Тогда
ИмяПланаОбмена = ПараметрыОбмена.ИмяПланаОбмена;
КодУзлаИнформационнойБазы = ПараметрыОбмена.КодУзлаИнформационнойБазы;
ПараметрыОбмена.УзелИнформационнойБазы = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодУзлаИнформационнойБазы);
Если ПараметрыОбмена.УзелИнформационнойБазы.Пустая()
И ЭтоПланОбменаXDTO(ИмяПланаОбмена) Тогда
ОшибкаПерехода = Ложь;
НастройкаСинхронизацииЧерезУФ = ПланыОбмена[ИмяПланаОбмена].ПереходНаСинхронизациюЧерезУниверсальныйФорматИнтернет(
КодУзлаИнформационнойБазы, ОшибкаПерехода);
Если ЗначениеЗаполнено(НастройкаСинхронизацииЧерезУФ) Тогда
ПараметрыОбмена.УзелИнформационнойБазы = НастройкаСинхронизацииЧерезУФ;
ИначеЕсли ОшибкаПерехода Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Не удалось выполнить переход на синхронизацию данных через универсальный формат.'");
ВызватьИсключение СтрокаСообщенияОбОшибке;
КонецЕсли;
КонецЕсли;
Если ПараметрыОбмена.УзелИнформационнойБазы.Пустая() Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Узел плана обмена %1 с кодом %2 не найден.'");
СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщенияОбОшибке, ИмяПланаОбмена, КодУзлаИнформационнойБазы);
ВызватьИсключение СтрокаСообщенияОбОшибке;
КонецЕсли;
КонецЕсли;
ВыполнитьОбновлениеНастроекОбмена(ПараметрыОбмена.УзелИнформационнойБазы);
Если Не НастройкаСинхронизацииЗавершена(ПараметрыОбмена.УзелИнформационнойБазы) Тогда
ПредставлениеПрограммы = ?(ОбщегоНазначения.РазделениеВключено(),
Метаданные.Синоним, ОбменДаннымиПовтИсп.ИмяЭтойИнформационнойБазы());
ДанныеКорреспондента = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ПараметрыОбмена.УзелИнформационнойБазы,
"Код, Наименование");
СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'В ""%1"" настройка синхронизации данных с ""%2"" (идентификатор ""%3"") еще не завершена.'"),
ПредставлениеПрограммы, ДанныеКорреспондента.Наименование, ДанныеКорреспондента.Код);
ВызватьИсключение СтрокаСообщенияОбОшибке;
КонецЕсли;
// ИНИЦИАЛИЗАЦИЯ ОБМЕНА ДАННЫМИ
СтруктураНастроекОбмена = НастройкиОбменаДляУзлаИнформационнойБазы(
ПараметрыОбмена.УзелИнформационнойБазы, ПараметрыОбмена.ДействиеПриОбмене, Неопределено, Ложь);
Если ЗначениеЗаполнено(ПараметрыОбмена.ДатаНачалаОперации) Тогда
СтруктураНастроекОбмена.ДатаНачала = ПараметрыОбмена.ДатаНачалаОперации;
КонецЕсли;
ЗафиксироватьНачалоОбменаВРегистреСведений(СтруктураНастроекОбмена);
Если СтруктураНастроекОбмена.Отказ Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Ошибка при инициализации процесса обмена данными.'");
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
ВызватьИсключение СтрокаСообщенияОбОшибке;
КонецЕсли;
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено;
СтрокаСообщения = НСтр("ru = 'Начало процесса обмена данными для узла %1'", ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, СтруктураНастроекОбмена.УзелИнформационнойБазыНаименование);
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщения, СтруктураНастроекОбмена);
Если СтруктураНастроекОбмена.ПроизводитьЗагрузкуДанных Тогда
СозданВременныйФайл = Ложь;
Если ПараметрыОбмена.ПолноеИмяФайлаСообщенияОбмена = ""
И ПараметрыОбмена.СообщениеОбмена <> "" Тогда
ПараметрыОбмена.ПолноеИмяФайлаСообщенияОбмена = ПолучитьИмяВременногоФайла(".xml");
ТекстовыйФайл = Новый ТекстовыйДокумент;
ТекстовыйФайл.УстановитьТекст(ПараметрыОбмена.СообщениеОбмена);
ТекстовыйФайл.Записать(ПараметрыОбмена.ПолноеИмяФайлаСообщенияОбмена);
СозданВременныйФайл = Истина;
КонецЕсли;
ПрочитатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена, ПараметрыОбмена.ПолноеИмяФайлаСообщенияОбмена, ПараметрыОбмена.СообщениеОбмена);
// {Обработчик: ПослеЧтенияСообщенияОбмена} Начало
СтандартнаяОбработка = Истина;
ПослеЧтенияСообщенияОбмена(
СтруктураНастроекОбмена.УзелИнформационнойБазы,
ПараметрыОбмена.ПолноеИмяФайлаСообщенияОбмена,
РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена),
СтандартнаяОбработка);
// {Обработчик: ПослеЧтенияСообщенияОбмена} Окончание
Если СозданВременныйФайл Тогда
Попытка
УдалитьФайлы(ПараметрыОбмена.ПолноеИмяФайлаСообщенияОбмена);
Исключение
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЕсли;
ИначеЕсли СтруктураНастроекОбмена.ПроизводитьВыгрузкуДанных Тогда
ЗаписатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена, ПараметрыОбмена.ПолноеИмяФайлаСообщенияОбмена, ПараметрыОбмена.СообщениеОбмена);
КонецЕсли;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Если Не РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена) Тогда
ВызватьИсключение СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке;
КонецЕсли;
КонецПроцедуры
Процедура ЗафиксироватьЗавершениеОбменаЧерезВнешнееСоединение(СтруктураНастроекОбмена) Экспорт
УстановитьПривилегированныйРежим(Истина);
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
КонецПроцедуры
Функция СтруктураНастроекОбменаЧерезВнешнееСоединение(Структура) Экспорт
ПроверитьИспользованиеОбменаДанными();
УстановитьПривилегированныйРежим(Истина);
УзелИнформационнойБазы = ПланыОбмена[Структура.ИмяПланаОбмена].НайтиПоКоду(Структура.ТекущийУзелПланаОбменаКод);
ДействиеПриОбмене = Перечисления.ДействияПриОбмене[Структура.ДействиеПриОбменеСтрокой];
СтруктураНастроекОбменаВнешнееСоединение = Новый Структура;
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ИмяПланаОбмена", Структура.ИмяПланаОбмена);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("РежимОтладки", Структура.РежимОтладки);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("УзелИнформационнойБазы", УзелИнформационнойБазы);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("УзелИнформационнойБазыНаименование", ОбщегоНазначения.ЗначениеРеквизитаОбъекта(УзелИнформационнойБазы, "Наименование"));
СтруктураНастроекОбменаВнешнееСоединение.Вставить("КлючСообщенияЖурналаРегистрации", КлючСообщенияЖурналаРегистрации(УзелИнформационнойБазы, ДействиеПриОбмене));
СтруктураНастроекОбменаВнешнееСоединение.Вставить("РезультатВыполненияОбмена", Неопределено);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("РезультатВыполненияОбменаСтрокой", "");
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ДействиеПриОбмене", ДействиеПриОбмене);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ОтладкаОбработчиковВыгрузки ", Ложь);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ОтладкаОбработчиковЗагрузки", Ложь);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ИмяФайлаВнешнейОбработкиОтладкиВыгрузки", "");
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ИмяФайлаВнешнейОбработкиОтладкиЗагрузки", "");
СтруктураНастроекОбменаВнешнееСоединение.Вставить("РежимПротоколированияОбменаДанными", Ложь);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ИмяФайлаПротоколаОбмена", "");
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ПродолжитьПриОшибке", Ложь);
УстановитьНастройкиРежимаОтладкиДляСтруктуры(СтруктураНастроекОбменаВнешнееСоединение, Истина);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("КоличествоОбъектовОбработано", 0);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ДатаНачала", Неопределено);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ДатаОкончания", Неопределено);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("СообщениеПриОбмене", "");
СтруктураНастроекОбменаВнешнееСоединение.Вставить("СтрокаСообщенияОбОшибке", "");
СтруктураНастроекОбменаВнешнееСоединение.Вставить("КоличествоЭлементовВТранзакции", Структура.КоличествоЭлементовВТранзакции);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ЭтоОбменВРИБ", Ложь);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("НастройкаСинхронизацииДанныхЗавершена", Ложь);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ПолученоСообщениеДляСопоставленияДанных", Ложь);
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ПоддерживаетсяСопоставлениеДанных", Истина);
Если ЗначениеЗаполнено(УзелИнформационнойБазы) Тогда
СтруктураНастроекОбменаВнешнееСоединение.НастройкаСинхронизацииДанныхЗавершена = НастройкаСинхронизацииЗавершена(УзелИнформационнойБазы);
СтруктураНастроекОбменаВнешнееСоединение.ПолученоСообщениеДляСопоставленияДанных = ПолученоСообщениеСДаннымиДляСопоставления(УзелИнформационнойБазы);
СтруктураНастроекОбменаВнешнееСоединение.ПоддерживаетсяСопоставлениеДанных = ЗначениеНастройкиПланаОбмена(Структура.ИмяПланаОбмена,
"ПоддерживаетсяСопоставлениеДанных", СохраненныйВариантНастройкиУзлаПланаОбмена(УзелИнформационнойБазы));
КонецЕсли;
Возврат СтруктураНастроекОбменаВнешнееСоединение;
КонецФункции
Функция ПолучитьПравилаКонвертацииОбъектовЧерезВнешнееСоединение(ИмяПланаОбмена, ПолучатьПравилаКорреспондента = Ложь) Экспорт
УстановитьПривилегированныйРежим(Истина);
Возврат РегистрыСведений.ПравилаДляОбменаДанными.ЗачитанныеПравилаКонвертацииОбъектов(ИмяПланаОбмена, ПолучатьПравилаКорреспондента);
КонецФункции
Процедура ВыполнитьДействиеОбменаДляУзлаИнформационнойБазыЧерезWebСервис(Отказ,
УзелИнформационнойБазы, ДействиеПриОбмене, ПараметрыОбмена)
ТолькоПараметры = ПараметрыОбмена.ТолькоПараметры;
УстановитьПривилегированныйРежим(Истина);
// ИНИЦИАЛИЗАЦИЯ ОБМЕНА ДАННЫМИ
СтруктураНастроекОбмена = НастройкиОбменаДляУзлаИнформационнойБазы(
УзелИнформационнойБазы, ДействиеПриОбмене, Перечисления.ВидыТранспортаСообщенийОбмена.WS, Ложь);
ЗафиксироватьНачалоОбменаВРегистреСведений(СтруктураНастроекОбмена);
Если СтруктураНастроекОбмена.Отказ Тогда
// Если настройка содержит ошибки, то обмен не производим; статус "Отменено".
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Отказ = Истина;
Возврат;
КонецЕсли;
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено;
СтрокаСообщения = НСтр("ru = 'Начало процесса обмена данными для узла %1'", ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, СтруктураНастроекОбмена.УзелИнформационнойБазыНаименование);
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщения, СтруктураНастроекОбмена);
Если СтруктураНастроекОбмена.ПроизводитьЗагрузкуДанных Тогда
Если СтруктураНастроекОбмена.ИспользоватьПередачуБольшогоОбъемаДанных Тогда
// {Обработчик: ПередЧтениемСообщенияОбмена} Начало
ФайлСообщенияОбмена = "";
СтандартнаяОбработка = Истина;
ПередЧтениемСообщенияОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы, ФайлСообщенияОбмена, СтандартнаяОбработка);
// {Обработчик: ПередЧтениемСообщенияОбмена} Окончание
Если СтандартнаяОбработка Тогда
Прокси = Неопределено;
ПараметрыПрокси = Новый Структура;
ПараметрыПрокси.Вставить("ПараметрыАутентификации", ПараметрыОбмена.ПараметрыАутентификации);
СостояниеНастройки = Неопределено;
СообщениеОбОшибке = "";
ИнициализироватьWSПроксиДляУправленияОбменомДанными(Прокси, СтруктураНастроекОбмена, ПараметрыПрокси, Отказ, СостояниеНастройки, СообщениеОбОшибке);
Если Отказ Тогда
ЗаписьЖурналаРегистрацииОбменаДанными(СообщениеОбОшибке, СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
ФайлСообщенияОбмена = "";
Попытка
Прокси.UploadData(СтруктураНастроекОбмена.ИмяПланаОбмена,
СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
ПараметрыОбмена.ИдентификаторФайла,
ПараметрыОбмена.ДлительнаяОперация,
ПараметрыОбмена.ИдентификаторОперации,
ПараметрыОбмена.ДлительнаяОперацияРазрешена);
Если ПараметрыОбмена.ДлительнаяОперация Тогда
Если ПараметрыОбмена.ИнтервалОжиданияНаСервере > 0 Тогда
Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
МодульОбщегоНазначенияБТС = ОбщегоНазначения.ОбщийМодуль("ОбщегоНазначенияБТС");
Пока ПараметрыОбмена.ДлительнаяОперация Цикл
МодульОбщегоНазначенияБТС.Пауза(ПараметрыОбмена.ИнтервалОжиданияНаСервере);
СтрокаСообщенияОбОшибке = "";
СостояниеОперации = Прокси.GetContinuousOperationStatus(ПараметрыОбмена.ИдентификаторОперации, СтрокаСообщенияОбОшибке);
Если СостояниеОперации = "Active" Тогда
ПараметрыОбмена.ИнтервалОжиданияНаСервере = Мин(ПараметрыОбмена.ИнтервалОжиданияНаСервере + 30, 180);
Продолжить;
ИначеЕсли СостояниеОперации <> "Completed" Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Ошибка в базе-корреспонденте: %1'"),
СтрокаСообщенияОбОшибке);
Иначе
ПараметрыОбмена.ДлительнаяОперация = Ложь;
КонецЕсли;
КонецЦикла;
Иначе
ВызватьИсключение НСтр("ru = 'Запуск асинхронной операции на сервере без подсистемы ""ТехнологияСервиса.БазоваяФункциональность"" не поддерживается.'");
КонецЕсли;
Иначе
ЗаписьЖурналаРегистрацииОбменаДанными(НСтр("ru = 'Ожидание получения данных от базы-корреспондента...'",
ОбщегоНазначения.КодОсновногоЯзыка()), СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
КонецЕсли;
ФайлСообщенияОбмена = ПолучитьФайлИзХранилищаВСервисе(
Новый УникальныйИдентификатор(ПараметрыОбмена.ИдентификаторФайла),
УзелИнформационнойБазы,,
ПараметрыОбмена.ПараметрыАутентификации);
Исключение
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
Отказ = Истина;
КонецПопытки;
КонецЕсли;
Если Не Отказ Тогда
ПрочитатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена, ФайлСообщенияОбмена,, ТолькоПараметры);
КонецЕсли;
// {Обработчик: ПослеЧтенияСообщенияОбмена} Начало
СтандартнаяОбработка = Истина;
ПослеЧтенияСообщенияОбмена(
СтруктураНастроекОбмена.УзелИнформационнойБазы,
ФайлСообщенияОбмена,
РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена),
СтандартнаяОбработка,
Не ТолькоПараметры);
// {Обработчик: ПослеЧтенияСообщенияОбмена} Окончание
Если СтандартнаяОбработка Тогда
Попытка
Если Не ПустаяСтрока(ФайлСообщенияОбмена) И ТипЗнч(СообщениеОбменаДаннымиИзГлавногоУзла()) <> Тип("Структура") Тогда
УдалитьФайлы(ФайлСообщенияОбмена);
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЕсли;
Иначе
Прокси = Неопределено;
ПараметрыПрокси = Новый Структура;
ПараметрыПрокси.Вставить("ПараметрыАутентификации", ПараметрыОбмена.ПараметрыАутентификации);
СостояниеНастройки = Неопределено;
СообщениеОбОшибке = "";
ИнициализироватьWSПроксиДляУправленияОбменомДанными(Прокси, СтруктураНастроекОбмена, ПараметрыПрокси, Отказ, СостояниеНастройки, СообщениеОбОшибке);
Если Отказ Тогда
ЗаписьЖурналаРегистрацииОбменаДанными(СообщениеОбОшибке, СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
ХранилищеСообщенияОбмена = Неопределено;
Попытка
Прокси.Upload(СтруктураНастроекОбмена.ИмяПланаОбмена, СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод, ХранилищеСообщенияОбмена);
ПрочитатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена,, ХранилищеСообщенияОбмена.Получить());
Исключение
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
КонецПопытки;
КонецЕсли;
ИначеЕсли СтруктураНастроекОбмена.ПроизводитьВыгрузкуДанных Тогда
Прокси = Неопределено;
ПараметрыПрокси = Новый Структура;
ПараметрыПрокси.Вставить("ПараметрыАутентификации", ПараметрыОбмена.ПараметрыАутентификации);
Если ПараметрыОбмена.СообщениеДляСопоставленияДанных Тогда
ПараметрыПрокси.Вставить("МинимальнаяВерсия", "3.0.1.1");
КонецЕсли;
СостояниеНастройки = Неопределено;
СообщениеОбОшибке = "";
ИнициализироватьWSПроксиДляУправленияОбменомДанными(Прокси, СтруктураНастроекОбмена, ПараметрыПрокси, Отказ, СостояниеНастройки, СообщениеОбОшибке);
Если Отказ Тогда
ЗаписьЖурналаРегистрацииОбменаДанными(СообщениеОбОшибке, СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
Если СтруктураНастроекОбмена.ИспользоватьПередачуБольшогоОбъемаДанных Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
ФайлСообщенияОбмена = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(
ВременныйКаталог, УникальноеИмяФайлаСообщенияОбмена());
Попытка
ЗаписатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена, ФайлСообщенияОбмена);
Исключение
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
Отказ = Истина;
КонецПопытки;
// Отправка сообщения обмена только в случае успешной выгрузки данных.
Если РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена) И Не Отказ Тогда
Попытка
ИдентификаторФайлаСтрокой = Строка(ПоместитьФайлВХранилищеВСервисе(
ФайлСообщенияОбмена, УзелИнформационнойБазы,, ПараметрыОбмена.ПараметрыАутентификации));
Попытка
УдалитьФайлы(ВременныйКаталог);
Исключение
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Если ПараметрыОбмена.СообщениеДляСопоставленияДанных
И (СостояниеНастройки.ПоддерживаетсяСопоставлениеДанных
Или Не СостояниеНастройки.НастройкаСинхронизацииДанныхЗавершена) Тогда
Прокси.PutMessageForDataMatching(СтруктураНастроекОбмена.ИмяПланаОбмена,
СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
ИдентификаторФайлаСтрокой);
Иначе
Прокси.DownloadData(СтруктураНастроекОбмена.ИмяПланаОбмена,
СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
ИдентификаторФайлаСтрокой,
ПараметрыОбмена.ДлительнаяОперация,
ПараметрыОбмена.ИдентификаторОперации,
ПараметрыОбмена.ДлительнаяОперацияРазрешена);
Если ПараметрыОбмена.ДлительнаяОперация Тогда
Если ПараметрыОбмена.ИнтервалОжиданияНаСервере > 0 Тогда
Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
МодульОбщегоНазначенияБТС = ОбщегоНазначения.ОбщийМодуль("ОбщегоНазначенияБТС");
Пока ПараметрыОбмена.ДлительнаяОперация Цикл
МодульОбщегоНазначенияБТС.Пауза(ПараметрыОбмена.ИнтервалОжиданияНаСервере);
СтрокаСообщенияОбОшибке = "";
СостояниеОперации = Прокси.GetContinuousOperationStatus(ПараметрыОбмена.ИдентификаторОперации, СтрокаСообщенияОбОшибке);
Если СостояниеОперации = "Active" Тогда
Продолжить;
ИначеЕсли СостояниеОперации <> "Completed" Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Ошибка в базе-корреспонденте: %1'"),
СтрокаСообщенияОбОшибке);
Иначе
ПараметрыОбмена.ДлительнаяОперация = Ложь;
КонецЕсли;
КонецЦикла;
Иначе
ВызватьИсключение НСтр("ru = 'Запуск асинхронной операции на сервере без подсистемы ""ТехнологияСервиса.БазоваяФункциональность"" не поддерживается.'");
КонецЕсли;
Иначе
ЗаписьЖурналаРегистрацииОбменаДанными(НСтр("ru = 'Ожидание загрузки данных в базе-корреспонденте...'",
ОбщегоНазначения.КодОсновногоЯзыка()), СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
Отказ = Истина;
КонецПопытки;
КонецЕсли;
Попытка
УдалитьФайлы(ВременныйКаталог);
Исключение
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Иначе
СообщениеОбмена = "";
Попытка
ЗаписатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена,, СообщениеОбмена);
// Отправка сообщения обмена только в случае успешной выгрузки данных.
Если РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена) Тогда
Прокси.Download(СтруктураНастроекОбмена.ИмяПланаОбмена,
СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод,
Новый ХранилищеЗначения(СообщениеОбмена, Новый СжатиеДанных(9)));
КонецЕсли;
Исключение
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
КонецПопытки;
КонецЕсли;
КонецЕсли;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Если Не РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена) Тогда
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьДействиеОбменаДляУзлаИнформационнойБазыПоВнешнемуСоединению(Отказ, УзелИнформационнойБазы,
ДействиеПриОбмене,
КоличествоЭлементовВТранзакции,
СообщениеДляСопоставленияДанных = Ложь)
УстановитьПривилегированныйРежим(Истина);
// ИНИЦИАЛИЗАЦИЯ ОБМЕНА ДАННЫМИ
СтруктураНастроекОбмена = НастройкиОбменаДляВнешнегоСоединения(
УзелИнформационнойБазы,
ДействиеПриОбмене,
КоличествоЭлементовВТранзакции);
ЗаписьЖурналаРегистрацииНачалаОбменаДанными(СтруктураНастроекОбмена);
Если СтруктураНастроекОбмена.Отказ Тогда
// Если настройка содержит ошибки, то обмен не производим; статус "Отменено".
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Отказ = Истина;
Возврат;
КонецЕсли;
СтрокаСообщенияОбОшибке = "";
// Получаем внешнее соединение для узла информационной базы.
ВнешнееСоединение = ОбменДаннымиПовтИсп.ПолучитьВнешнееСоединениеДляУзлаИнформационнойБазы(
УзелИнформационнойБазы,
СтрокаСообщенияОбОшибке);
Если ВнешнееСоединение = Неопределено Тогда
// добавляем запись в ЖР
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
// Если настройка содержит ошибки, то обмен не производим; статус "Отменено".
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Отказ = Истина;
Возврат;
КонецЕсли;
// Получаем версию удаленной базы.
ВерсияБСППоВнешнемуСоединению = ВнешнееСоединение.СтандартныеПодсистемыСервер.ВерсияБиблиотеки();
ОбменСБСП20 = ОбщегоНазначенияКлиентСервер.СравнитьВерсии("2.1.1.10", ВерсияБСППоВнешнемуСоединению) > 0;
// ИНИЦИАЛИЗАЦИЯ ОБМЕНА ДАННЫМИ (ВНЕШНЕЕ СОЕДИНЕНИЕ)
Структура = Новый Структура("ИмяПланаОбмена, ТекущийУзелПланаОбменаКод, КоличествоЭлементовВТранзакции");
ЗаполнитьЗначенияСвойств(Структура, СтруктураНастроекОбмена);
// Выполняем реверс значений перечисления.
ДействиеПриОбменеСтрокой = ?(ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ВыгрузкаДанных,
ОбщегоНазначения.ИмяЗначенияПеречисления(Перечисления.ДействияПриОбмене.ЗагрузкаДанных),
ОбщегоНазначения.ИмяЗначенияПеречисления(Перечисления.ДействияПриОбмене.ВыгрузкаДанных));
//
Структура.Вставить("ДействиеПриОбменеСтрокой", ДействиеПриОбменеСтрокой);
Структура.Вставить("РежимОтладки", Ложь);
Структура.Вставить("ИмяФайлаПротоколаОбмена", "");
ЭтоПланОбменаXDTO = ЭтоПланОбменаXDTO(УзелИнформационнойБазы);
Если ЭтоПланОбменаXDTO Тогда
// Проверка псевдонима предопределенного узла
ПсевдонимПредопределенногоУзла = ПсевдонимПредопределенногоУзла(УзелИнформационнойБазы);
ПланОбменаМенеджер = ВнешнееСоединение.ПланыОбмена[Структура.ИмяПланаОбмена];
ПроверятьНаличиеУзлаВКорреспонденте = Истина;
Если ЗначениеЗаполнено(ПсевдонимПредопределенногоУзла) Тогда
// Надо проверить код узла в корреспонденте - он может быть уже перекодирован.
// Тогда псевдоним больше не нужен.
Если ПланОбменаМенеджер.НайтиПоКоду(ПсевдонимПредопределенногоУзла) <> ПланОбменаМенеджер.ПустаяСсылка() Тогда
Структура.ТекущийУзелПланаОбменаКод = ПсевдонимПредопределенногоУзла;
ПроверятьНаличиеУзлаВКорреспонденте = Ложь;
КонецЕсли;
КонецЕсли;
Если ПроверятьНаличиеУзлаВКорреспонденте Тогда
ПланОбменаСсылка = ПланОбменаМенеджер.НайтиПоКоду(Структура.ТекущийУзелПланаОбменаКод);
Если НЕ ЗначениеЗаполнено(ПланОбменаСсылка.Code) Тогда
// При необходимости запуск перехода на синхронизацию данных через универсальный формат.
ТекстСообщения = НСтр("ru = 'Необходим переход на синхронизацию данных через универсальный формат в базе-корреспонденте.'");
ЗаписьЖурналаРегистрацииОбменаДанными(ТекстСообщения, СтруктураНастроекОбмена, Ложь);
СтруктураПараметров = Новый Структура();
СтруктураПараметров.Вставить("Код", Структура.ТекущийУзелПланаОбменаКод);
СтруктураПараметров.Вставить("ВариантНастройки",
ОбщегоНазначения.ЗначениеРеквизитаОбъекта(УзелИнформационнойБазы, "ВариантНастройки"));
СтруктураПараметров.Вставить("Ошибка", Ложь);
СтруктураПараметров.Вставить("СообщениеОбОшибке", "");
ЕстьОшибки = Ложь;
СтрокаСообщенияОбОшибке = "";
РезультатПерехода =
ПланОбменаМенеджер.ПереходНаСинхронизациюЧерезУниверсальныйФорматВнешнееСоединение(СтруктураПараметров);
Если СтруктураПараметров.Ошибка Тогда
ЕстьОшибки = Истина;
НСтрока = НСтр("ru = 'Ошибка при переходе на синхронизацию данных через универсальный формат: %1. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтрока,
СтруктураПараметров.СообщениеОбОшибке);
ИначеЕсли РезультатПерехода = Неопределено Тогда
ЕстьОшибки = Истина;
СтрокаСообщенияОбОшибке = НСтр("ru = 'Переход на синхронизацию данных через универсальный формат не выполнен'");
КонецЕсли;
Если ЕстьОшибки Тогда
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Отказ = Истина;
Возврат;
Иначе
Сообщение = НСтр("ru = 'Переход на синхронизацию данных через универсальный формат завершен успешно.'");
ЗаписьЖурналаРегистрацииОбменаДанными(Сообщение, СтруктураНастроекОбмена, Ложь);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Попытка
СтруктураНастроекОбменаВнешнееСоединение = ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.СтруктураНастроекОбмена(Структура);
Исключение
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Отказ = Истина;
Возврат;
КонецПопытки;
Если СтруктураНастроекОбменаВнешнееСоединение.Свойство("НастройкаСинхронизацииДанныхЗавершена") Тогда
Если Не СообщениеДляСопоставленияДанных
И СтруктураНастроекОбменаВнешнееСоединение.НастройкаСинхронизацииДанныхЗавершена = Ложь Тогда
СообщениеОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Для продолжения необходимо перейти в программу ""%1"" и завершить в ней настройку синхронизации.
|Выполнение обмена данными отменено.'"),
СтруктураНастроекОбменаВнешнееСоединение.УзелИнформационнойБазыНаименование);
ЗаписьЖурналаРегистрацииОбменаДанными(СообщениеОбОшибке, СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Отказ = Истина;
Возврат;
КонецЕсли;
КонецЕсли;
Если СтруктураНастроекОбменаВнешнееСоединение.Свойство("ПолученоСообщениеДляСопоставленияДанных") Тогда
Если Не СообщениеДляСопоставленияДанных
И СтруктураНастроекОбменаВнешнееСоединение.ПолученоСообщениеДляСопоставленияДанных = Истина Тогда
СообщениеОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Для продолжения необходимо перейти в программу ""%1"" и выполнить загрузку сообщения для сопоставления данных.
|Выполнение обмена данными отменено.'"),
СтруктураНастроекОбменаВнешнееСоединение.УзелИнформационнойБазыНаименование);
ЗаписьЖурналаРегистрацииОбменаДанными(СообщениеОбОшибке, СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Отказ = Истина;
Возврат;
КонецЕсли;
КонецЕсли;
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено;
СтруктураНастроекОбменаВнешнееСоединение.Вставить("ДатаНачала", ВнешнееСоединение.ТекущаяДатаСеанса());
ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.ЗаписьЖурналаРегистрацииНачалаОбменаДанными(СтруктураНастроекОбменаВнешнееСоединение);
// ОБМЕН ДАННЫМИ
Если СтруктураНастроекОбмена.ПроизводитьЗагрузкуДанных Тогда
Если НЕ ЭтоПланОбменаXDTO Тогда
// Получаем правила обмена из второй ИБ.
ПравилаКонвертацииОбъектов = ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.ПолучитьПравилаКонвертацииОбъектов(СтруктураНастроекОбменаВнешнееСоединение.ИмяПланаОбмена);
Если ПравилаКонвертацииОбъектов = Неопределено Тогда
// Правила обмена должны быть указаны.
НСтрока = НСтр("ru = 'Не заданы правила конвертации во второй информационной базе для плана обмена %1. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтрока, СтруктураНастроекОбменаВнешнееСоединение.ИмяПланаОбмена);
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
КонецЕсли;
// Обработка для загрузки данных.
ОбработкаДляЗагрузкиДанных = СтруктураНастроекОбмена.ОбработкаОбменаДанными;
ОбработкаДляЗагрузкиДанных.ИмяФайлаОбмена = "";
ОбработкаДляЗагрузкиДанных.КоличествоОбъектовНаТранзакцию = СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции;
ОбработкаДляЗагрузкиДанных.ИспользоватьТранзакции = (ОбработкаДляЗагрузкиДанных.КоличествоОбъектовНаТранзакцию <> 1);
ОбработкаДляЗагрузкиДанных.ЗагрузкаДанныхВыполняетсяЧерезВнешнееСоединение = Истина;
// Получаем инициализированную обработку для выгрузки данных.
Если ЭтоПланОбменаXDTO Тогда
ОбработкаОбменаДаннымиВнешнееСоединение = ВнешнееСоединение.Обработки.КонвертацияОбъектовXDTO.Создать();
ОбработкаОбменаДаннымиВнешнееСоединение.РежимОбмена = "Выгрузка";
Иначе
ОбработкаОбменаДаннымиВнешнееСоединение = ВнешнееСоединение.Обработки.КонвертацияОбъектовИнформационныхБаз.Создать();
ОбработкаОбменаДаннымиВнешнееСоединение.СохраненныеНастройки = ПравилаКонвертацииОбъектов;
ОбработкаОбменаДаннымиВнешнееСоединение.ЗагрузкаДанныхВыполняетсяВоВнешнемСоединении = Ложь;
ОбработкаОбменаДаннымиВнешнееСоединение.РежимОбмена = "Выгрузка";
Попытка
ОбработкаОбменаДаннымиВнешнееСоединение.ВосстановитьПравилаИзВнутреннегоФормата();
Исключение
ЗаписьЖурналаРегистрацииОбменаДанными(
СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Возникла ошибка во второй информационной базе: %1'"),
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())), СтруктураНастроекОбмена, Истина);
// Если настройка содержит ошибки, то обмен не производим; статус "Отменено".
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
Отказ = Истина;
Возврат;
КонецПопытки;
// Задаем узлы обмена.
ОбработкаОбменаДаннымиВнешнееСоединение.УзелДляФоновогоОбмена = Неопределено;
ОбработкаОбменаДаннымиВнешнееСоединение.НеВыгружатьОбъектыПоСсылкам = Истина;
ОбработкаОбменаДаннымиВнешнееСоединение.ИмяФайлаПравилОбмена = "1";
ОбработкаОбменаДаннымиВнешнееСоединение.ВнешнееСоединение = Неопределено;
КонецЕсли;
// Задаем узлы обмена (общие для любого вида обмена).
ОбработкаОбменаДаннымиВнешнееСоединение.УзелДляОбмена = СтруктураНастроекОбменаВнешнееСоединение.УзелИнформационнойБазы;
УстановитьОбщиеПараметрыДляОбработкиОбменаДанными(ОбработкаОбменаДаннымиВнешнееСоединение, СтруктураНастроекОбменаВнешнееСоединение, ОбменСБСП20);
Если НЕ ЭтоПланОбменаXDTO Тогда
ВерсияКонфигурацииПриемника = "";
ВерсияИсточникаИзПравил = "";
ТекстСообщения = "";
ПараметрыВнешнегоСоединения = Новый Структура;
ПараметрыВнешнегоСоединения.Вставить("ВнешнееСоединение", ВнешнееСоединение);
ПараметрыВнешнегоСоединения.Вставить("ВерсияБСППоВнешнемуСоединению", ВерсияБСППоВнешнемуСоединению);
ПараметрыВнешнегоСоединения.Вставить("КлючСообщенияЖурналаРегистрации", СтруктураНастроекОбменаВнешнееСоединение.КлючСообщенияЖурналаРегистрации);
ПараметрыВнешнегоСоединения.Вставить("УзелИнформационнойБазы", СтруктураНастроекОбменаВнешнееСоединение.УзелИнформационнойБазы);
ПравилаКонвертацииОбъектов.Получить().Конвертация.Свойство("ВерсияКонфигурацииИсточника", ВерсияКонфигурацииПриемника);
ОбработкаДляЗагрузкиДанных.СохраненныеНастройки.Получить().Конвертация.Свойство("ВерсияКонфигурацииИсточника", ВерсияИсточникаИзПравил);
Если РазличаютсяВерсииКорреспондента(СтруктураНастроекОбмена.ИмяПланаОбмена, СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации,
ВерсияИсточникаИзПравил, ВерсияКонфигурацииПриемника, ТекстСообщения, ПараметрыВнешнегоСоединения) Тогда
ОбработкаОбменаДаннымиВнешнееСоединение = Неопределено;
Возврат;
КонецЕсли;
КонецЕсли;
// ВЫГРУЗКА (КОРРЕСПОНДЕНТ) - ЗАГРУЗКА (ЭТА БАЗА)
ОбработкаОбменаДаннымиВнешнееСоединение.ВыполнитьВыгрузкуДанных(ОбработкаДляЗагрузкиДанных);
// Фиксируем состояние выполнения обмена данными.
СтруктураНастроекОбмена.РезультатВыполненияОбмена = ОбработкаДляЗагрузкиДанных.РезультатВыполненияОбмена();
СтруктураНастроекОбмена.КоличествоОбъектовОбработано = ОбработкаДляЗагрузкиДанных.СчетчикЗагруженныхОбъектов();
СтруктураНастроекОбменаВнешнееСоединение.РезультатВыполненияОбменаСтрокой = ОбработкаОбменаДаннымиВнешнееСоединение.РезультатВыполненияОбменаСтрокой();
СтруктураНастроекОбменаВнешнееСоединение.КоличествоОбъектовОбработано = ОбработкаОбменаДаннымиВнешнееСоединение.СчетчикВыгруженныхОбъектов();
СтруктураНастроекОбмена.СообщениеПриОбмене = ОбработкаДляЗагрузкиДанных.КомментарийПриЗагрузкеДанных;
СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке = ОбработкаДляЗагрузкиДанных.СтрокаСообщенияОбОшибке();
СтруктураНастроекОбменаВнешнееСоединение.СообщениеПриОбмене = ОбработкаОбменаДаннымиВнешнееСоединение.КомментарийПриВыгрузкеДанных;
СтруктураНастроекОбменаВнешнееСоединение.СтрокаСообщенияОбОшибке = ОбработкаОбменаДаннымиВнешнееСоединение.СтрокаСообщенияОбОшибке();
ОбработкаОбменаДаннымиВнешнееСоединение = Неопределено;
ИначеЕсли СтруктураНастроекОбмена.ПроизводитьВыгрузкуДанных Тогда
// Обработка для загрузки данных.
Если ЭтоПланОбменаXDTO Тогда
ОбработкаДляЗагрузкиДанных = ВнешнееСоединение.Обработки.КонвертацияОбъектовXDTO.Создать();
Иначе
ОбработкаДляЗагрузкиДанных = ВнешнееСоединение.Обработки.КонвертацияОбъектовИнформационныхБаз.Создать();
ОбработкаДляЗагрузкиДанных.ЗагрузкаДанныхВыполняетсяЧерезВнешнееСоединение = Истина;
КонецЕсли;
ОбработкаДляЗагрузкиДанных.РежимОбмена = "Загрузка";
ОбработкаДляЗагрузкиДанных.УзелОбменаЗагрузкаДанных = СтруктураНастроекОбменаВнешнееСоединение.УзелИнформационнойБазы;
УстановитьОбщиеПараметрыДляОбработкиОбменаДанными(ОбработкаДляЗагрузкиДанных, СтруктураНастроекОбменаВнешнееСоединение, ОбменСБСП20);
ЕстьПоддержкаСопоставления = Истина;
НастройкаСинхронизацииДанныхЗавершена = Истина;
ВерсииИнтерфейса = ВерсииИнтерфейсаЧерезВнешнееСоединение(ВнешнееСоединение);
Если ВерсииИнтерфейса.Найти("3.0.1.1") <> Неопределено Тогда
СообщениеОбОшибке = "";
ПараметрыИнформационнойБазы = ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.ПолучитьПараметрыИнформационнойБазы_2_0_1_6(
СтруктураНастроекОбмена.ИмяПланаОбмена, СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод, СообщениеОбОшибке);
ПараметрыКорреспондента = ОбщегоНазначения.ЗначениеИзСтрокиXML(ПараметрыИнформационнойБазы);
Если ПараметрыКорреспондента.Свойство("ПоддерживаетсяСопоставлениеДанных") Тогда
ЕстьПоддержкаСопоставления = ПараметрыКорреспондента.ПоддерживаетсяСопоставлениеДанных;
КонецЕсли;
Если ПараметрыКорреспондента.Свойство("НастройкаСинхронизацииДанныхЗавершена") Тогда
НастройкаСинхронизацииДанныхЗавершена = ПараметрыКорреспондента.НастройкаСинхронизацииДанныхЗавершена;
КонецЕсли;
КонецЕсли;
Если СообщениеДляСопоставленияДанных
И (ЕстьПоддержкаСопоставления Или Не НастройкаСинхронизацииДанныхЗавершена) Тогда
ОбработкаДляЗагрузкиДанных.РежимЗагрузкиДанных = "ЗагрузкаСообщенияДляСопоставленияДанных";
КонецЕсли;
ОбработкаДляЗагрузкиДанных.КоличествоОбъектовНаТранзакцию = СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции;
ОбработкаДляЗагрузкиДанных.ИспользоватьТранзакции = (ОбработкаДляЗагрузкиДанных.КоличествоОбъектовНаТранзакцию <> 1);
// Получаем инициализированную обработку для выгрузки данных.
ОбработкаОбменаДаннымиXML = СтруктураНастроекОбмена.ОбработкаОбменаДанными;
ОбработкаОбменаДаннымиXML.ИмяФайлаОбмена = "";
Если Не ЭтоПланОбменаXDTO Тогда
ОбработкаОбменаДаннымиXML.ВнешнееСоединение = ВнешнееСоединение;
ОбработкаОбменаДаннымиXML.ЗагрузкаДанныхВыполняетсяВоВнешнемСоединении = Истина;
КонецЕсли;
// ВЫГРУЗКА (ЭТА БАЗА) - ЗАГРУЗКА (КОРРЕСПОНДЕНТ)
ОбработкаОбменаДаннымиXML.ВыполнитьВыгрузкуДанных(ОбработкаДляЗагрузкиДанных);
// Фиксируем состояние выполнения обмена данными.
СтруктураНастроекОбмена.РезультатВыполненияОбмена = ОбработкаОбменаДаннымиXML.РезультатВыполненияОбмена();
СтруктураНастроекОбмена.КоличествоОбъектовОбработано = ОбработкаОбменаДаннымиXML.СчетчикВыгруженныхОбъектов();
СтруктураНастроекОбменаВнешнееСоединение.РезультатВыполненияОбменаСтрокой = ОбработкаДляЗагрузкиДанных.РезультатВыполненияОбменаСтрокой();
СтруктураНастроекОбменаВнешнееСоединение.КоличествоОбъектовОбработано = ОбработкаДляЗагрузкиДанных.СчетчикЗагруженныхОбъектов();
СтруктураНастроекОбмена.СообщениеПриОбмене = ОбработкаОбменаДаннымиXML.КомментарийПриВыгрузкеДанных;
СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке = ОбработкаОбменаДаннымиXML.СтрокаСообщенияОбОшибке();
СтруктураНастроекОбменаВнешнееСоединение.СообщениеПриОбмене = ОбработкаДляЗагрузкиДанных.КомментарийПриЗагрузкеДанных;
СтруктураНастроекОбменаВнешнееСоединение.СтрокаСообщенияОбОшибке = ОбработкаДляЗагрузкиДанных.СтрокаСообщенияОбОшибке();
ОбработкаДляЗагрузкиДанных = Неопределено;
КонецЕсли;
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбменаВнешнееСоединение);
Если Не РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена) Тогда
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьОбменДаннымиЧерезФайловыйРесурс(СтруктураНастроекОбмена, Знач ТолькоПараметры = Ложь)
Если СтруктураНастроекОбмена.ПроизводитьЗагрузкуДанных Тогда
Если СтруктураНастроекОбмена.ВидТранспортаОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.ВнешняяСистема Тогда
ВыполнитьОбменДаннымиСВнешнейСистемойЗагрузкаДанных(СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
// {Обработчик: ПередЧтениемСообщенияОбмена} Начало
СообщениеОбмена = "";
СтандартнаяОбработка = Истина;
ПередЧтениемСообщенияОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы, СообщениеОбмена, СтандартнаяОбработка);
// {Обработчик: ПередЧтениемСообщенияОбмена} Окончание
Если СтандартнаяОбработка Тогда
ВыполнитьТранспортСообщенияОбменаПередОбработкой(СтруктураНастроекОбмена);
Если СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено Тогда
ВыполнитьТранспортСообщенияОбменаПолучение(СтруктураНастроекОбмена);
Если СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено Тогда
СообщениеОбмена = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена.ИмяФайлаСообщенияОбмена();
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Загрузка данных только при успешном получении сообщения обмена.
Если СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено Тогда
ЕстьПоддержкаСопоставления = ЗначениеНастройкиПланаОбмена(
ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы),
"ПоддерживаетсяСопоставлениеДанных",
СохраненныйВариантНастройкиУзлаПланаОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы));
Если СтруктураНастроекОбмена.ДополнительныеПараметры.Свойство("СообщениеДляСопоставленияДанных")
И (ЕстьПоддержкаСопоставления
Или Не НастройкаСинхронизацииЗавершена(СтруктураНастроекОбмена.УзелИнформационнойБазы)) Тогда
ИмяФайлаДляПомещенияВХранилище = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(
КаталогВременногоХранилищаФайлов(),
УникальноеИмяФайлаСообщенияОбмена());
// Сохраняется новое сообщение для сопоставления данных.
ИдентификаторФайла = ПоместитьФайлВХранилище(ИмяФайлаДляПомещенияВХранилище);
ПереместитьФайл(СообщениеОбмена, ИмяФайлаДляПомещенияВХранилище);
ОбменДаннымиСлужебный.ПоместитьСообщениеДляСопоставленияДанных(
СтруктураНастроекОбмена.УзелИнформационнойБазы, ИдентификаторФайла);
СтандартнаяОбработка = Истина;
Иначе
ПрочитатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена, СообщениеОбмена, , ТолькоПараметры);
// {Обработчик: ПослеЧтенияСообщенияОбмена} Начало
СтандартнаяОбработка = Истина;
ПослеЧтенияСообщенияОбмена(
СтруктураНастроекОбмена.УзелИнформационнойБазы,
СообщениеОбмена,
РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена),
СтандартнаяОбработка,
Не ТолькоПараметры);
// {Обработчик: ПослеЧтенияСообщенияОбмена} Окончание
КонецЕсли;
КонецЕсли;
// {Обработчик: ПослеЧтенияСообщенияОбмена} Начало
СтандартнаяОбработка = Истина;
ПослеЧтенияСообщенияОбмена(
СтруктураНастроекОбмена.УзелИнформационнойБазы,
СообщениеОбмена,
РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена),
СтандартнаяОбработка,
Не ТолькоПараметры);
// {Обработчик: ПослеЧтенияСообщенияОбмена} Окончание
Если СтандартнаяОбработка Тогда
ВыполнитьТранспортСообщенияОбменаПослеОбработки(СтруктураНастроекОбмена);
КонецЕсли;
ИначеЕсли СтруктураНастроекОбмена.ПроизводитьВыгрузкуДанных Тогда
Если СтруктураНастроекОбмена.ВидТранспортаОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.ВнешняяСистема Тогда
ВыполнитьОбменДаннымиСВнешнейСистемойВыгрузкаНастроекXDTO(СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
ВыполнитьТранспортСообщенияОбменаПередОбработкой(СтруктураНастроекОбмена);
// выгрузка данных
Если СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено Тогда
ЗаписатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена, СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена.ИмяФайлаСообщенияОбмена());
КонецЕсли;
// Отправка сообщения обмена только в случае успешной выгрузки данных.
Если РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена) Тогда
ВыполнитьТранспортСообщенияОбменаОтправка(СтруктураНастроекОбмена);
КонецЕсли;
ВыполнитьТранспортСообщенияОбменаПослеОбработки(СтруктураНастроекОбмена);
КонецЕсли;
КонецПроцедуры
Процедура ПередЧтениемСообщенияОбмена(Знач Получатель, СообщениеОбмена, СтандартнаяОбработка)
Если ЭтоПодчиненныйУзелРИБ()
И ТипЗнч(ГлавныйУзел()) = ТипЗнч(Получатель) Тогда
СохраненноеСообщениеОбмена = СообщениеОбменаДаннымиИзГлавногоУзла();
Если ТипЗнч(СохраненноеСообщениеОбмена) = Тип("ДвоичныеДанные") Тогда
// Приведение к новому формату хранения и повторное зачитывание
// значения константы СообщениеОбменаДаннымиИзГлавногоУзла.
УстановитьСообщениеОбменаДаннымиИзГлавногоУзла(СохраненноеСообщениеОбмена, Получатель);
СохраненноеСообщениеОбмена = СообщениеОбменаДаннымиИзГлавногоУзла();
КонецЕсли;
Если ТипЗнч(СохраненноеСообщениеОбмена) = Тип("Структура") Тогда
СтандартнаяОбработка = Ложь;
СообщениеОбмена = СохраненноеСообщениеОбмена.ПутьКФайлу;
ЗаписатьСобытиеПолученияДанных(Получатель, НСтр("ru = 'Сообщение обмена получено из кэша.'"));
УстановитьПривилегированныйРежим(Истина);
УстановитьРежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском("СообщениеПолученоИзКэша", Истина);
УстановитьПривилегированныйРежим(Ложь);
Иначе
УстановитьПривилегированныйРежим(Истина);
УстановитьРежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском("СообщениеПолученоИзКэша", Ложь);
УстановитьПривилегированныйРежим(Ложь);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ПослеЧтенияСообщенияОбмена(Знач Получатель, Знач СообщениеОбмена, Знач СообщениеПрочитано, СтандартнаяОбработка, Знач УдалитьСообщение = Истина)
Если ЭтоПодчиненныйУзелРИБ()
И ТипЗнч(ГлавныйУзел()) = ТипЗнч(Получатель) Тогда
Если Не СообщениеПрочитано
И ОбменДаннымиСлужебный.РежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском("СообщениеПолученоИзКэша") Тогда
// Не удалось прочитать сообщение, полученное из кэша - требуется очистка кэша.
ОчиститьСообщениеОбменаДаннымиИзГлавногоУзла();
Возврат;
КонецЕсли;
ОбновитьСообщениеВКэше = Ложь;
Если КонфигурацияИзменена() Тогда
// Т.к. конфигурация может быть изменена повторно, требуется
// обновить кэш, если он содержит устаревшее сообщение,
// а не только при первой загрузке изменений конфигурации.
ОбновитьСообщениеВКэше = Истина;
Если Не СообщениеПрочитано Тогда
Если НЕ Константы.ЗагрузитьСообщениеОбменаДанными.Получить() Тогда
Константы.ЗагрузитьСообщениеОбменаДанными.Установить(Истина);
КонецЕсли;
КонецЕсли;
Иначе
Если УдалитьСообщение Тогда
ОчиститьСообщениеОбменаДаннымиИзГлавногоУзла();
Если Константы.ЗагрузитьСообщениеОбменаДанными.Получить() Тогда
Константы.ЗагрузитьСообщениеОбменаДанными.Установить(Ложь);
КонецЕсли;
Иначе
// Т.к. чтение сообщение обмена может быть без загрузки метаданных,
// то нужно сохранить сообщение обмена после чтения параметров работы программы,
// чтобы не загружать его повторно для основного чтения.
ОбновитьСообщениеВКэше = Истина;
КонецЕсли;
КонецЕсли;
Если ОбновитьСообщениеВКэше Тогда
СтароеСообщение = СообщениеОбменаДаннымиИзГлавногоУзла();
ОбновитьКэш = Ложь;
НовоеСообщение = Новый ДвоичныеДанные(СообщениеОбмена);
ТипСтруктура = ТипЗнч(СтароеСообщение) = Тип("Структура");
Если ТипСтруктура Или ТипЗнч(СтароеСообщение) = Тип("ДвоичныеДанные") Тогда
Если ТипСтруктура Тогда
СтароеСообщение = Новый ДвоичныеДанные(СтароеСообщение.ПутьКФайлу);
КонецЕсли;
Если СтароеСообщение.Размер() <> НовоеСообщение.Размер() Тогда
ОбновитьКэш = Истина;
ИначеЕсли НовоеСообщение <> СтароеСообщение Тогда
ОбновитьКэш = Истина;
КонецЕсли;
Иначе
ОбновитьКэш = Истина;
КонецЕсли;
Если ОбновитьКэш Тогда
УстановитьСообщениеОбменаДаннымиИзГлавногоУзла(НовоеСообщение, Получатель);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СообщениеПрочитано И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
РегистрыСведений.ОбработчикиСобытийСинхронизацииДанных.ВыполнитьОбработчики(Получатель, "ПослеПолученияДанных");
КонецЕсли;
КонецПроцедуры
// Записывает изменения узла информационной базы в файл во временном каталоге.
//
// Параметры:
// СтруктураНастроекОбмена - Структура - структура со всеми необходимыми данными и объектами для выполнения обмена.
//
Процедура ЗаписатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена, Знач ИмяФайлаСообщенияОбмена = "", СообщениеОбмена = "")
Если СтруктураНастроекОбмена.ЭтоОбменВРИБ Тогда // Обмен в РИБ
Отказ = Ложь;
СообщениеОбОшибке = "";
// Получаем обработку обмена данными.
ОбработкаОбменаДанными = СтруктураНастроекОбмена.ОбработкаОбменаДанными;
// Устанавливаем имя файла сообщения обмена, который необходимо прочитать.
ОбработкаОбменаДанными.УстановитьИмяФайлаСообщенияОбмена(ИмяФайлаСообщенияОбмена);
ОбработкаОбменаДанными.ВыполнитьВыгрузкуДанных(Отказ, СообщениеОбОшибке);
Если Отказ Тогда
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке = СообщениеОбОшибке;
КонецЕсли;
Иначе
// {Обработчик: ПриВыгрузкеДанных} Начало. Переопределение стандартной обработки выгрузки данных.
СтандартнаяОбработка = Истина;
КоличествоОбъектовОбработано = 0;
Попытка
ПараметрыВыполнения = Новый Структура;
ПараметрыВыполнения.Вставить("УзелИнформационнойБазы", СтруктураНастроекОбмена.УзелИнформационнойБазы);
ПараметрыВыполнения.Вставить("КоличествоЭлементовВТранзакции", СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции);
ПараметрыВыполнения.Вставить("КлючСообщенияЖурналаРегистрации", СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации);
ПараметрыВыполнения.Вставить("ИмяФайлаСообщенияОбмена", ИмяФайлаСообщенияОбмена);
Обработчики = Новый Массив;
Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.ОбменСообщениями") Тогда
МодульОбменСообщениямиВнутренний = ОбщегоНазначения.ОбщийМодуль("ОбменСообщениямиВнутренний");
Обработчики.Добавить(МодульОбменСообщениямиВнутренний);
КонецЕсли;
Обработчики.Добавить(ОбменДаннымиПереопределяемый);
ОбработчикПриВыгрузкеДанныхБСП(
Обработчики,
ПараметрыВыполнения,
СтандартнаяОбработка,
СообщениеОбмена,
КоличествоОбъектовОбработано);
Исключение
СтрокаСообщенияОбОшибке = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Ошибка,
СтруктураНастроекОбмена.УзелИнформационнойБазы.Метаданные(),
СтруктураНастроекОбмена.УзелИнформационнойБазы, СтрокаСообщенияОбОшибке);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке = СтрокаСообщенияОбОшибке;
Возврат;
КонецПопытки;
Если СтандартнаяОбработка = Ложь Тогда
СтруктураНастроекОбмена.КоличествоОбъектовОбработано = КоличествоОбъектовОбработано;
Возврат;
КонецЕсли;
// {Обработчик: ПриВыгрузкеДанных} Окончание
// Универсальный обмен (обмен по правилам конвертации).
Если СтруктураНастроекОбмена.ОбменПоПравиламКонвертацииОбъектов Тогда
ФормироватьСообщениеОбмена = ПустаяСтрока(ИмяФайлаСообщенияОбмена);
Если ФормироватьСообщениеОбмена Тогда
ИмяФайлаСообщенияОбмена = ПолучитьИмяВременногоФайла(".xml");
КонецЕсли;
// Получаем инициализированную обработку обмена данными.
ОбработкаОбменаДаннымиXML = СтруктураНастроекОбмена.ОбработкаОбменаДанными;
ОбработкаОбменаДаннымиXML.ИмяФайлаОбмена = ИмяФайлаСообщенияОбмена;
// выгрузка данных
Попытка
ОбработкаОбменаДаннымиXML.ВыполнитьВыгрузкуДанных();
Исключение
СтрокаСообщенияОбОшибке = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Ошибка,
СтруктураНастроекОбмена.УзелИнформационнойБазы.Метаданные(),
СтруктураНастроекОбмена.УзелИнформационнойБазы, СтрокаСообщенияОбОшибке);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке = СтрокаСообщенияОбОшибке;
Возврат;
КонецПопытки;
Если ФормироватьСообщениеОбмена Тогда
ТекстовыйФайл = Новый ТекстовыйДокумент;
ТекстовыйФайл.Прочитать(ИмяФайлаСообщенияОбмена, КодировкаТекста.UTF8);
СообщениеОбмена = ТекстовыйФайл.ПолучитьТекст();
УдалитьФайлы(ИмяФайлаСообщенияОбмена);
КонецЕсли;
СтруктураНастроекОбмена.РезультатВыполненияОбмена = ОбработкаОбменаДаннымиXML.РезультатВыполненияОбмена();
// Фиксируем состояние выполнения обмена данными.
СтруктураНастроекОбмена.КоличествоОбъектовОбработано = ОбработкаОбменаДаннымиXML.СчетчикВыгруженныхОбъектов();
СтруктураНастроекОбмена.СообщениеПриОбмене = ОбработкаОбменаДаннымиXML.КомментарийПриВыгрузкеДанных;
СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке = ОбработкаОбменаДаннымиXML.СтрокаСообщенияОбОшибке();
Иначе // Стандартный обмен (платформенная сериализация).
Отказ = Ложь;
КоличествоОбъектовОбработано = 0;
Попытка
ВыполнитьСтандартнуюВыгрузкуИзмененийДляУзла(Отказ,
СтруктураНастроекОбмена.УзелИнформационнойБазы,
ИмяФайлаСообщенияОбмена,
СообщениеОбмена,
СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции,
СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации,
КоличествоОбъектовОбработано);
Исключение
СтрокаСообщенияОбОшибке = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Ошибка,
СтруктураНастроекОбмена.УзелИнформационнойБазы.Метаданные(),
СтруктураНастроекОбмена.УзелИнформационнойБазы, СтрокаСообщенияОбОшибке);
СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке = СтрокаСообщенияОбОшибке;
Отказ = Истина;
КонецПопытки;
СтруктураНастроекОбмена.КоличествоОбъектовОбработано = КоличествоОбъектовОбработано;
Если Отказ Тогда
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Получает сообщение обмена с новыми данными и загружает данные в информационную базу.
//
// Параметры:
// СтруктураНастроекОбмена - Структура - структура со всеми необходимыми данными и объектами для выполнения обмена.
//
Процедура ПрочитатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена,
Знач ИмяФайлаСообщенияОбмена = "", СообщениеОбмена = "", Знач ТолькоПараметры = Ложь)
Если СтруктураНастроекОбмена.ЭтоОбменВРИБ Тогда // Обмен в РИБ
Отказ = Ложь;
// Получаем обработку обмена данными.
ОбработкаОбменаДанными = СтруктураНастроекОбмена.ОбработкаОбменаДанными;
// Устанавливаем имя файла сообщения обмена, который необходимо прочитать.
ОбработкаОбменаДанными.УстановитьИмяФайлаСообщенияОбмена(ИмяФайлаСообщенияОбмена);
СообщениеОбОшибке = "";
ОбработкаОбменаДанными.ВыполнитьЗагрузкуДанных(Отказ, ТолькоПараметры, СообщениеОбОшибке);
Если Отказ Тогда
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке = СообщениеОбОшибке;
КонецЕсли;
Иначе
// {Обработчик: ПриЗагрузкеДанных} Начало. Переопределение стандартной обработки загрузки данных.
СтандартнаяОбработка = Истина;
КоличествоОбъектовОбработано = 0;
Попытка
ПараметрыВыполнения = Новый Структура;
ПараметрыВыполнения.Вставить("УзелИнформационнойБазы", СтруктураНастроекОбмена.УзелИнформационнойБазы);
ПараметрыВыполнения.Вставить("КоличествоЭлементовВТранзакции", СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции);
ПараметрыВыполнения.Вставить("КлючСообщенияЖурналаРегистрации", СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации);
ПараметрыВыполнения.Вставить("ИмяФайлаСообщенияОбмена", ИмяФайлаСообщенияОбмена);
Обработчики = Новый Массив;
Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.ОбменСообщениями") Тогда
МодульОбменСообщениямиВнутренний = ОбщегоНазначения.ОбщийМодуль("ОбменСообщениямиВнутренний");
Обработчики.Добавить(МодульОбменСообщениямиВнутренний);
КонецЕсли;
Обработчики.Добавить(ОбменДаннымиПереопределяемый);
ОбработчикПриЗагрузкеДанныхБСП(
Обработчики,
ПараметрыВыполнения,
СтандартнаяОбработка,
СообщениеОбмена,
КоличествоОбъектовОбработано);
Исключение
СтрокаСообщенияОбОшибке = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Ошибка,
СтруктураНастроекОбмена.УзелИнформационнойБазы.Метаданные(),
СтруктураНастроекОбмена.УзелИнформационнойБазы, СтрокаСообщенияОбОшибке);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке = СтрокаСообщенияОбОшибке;
Возврат;
КонецПопытки;
Если СтандартнаяОбработка = Ложь Тогда
СтруктураНастроекОбмена.КоличествоОбъектовОбработано = КоличествоОбъектовОбработано;
Возврат;
КонецЕсли;
// {Обработчик: ПриЗагрузкеДанных} Окончание
// Универсальный обмен (обмен по правилам конвертации).
Если СтруктураНастроекОбмена.ОбменПоПравиламКонвертацииОбъектов Тогда
// Получаем инициализированную обработку обмена данными.
ОбработкаОбменаДаннымиXML = СтруктураНастроекОбмена.ОбработкаОбменаДанными;
ОбработкаОбменаДаннымиXML.ИмяФайлаОбмена = ИмяФайлаСообщенияОбмена;
// загрузка данных
Если ОбменДаннымиПовтИсп.ЭтоПланОбменаXDTO(СтруктураНастроекОбмена.ИмяПланаОбмена) Тогда
ПараметрыЗагрузки = Новый Структура;
ПараметрыЗагрузки.Вставить("ОбменДаннымиСВнешнейСистемой",
СтруктураНастроекОбмена.ВидТранспортаОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.ВнешняяСистема);
ОбработкаОбменаДаннымиXML.ВыполнитьЗагрузкуДанных(ПараметрыЗагрузки);
ПолученыДанныеДляСопоставления = Ложь;
Если Не ОбработкаОбменаДаннымиXML.КомпонентыОбмена.ФлагОшибки Тогда
ПолученыДанныеДляСопоставления = (ОбработкаОбменаДаннымиXML.КомпонентыОбмена.НомерВходящегоСообщения > 0
И ОбработкаОбменаДаннымиXML.КомпонентыОбмена.НомерСообщенияПолученногоКорреспондентом = 0);
КонецЕсли;
СтруктураНастроекОбмена.ДополнительныеПараметры.Вставить("ПолученыДанныеДляСопоставления", ПолученыДанныеДляСопоставления);
Иначе
ОбработкаОбменаДаннымиXML.ВыполнитьЗагрузкуДанных();
КонецЕсли;
СтруктураНастроекОбмена.РезультатВыполненияОбмена = ОбработкаОбменаДаннымиXML.РезультатВыполненияОбмена();
// Фиксируем состояние выполнения обмена данными.
СтруктураНастроекОбмена.КоличествоОбъектовОбработано = ОбработкаОбменаДаннымиXML.СчетчикЗагруженныхОбъектов();
СтруктураНастроекОбмена.СообщениеПриОбмене = ОбработкаОбменаДаннымиXML.КомментарийПриЗагрузкеДанных;
СтруктураНастроекОбмена.СтрокаСообщенияОбОшибке = ОбработкаОбменаДаннымиXML.СтрокаСообщенияОбОшибке();
Иначе // Стандартный обмен (платформенная сериализация).
КоличествоОбъектовОбработано = 0;
РезультатВыполненияОбмена = Неопределено;
ВыполнитьСтандартнуюЗагрузкуИзмененийДляУзла(
СтруктураНастроекОбмена.УзелИнформационнойБазы,
ИмяФайлаСообщенияОбмена,
СообщениеОбмена,
СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции,
СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации,
КоличествоОбъектовОбработано,
РезультатВыполненияОбмена);
СтруктураНастроекОбмена.КоличествоОбъектовОбработано = КоличествоОбъектовОбработано;
СтруктураНастроекОбмена.РезультатВыполненияОбмена = РезультатВыполненияОбмена;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьОбменДаннымиСВнешнейСистемойЗагрузкаДанных(СтруктураНастроекОбмена)
ИмяВременногоКаталога = СоздатьВременныйКаталогСообщенийОбмена();
ИмяФайлаСообщения = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(
ИмяВременногоКаталога, УникальноеИмяФайлаСообщенияОбмена());
ОбработкаТранспортаСообщенийОбмена = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена;
СообщениеПолучено = Ложь;
Попытка
СообщениеПолучено = ОбработкаТранспортаСообщенийОбмена.ПолучитьСообщение(ИмяФайлаСообщения);
Исключение
Информация = ИнформацияОбОшибке();
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения;
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(Информация), СтруктураНастроекОбмена, Истина);
КонецПопытки;
СообщениеОбработано = Ложь;
ВыполнитьОбработчикПослеЗагрузки = Ложь;
Если СообщениеПолучено
И СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено Тогда
ВыполнитьОбработчикПослеЗагрузки = Истина;
ПрочитатьСообщениеСИзменениямиДляУзла(СтруктураНастроекОбмена, ИмяФайлаСообщения);
СообщениеОбработано = РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена);
КонецЕсли;
Попытка
УдалитьФайлы(ИмяВременногоКаталога);
Исключение
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(Информация), СтруктураНастроекОбмена);
КонецПопытки;
НастройкаЗавершена = НастройкаСинхронизацииЗавершена(СтруктураНастроекОбмена.УзелИнформационнойБазы);
Если ВыполнитьОбработчикПослеЗагрузки Тогда
ЕстьСледующееСообщение = Ложь;
Попытка
ОбработкаТранспортаСообщенийОбмена.ПослеОбработкиПолученногоСообщения(СообщениеОбработано, ЕстьСледующееСообщение);
Исключение
Информация = ИнформацияОбОшибке();
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения;
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(Информация), СтруктураНастроекОбмена, Истина);
ЕстьСледующееСообщение = Ложь;
КонецПопытки;
Если СообщениеОбработано
И Не НастройкаЗавершена Тогда
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы);
Если ЕстьАлгоритмМенеджераПланаОбмена("ПередНастройкойСинхронизацииДанных", ИмяПланаОбмена) Тогда
Контекст = Новый Структура;
Контекст.Вставить("Корреспондент", СтруктураНастроекОбмена.УзелИнформационнойБазы);
Контекст.Вставить("ИдентификаторНастройки", СохраненныйВариантНастройкиУзлаПланаОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы));
Контекст.Вставить("НачальнаяНастройка", Не НастройкаЗавершена);
ИмяФормыПомощника = "";
ПланыОбмена[ИмяПланаОбмена].ПередНастройкойСинхронизацииДанных(Контекст, НастройкаЗавершена, ИмяФормыПомощника);
Если НастройкаЗавершена Тогда
ЗавершитьНастройкуСинхронизацииДанных(СтруктураНастроекОбмена.УзелИнформационнойБазы);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЕстьСледующееСообщение И НастройкаЗавершена Тогда
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено;
ВыполнитьОбменДаннымиСВнешнейСистемойЗагрузкаДанных(СтруктураНастроекОбмена);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьОбменДаннымиСВнешнейСистемойВыгрузкаНастроекXDTO(СтруктураНастроекОбмена)
ОбработкаТранспортаСообщенийОбмена = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена;
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы);
НастройкиXDTO = Новый Структура;
НастройкиXDTO.Вставить("ФорматОбмена",
ЗначениеНастройкиПланаОбмена(ИмяПланаОбмена, "ФорматОбмена"));
НастройкиXDTO.Вставить("ПоддерживаемыеВерсии",
ОбменДаннымиXDTOСервер.ВерсииФорматаОбменаМассив(СтруктураНастроекОбмена.УзелИнформационнойБазы));
НастройкиXDTO.Вставить("ПоддерживаемыеОбъекты",
ОбменДаннымиXDTOСервер.ПоддерживаемыеОбъектыФормата(ИмяПланаОбмена, , СтруктураНастроекОбмена.УзелИнформационнойБазы));
Попытка
ОбработкаТранспортаСообщенийОбмена.ОтправитьНастройкиXDTO(НастройкиXDTO);
Исключение
Информация = ИнформацияОбОшибке();
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения;
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(Информация), СтруктураНастроекОбмена, Истина);
КонецПопытки;
КонецПроцедуры
#КонецОбласти
#Область ВыполнениеОбменаМетодамиСериализации
// Процедура записи изменений для сообщения обмена.
// Применима для случаев когда структура метаданных обменивающихся баз одинакова для всех объектов участвующих в обмене.
//
Процедура ВыполнитьСтандартнуюВыгрузкуИзмененийДляУзла(Отказ,
УзелИнформационнойБазы,
ИмяФайла,
СообщениеОбмена,
КоличествоЭлементовВТранзакции = 0,
КлючСообщенияЖурналаРегистрации = "",
КоличествоОбъектовОбработано = 0)
ЗаписьXML = Новый ЗаписьXML;
Если Не ПустаяСтрока(ИмяФайла) Тогда
ЗаписьXML.ОткрытьФайл(ИмяФайла);
Иначе
ЗаписьXML.УстановитьСтроку();
КонецЕсли;
ЗаписьXML.ЗаписатьОбъявлениеXML();
// Создаем новое сообщение.
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
ЗаписьСообщения.НачатьЗапись(ЗаписьXML, УзелИнформационнойБазы);
ОбменДаннымиСлужебный.ПроверитьКэшМеханизмаРегистрацииОбъектов();
ТаблицаПредопределенных = ОбменДаннымиСлужебный.ТаблицаПредопределенныхДанных();
ТаблицаПредопределенных.Колонки.Добавить("Выгружать", Новый ОписаниеТипов("Булево"));
ТаблицаПредопределенных.Индексы.Добавить("Ссылка");
// Получаем выборку измененных данных.
ВыборкаИзменений = ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения);
Если ПустаяСтрока(КлючСообщенияЖурналаРегистрации) Тогда
КлючСообщенияЖурналаРегистрации = СобытиеЖурналаРегистрацииОбменДанными();
КонецЕсли;
ПолучательОбъект = УзелИнформационнойБазы.ПолучитьОбъект();
ПараметрыВыгрузки = Новый Структура;
ПараметрыВыгрузки.Вставить("ЗаписьXML", ЗаписьXML);
ПараметрыВыгрузки.Вставить("Получатель", ПолучательОбъект);
ПараметрыВыгрузки.Вставить("НачальнаяВыгрузкаДанных", УстановленПризнакНачальнойВыгрузкиДанных(УзелИнформационнойБазы));
ПараметрыВыгрузки.Вставить("КоличествоЭлементовВТранзакции", КоличествоЭлементовВТранзакции);
ПараметрыВыгрузки.Вставить("КоличествоОбъектовОбработано", КоличествоОбъектовОбработано);
ПараметрыВыгрузки.Вставить("ТаблицаПредопределенных", ТаблицаПредопределенных);
ИспользоватьТранзакции = КоличествоЭлементовВТранзакции <> 1;
ПродолжитьВыгрузку = Истина;
Если ИспользоватьТранзакции Тогда
Пока ПродолжитьВыгрузку Цикл
НачатьТранзакцию();
Попытка
ВыполнитьСтандартнуюВыгрузкуПорцииДанных(ВыборкаИзменений, ПараметрыВыгрузки, ПродолжитьВыгрузку);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Ошибка,
УзелИнформационнойБазы.Метаданные(), УзелИнформационнойБазы, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
Отказ = Истина;
Прервать;
КонецПопытки;
КонецЦикла;
Иначе
Попытка
Пока ПродолжитьВыгрузку Цикл
ВыполнитьСтандартнуюВыгрузкуПорцииДанных(ВыборкаИзменений, ПараметрыВыгрузки, ПродолжитьВыгрузку);
КонецЦикла;
Исключение
ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Ошибка,
УзелИнформационнойБазы.Метаданные(), УзелИнформационнойБазы, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
Отказ = Истина;
КонецПопытки;
КонецЕсли;
Если Отказ Тогда
ЗаписьСообщения.ПрерватьЗапись();
ЗаписьXML.Закрыть();
Возврат;
КонецЕсли;
ВыгрузитьТаблицуПредопределенных(ПараметрыВыгрузки);
ЗаписьСообщения.ЗакончитьЗапись();
СообщениеОбмена = ЗаписьXML.Закрыть();
КоличествоОбъектовОбработано = ПараметрыВыгрузки.КоличествоОбъектовОбработано;
КонецПроцедуры
Процедура ВыполнитьСтандартнуюВыгрузкуПорцииДанных(ВыборкаИзменений, ПараметрыВыгрузки, ПродолжитьВыгрузку)
КоличествоЗаписанных = 0;
Пока (ПараметрыВыгрузки.КоличествоЭлементовВТранзакции = 0
Или КоличествоЗаписанных <= ПараметрыВыгрузки.КоличествоЭлементовВТранзакции)
И ВыборкаИзменений.Следующий() Цикл
Данные = ВыборкаИзменений.Получить();
// Выполняем проверку на то, что объект проходит фильтр ПРО
// если объект фильтр ПРО не проходит, то в базу-приемник отсылаем удаление объекта
// для наборов записей выполняем фильтрацию каждой записи
// наборы выгружаем всегда, даже пустые (аналог удаления объекта).
ОтправкаЭлемента = ОтправкаЭлементаДанных.Авто;
СтандартныеПодсистемыСервер.ПриОтправкеДанныхПодчиненному(Данные, ОтправкаЭлемента, ПараметрыВыгрузки.НачальнаяВыгрузкаДанных, ПараметрыВыгрузки.Получатель);
Если ОтправкаЭлемента = ОтправкаЭлементаДанных.Удалить Тогда
Если ОбщегоНазначения.ЭтоРегистр(Данные.Метаданные()) Тогда
// Удаление регистра отсылаем в виде пустого набора записей.
Иначе
Данные = Новый УдалениеОбъекта(Данные.Ссылка);
КонецЕсли;
ИначеЕсли ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать Тогда
Продолжить;
КонецЕсли;
// Записываем данные в сообщение.
ЗаписатьXML(ПараметрыВыгрузки.ЗаписьXML, Данные);
КоличествоЗаписанных = КоличествоЗаписанных + 1;
ОбменДаннымиСлужебный.ОтметитьСсылкиНаПредопределенныеДанные(Данные, ПараметрыВыгрузки.ТаблицаПредопределенных);
КонецЦикла;
ПродолжитьВыгрузку = (КоличествоЗаписанных > 0);
ПараметрыВыгрузки.КоличествоОбъектовОбработано = ПараметрыВыгрузки.КоличествоОбъектовОбработано + КоличествоЗаписанных;
КонецПроцедуры
Процедура ВыгрузитьТаблицуПредопределенных(ПараметрыВыгрузки)
ПараметрыВыгрузки.ТаблицаПредопределенных.Сортировать("ИмяТаблицы");
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьНачалоЭлемента("PredefinedData");
КоличествоВыгружено = 0;
Для Каждого СтрокаПредопределенных Из ПараметрыВыгрузки.ТаблицаПредопределенных Цикл
Если Не СтрокаПредопределенных.Выгружать Тогда
Продолжить;
КонецЕсли;
ЗаписьXML.ЗаписатьНачалоЭлемента(СтрокаПредопределенных.ИмяТипаXML);
ЗаписьXML.ЗаписатьАтрибут("PredefinedDataName", СтрокаПредопределенных.ИмяПредопределенныхДанных);
ЗаписьXML.ЗаписатьТекст(XMLСтрока(СтрокаПредопределенных.Ссылка));
ЗаписьXML.ЗаписатьКонецЭлемента();
КоличествоВыгружено = КоличествоВыгружено + 1;
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента(); // PredefinedData
КомментарийПредопределенные = ЗаписьXML.Закрыть();
Если КоличествоВыгружено > 0 Тогда
ПараметрыВыгрузки.ЗаписьXML.ЗаписатьКомментарий(КомментарийПредопределенные);
КонецЕсли;
КонецПроцедуры
// Процедура чтения изменений из сообщения обмена.
// Применима для случаев когда структура метаданных обменивающихся баз одинакова для всех объектов участвующих в обмене.
//
Процедура ВыполнитьСтандартнуюЗагрузкуИзмененийДляУзла(
УзелИнформационнойБазы,
ИмяФайла,
СообщениеОбмена,
КоличествоЭлементовВТранзакции,
КлючСообщенияЖурналаРегистрации,
КоличествоОбъектовОбработано,
РезультатВыполненияОбмена)
Если ПустаяСтрока(КлючСообщенияЖурналаРегистрации) Тогда
КлючСообщенияЖурналаРегистрации = СобытиеЖурналаРегистрацииОбменДанными();
КонецЕсли;
ПараметрыЗагрузки = Новый Структура;
ПараметрыЗагрузки.Вставить("УзелИнформационнойБазы", УзелИнформационнойБазы);
ПараметрыЗагрузки.Вставить("СообщениеОбмена", СообщениеОбмена);
ПараметрыЗагрузки.Вставить("ИмяФайла", ИмяФайла);
ПараметрыЗагрузки.Вставить("ЧтениеXML", Неопределено);
ПараметрыЗагрузки.Вставить("ЧтениеСообщения", Неопределено);
ПараметрыЗагрузки.Вставить("КоличествоЭлементовВТранзакции", КоличествоЭлементовВТранзакции);
ПараметрыЗагрузки.Вставить("КоличествоОбъектовОбработано", 0);
ТаблицаПредопределенных = ОбменДаннымиСлужебный.ТаблицаПредопределенныхДанных();
ТаблицаПредопределенных.Колонки.Добавить("ИсходнаяСсылка");
ТаблицаПредопределенных.Колонки.Добавить("ИсходнаяСсылкаЗаполнена", Новый ОписаниеТипов("Булево"));
ПараметрыЗагрузки.Вставить("ТаблицаПредопределенных", ТаблицаПредопределенных);
СообщениеОбОшибке = "";
ЗаполнитьИсходныеСсылкиВТаблицеПредопределенныхДанных(ПараметрыЗагрузки, СообщениеОбОшибке);
ПараметрыЗагрузки.ТаблицаПредопределенных = ТаблицаПредопределенных.Скопировать(Новый Структура("ИсходнаяСсылкаЗаполнена", Истина));
ПараметрыЗагрузки.ТаблицаПредопределенных.Индексы.Добавить("ИсходнаяСсылка");
ТаблицаПредопределенных = Неопределено;
Если Не ПустаяСтрока(СообщениеОбОшибке) Тогда
ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Предупреждение,
УзелИнформационнойБазы.Метаданные(), УзелИнформационнойБазы, СообщениеОбОшибке);
КонецЕсли;
ИнициализироватьЧтениеСообщенияДляСтандартнойЗагрузки(ПараметрыЗагрузки, РезультатВыполненияОбмена, СообщениеОбОшибке);
Если РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка Тогда
ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Ошибка,
УзелИнформационнойБазы.Метаданные(), УзелИнформационнойБазы, СообщениеОбОшибке);
Возврат;
ИначеЕсли РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято Тогда
ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Предупреждение,
УзелИнформационнойБазы.Метаданные(), УзелИнформационнойБазы, СообщениеОбОшибке);
Возврат;
КонецЕсли;
ЧтениеXML = ПараметрыЗагрузки.ЧтениеXML;
ЧтениеСообщения = ПараметрыЗагрузки.ЧтениеСообщения;
ПараметрыРезервнойКопии = ПараметрыРезервнойКопии(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
// Удаление регистрации изменений для узла отправителя сообщения.
Если Не ПараметрыРезервнойКопии.ВосстановленаРезервнаяКопия Тогда
ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.СнятьПризнакНачальнойВыгрузкиДанных(
ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
КонецЕсли;
ИспользоватьТранзакции = КоличествоЭлементовВТранзакции <> 1;
ПродолжитьЗагрузку = Истина;
Если ИспользоватьТранзакции Тогда
Пока ПродолжитьЗагрузку Цикл
ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Истина);
НачатьТранзакцию();
Попытка
ВыполнитьСтандартнуюЗагрузкуПорцииДанных(ПараметрыЗагрузки, ПродолжитьЗагрузку);
ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь, Ложь);
РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Ошибка,
УзелИнформационнойБазы.Метаданные(), УзелИнформационнойБазы, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
Прервать;
КонецПопытки;
КонецЦикла;
Иначе
ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Истина);
Попытка
Пока ПродолжитьЗагрузку Цикл
ВыполнитьСтандартнуюЗагрузкуПорцииДанных(ПараметрыЗагрузки, ПродолжитьЗагрузку);
КонецЦикла;
ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь);
Исключение
ОбменДаннымиСлужебный.ОтключитьОбновлениеКлючейДоступа(Ложь);
РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Ошибка,
УзелИнформационнойБазы.Метаданные(), УзелИнформационнойБазы, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЕсли;
Если РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка Тогда
ЧтениеСообщения.ПрерватьЧтение();
Иначе
// Пропуск всех не стандартных элементов в теле сообщения.
ТекущееИмяУзла = "";
Пока ЧтениеСообщения.ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента
Или (ЧтениеСообщения.ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента
И ЧтениеСообщения.ЧтениеXML.Имя = ТекущееИмяУзла) Цикл
ТекущееИмяУзла = ЧтениеСообщения.ЧтениеXML.Имя;
ЧтениеСообщения.ЧтениеXML.Пропустить();
КонецЦикла;
Попытка
ЧтениеСообщения.ЗакончитьЧтение();
ПриВосстановленииРезервнойКопии(ПараметрыРезервнойКопии);
Исключение
РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Ошибка,
УзелИнформационнойБазы.Метаданные(), УзелИнформационнойБазы, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЕсли;
ЧтениеXML.Закрыть();
КоличествоОбъектовОбработано = ПараметрыЗагрузки.КоличествоОбъектовОбработано;
КонецПроцедуры
Процедура ЗаполнитьИсходныеСсылкиВТаблицеПредопределенныхДанных(ПараметрыЗагрузки, СообщениеОбОшибке)
ЧтениеXML = Новый ЧтениеXML;
ПараметрыЧтения = Новый ПараметрыЧтенияXML(, , , , , , , Ложь); // чтение с учетом комментариев
Попытка
Если Не ПустаяСтрока(ПараметрыЗагрузки.СообщениеОбмена) Тогда
ЧтениеXML.УстановитьСтроку(ПараметрыЗагрузки.СообщениеОбмена, ПараметрыЧтения);
Иначе
ЧтениеXML.ОткрытьФайл(ПараметрыЗагрузки.ИмяФайла, ПараметрыЧтения);
КонецЕсли;
ЭтоBody = Ложь;
Пока ЧтениеXML.Прочитать() Цикл
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
Если ЧтениеXML.ЛокальноеИмя = "Message" Тогда
Продолжить;
ИначеЕсли ЧтениеXML.ЛокальноеИмя = "Header" Тогда
ЧтениеXML.Пропустить();
ИначеЕсли ЧтениеXML.ЛокальноеИмя = "Body" Тогда
ЭтоBody = Истина;
Продолжить;
ИначеЕсли ЭтоBody И ВозможностьЧтенияXML(ЧтениеXML) Тогда
ЧтениеXML.Пропустить();
ИначеЕсли ЭтоBody И ЧтениеXML.ЛокальноеИмя = "PredefinedData" Тогда
ОбработатьСекциюПредопределенныхДанныхВСообщенииОбмена(
ЧтениеXML, ПараметрыЗагрузки.ТаблицаПредопределенных);
КонецЕсли;
ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
Если ЧтениеXML.ЛокальноеИмя = "Message" Тогда
Прервать;
ИначеЕсли ЧтениеXML.ЛокальноеИмя = "Header" Тогда
Продолжить;
ИначеЕсли ЧтениеXML.ЛокальноеИмя = "Body" Тогда
Прервать;
КонецЕсли;
ИначеЕсли ЭтоBody И ЧтениеXML.ТипУзла = ТипУзлаXML.Комментарий Тогда
ЧтениеXMLКомментарий = Новый ЧтениеXML;
ЧтениеXMLКомментарий.УстановитьСтроку(ЧтениеXML.Значение);
ЧтениеXMLКомментарий.Прочитать(); // PredefinedData - НачалоЭлемента
ОбработатьСекциюПредопределенныхДанныхВСообщенииОбмена(
ЧтениеXMLКомментарий, ПараметрыЗагрузки.ТаблицаПредопределенных);
ЧтениеXMLКомментарий.Закрыть();
КонецЕсли;
КонецЦикла;
Исключение
СообщениеОбОшибке = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
ЧтениеXML.Закрыть();
КонецПроцедуры
Процедура ИнициализироватьЧтениеСообщенияДляСтандартнойЗагрузки(ПараметрыЗагрузки, РезультатВыполненияОбмена, СообщениеОбОшибке)
ЧтениеXML = Новый ЧтениеXML;
Попытка
Если Не ПустаяСтрока(ПараметрыЗагрузки.СообщениеОбмена) Тогда
ЧтениеXML.УстановитьСтроку(ПараметрыЗагрузки.СообщениеОбмена);
Иначе
ЧтениеXML.ОткрытьФайл(ПараметрыЗагрузки.ИмяФайла);
КонецЕсли;
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
ЧтениеСообщения.НачатьЧтение(ЧтениеXML, ДопустимыйНомерСообщения.Больший);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
КраткаяИнформация = КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
ПодробнаяИнформация = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
Если ЭтоОшибкаНомерСообщенияМеньшеИлиРавенНомеруРанееПринятогоСообщения(КраткаяИнформация) Тогда
РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято;
СообщениеОбОшибке = КраткаяИнформация;
Иначе
РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
СообщениеОбОшибке = ПодробнаяИнформация;
КонецЕсли;
Возврат;
КонецПопытки;
Если ЧтениеСообщения.Отправитель <> ПараметрыЗагрузки.УзелИнформационнойБазы Тогда
// Сообщение предназначено не для этого узла.
РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка;
СообщениеОбОшибке = НСтр("ru = 'Сообщение обмена содержит данные для другого узла информационной базы.'",
ОбщегоНазначения.КодОсновногоЯзыка());
Возврат;
КонецЕсли;
ПараметрыЗагрузки.ЧтениеXML = ЧтениеXML;
ПараметрыЗагрузки.ЧтениеСообщения = ЧтениеСообщения;
КонецПроцедуры
Процедура ВыполнитьСтандартнуюЗагрузкуПорцииДанных(ПараметрыЗагрузки, ПродолжитьЗагрузку)
ЧтениеXML = ПараметрыЗагрузки.ЧтениеXML;
ЧтениеСообщения = ПараметрыЗагрузки.ЧтениеСообщения; // ЧтениеСообщенияОбмена
КоличествоЗаписанных = 0;
Пока (ПараметрыЗагрузки.КоличествоЭлементовВТранзакции = 0
Или КоличествоЗаписанных <= ПараметрыЗагрузки.КоличествоЭлементовВТранзакции)
И ВозможностьЧтенияXML(ЧтениеXML) Цикл
Данные = ПрочитатьXML(ЧтениеXML);
ПолучениеЭлемента = ПолучениеЭлементаДанных.Авто;
ОтправкаНазад = Ложь;
СтандартныеПодсистемыСервер.ПриПолученииДанныхОтГлавного(
Данные, ПолучениеЭлемента, ОтправкаНазад, ЧтениеСообщения.Отправитель.ПолучитьОбъект());
ПараметрыЗагрузки.КоличествоОбъектовОбработано = ПараметрыЗагрузки.КоличествоОбъектовОбработано + 1;
Если ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать Тогда
Продолжить;
КонецЕсли;
// Переопределяем стандартное поведение системы при получении удаления объекта.
// Вместо физического удаления объекта без контроля ссылочной целостности
// выполняем установку пометки на удаление.
Если ТипЗнч(Данные) = Тип("УдалениеОбъекта") Тогда
Данные = Данные.Ссылка.ПолучитьОбъект();
Если Данные = Неопределено Тогда
Продолжить;
КонецЕсли;
Данные.ПометкаУдаления = Истина;
Если ОбщегоНазначения.ЭтоДокумент(Данные.Метаданные()) Тогда
Данные.Проведен = Ложь;
КонецЕсли;
Иначе
ОбменДаннымиСлужебный.ЗаменитьСсылкиНаПредопределенныеЭлементы(Данные, ПараметрыЗагрузки.ТаблицаПредопределенных);
КонецЕсли;
Если Не ОтправкаНазад Тогда
Данные.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель;
КонецЕсли;
Данные.ОбменДанными.Загрузка = Истина;
Данные.Записать();
КоличествоЗаписанных = КоличествоЗаписанных + 1;
КонецЦикла;
ПродолжитьЗагрузку = (КоличествоЗаписанных > 0);
КонецПроцедуры
Процедура ОбработатьСекциюПредопределенныхДанныхВСообщенииОбмена(ЧтениеXML, ТаблицаПредопределенных)
Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента
И ЧтениеXML.ЛокальноеИмя = "PredefinedData" Тогда
ЧтениеXML.Прочитать();
Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл
ИмяТипаXML = ЧтениеXML.ЛокальноеИмя;
ИмяПредопределенных = ЧтениеXML.ПолучитьАтрибут("PredefinedDataName");
ИсходнаяСсылка = ПрочитатьXML(ЧтениеXML);
СтрокиПредопределенные = ТаблицаПредопределенных.НайтиСтроки(
Новый Структура("ИмяТипаXML, ИмяПредопределенныхДанных", ИмяТипаXML, ИмяПредопределенных));
Для Каждого СтрокаПредопределенные Из СтрокиПредопределенные Цикл
СтрокаПредопределенные.ИсходнаяСсылка = ИсходнаяСсылка;
СтрокаПредопределенные.ИсходнаяСсылкаЗаполнена = Истина;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ФункцииСвойства
Функция ПолноеИмяФайлаДанныхОтложенногоОбновления()
Возврат ПолучитьИмяВременногоФайла(".xml");
КонецФункции
// Возвращает имя файла сообщения обмена данными по данным узла-отправителя и узла-получателя.
//
Функция ИмяФайлаСообщенияОбмена(КодУзлаОтправителя, КодУзлаПолучателя, ЭтоИсходящееСообщение)
ШаблонИмени = "[Префикс]_[УзелОтправитель]_[УзелПолучатель]";
Если СтрДлина(КодУзлаОтправителя) = 36 И ЭтоИсходящееСообщение Тогда
ПрефиксИБИсточника = Константы.ПрефиксУзлаРаспределеннойИнформационнойБазы.Получить();
Если ЗначениеЗаполнено(ПрефиксИБИсточника) Тогда
ШаблонИмени = "[Префикс]_[ПрефиксИБИсточника]_[УзелОтправитель]_[УзелПолучатель]";
КонецЕсли;
КонецЕсли;
ШаблонИмени = СтрЗаменить(ШаблонИмени, "[Префикс]", "Message");
ШаблонИмени = СтрЗаменить(ШаблонИмени, "[ПрефиксИБИсточника]",ПрефиксИБИсточника);
ШаблонИмени = СтрЗаменить(ШаблонИмени, "[УзелОтправитель]", КодУзлаОтправителя);
ШаблонИмени = СтрЗаменить(ШаблонИмени, "[УзелПолучатель]", КодУзлаПолучателя);
Возврат ШаблонИмени;
КонецФункции
// Возвращает имя временного каталога для сообщений обмена данными.
// Имя каталога соответствует шаблону:
// "Exchange82 {GUID}",
// где GUID - строка уникального идентификатора.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Строка - имя временного каталога для сообщений обмена данными.
//
Функция ИмяВременногоКаталогаСообщенийОбмена()
Возврат СтрЗаменить("Exchange82 {GUID}", "GUID", ВРег(Строка(Новый УникальныйИдентификатор)));
КонецФункции
// Возвращает имя обработки транспорта сообщений обмена.
//
// Параметры:
// ВидТранспорта - ПеречислениеСсылка.ВидыТранспортаСообщенийОбмена - вид транспорта, для которого необходимо получить
// имя обработки.
//
// Возвращаемое значение:
// Строка - имя обработки транспорта сообщений обмена.
//
Функция ИмяОбработкиТранспортаСообщенийОбмена(ВидТранспорта)
Возврат СтрЗаменить("ТранспортСообщенийОбмена[ВидТранспорта]", "[ВидТранспорта]", ОбщегоНазначения.ИмяЗначенияПеречисления(ВидТранспорта));
КонецФункции
// Дубль процедуры на сервере ОбменДаннымиКлиент.МаксимальноеКоличествоПолейСопоставленияОбъектов().
//
// Возвращаемое значение:
// Число
//
Функция МаксимальноеКоличествоПолейСопоставленияОбъектов() Экспорт
Возврат 5;
КонецФункции
// Определяет, входит ли план обмена в список планов обмена, которые используют обмен данными по формату XDTO.
//
// Параметры:
// ПланОбмена - ПланОбменаСсылка - ссылка на узел плана обмена или имя плана обмена.
//
// Возвращаемое значение:
// Булево - Истина, если план обмена используется для обмена данными по формату XDTO.
//
Функция ЭтоПланОбменаXDTO(ПланОбмена) Экспорт
Возврат ОбменДаннымиПовтИсп.ЭтоПланОбменаXDTO(ПланОбмена);
КонецФункции
// Функция-свойство: возвращает литерал обозначения строки неограниченной длины.
//
// Возвращаемое значение:
// Строка - литерал обозначения строки неограниченной длины.
//
Функция СтрокаНеограниченнойДлины() Экспорт
Возврат "(снд)";
КонецФункции
// Функция-свойство: возвращает литерал обозначения узла-XML, который содержит значение константы ПРО.
//
// Возвращаемое значение:
// Строка - литерал обозначения узла-XML, который содержит значение константы ПРО.
//
Функция ЭлементОтбораСвойствоЗначениеКонстанты() Экспорт
Возврат "ЗначениеКонстанты";
КонецФункции
// Функция-свойство: возвращает литерал обозначения узла-XML, который содержит алгоритм получения значения.
//
// Возвращаемое значение:
// Строка - возвращает литерал обозначения узла-XML, который содержит алгоритм получения значения.
//
Функция ЭлементОтбораСвойствоАлгоритмЗначения() Экспорт
Возврат "АлгоритмЗначения";
КонецФункции
// Функция-свойство: возвращает имя файла, который используется для проверки подключения обработки транспорта.
//
// Возвращаемое значение:
// Строка - возвращает имя файла, который используется для проверки подключения обработки транспорта.
//
Функция ИмяВременногоФайлаПроверкиПодключения() Экспорт
ПостфиксФайла = Строка(Новый УникальныйИдентификатор());
Возврат "ConnectionCheckFile_" + ПостфиксФайла + ".tmp";
КонецФункции
Функция ЭтоОшибкаНомерСообщенияМеньшеИлиРавенНомеруРанееПринятогоСообщения(ОписаниеОшибки)
Возврат СтрНайти(НРег(ОписаниеОшибки), НРег(НСтр("ru = 'Номер сообщения меньше или равен'"))) > 0;
КонецФункции
#КонецОбласти
#Область ТранспортСообщенийОбмена
Процедура ВыполнитьТранспортСообщенияОбменаПередОбработкой(СтруктураНастроекОбмена)
// Получаем инициализированную обработку транспорта сообщений.
ОбработкаТранспортаСообщенийОбмена = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена;
// Получаем новое имя временного файла.
Если Не ОбработкаТранспортаСообщенийОбмена.ВыполнитьДействияПередОбработкойСообщения() Тогда
ЗаписьЖурналаРегистрацииОбменаДанными(ОбработкаТранспортаСообщенийОбмена.СтрокаСообщенияОбОшибкеЖР, СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения;
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьТранспортСообщенияОбменаОтправка(СтруктураНастроекОбмена)
// Получаем инициализированную обработку транспорта сообщений.
ОбработкаТранспортаСообщенийОбмена = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена;
// Отправляем сообщение обмена из временного каталога.
Если Не ОбработкаТранспортаСообщенийОбмена.ПодключениеУстановлено()
Или Не ОбработкаТранспортаСообщенийОбмена.ОтправитьСообщение() Тогда
ЗаписьЖурналаРегистрацииОбменаДанными(ОбработкаТранспортаСообщенийОбмена.СтрокаСообщенияОбОшибкеЖР, СтруктураНастроекОбмена, Истина);
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения;
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьТранспортСообщенияОбменаПолучение(СтруктураНастроекОбмена, ИспользоватьПсевдоним = Истина, СтекОшибок = Неопределено)
Если СтекОшибок = Неопределено Тогда
СтекОшибок = Новый Массив;
КонецЕсли;
// Получаем инициализированную обработку транспорта сообщений.
ОбработкаТранспортаСообщенийОбмена = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена;
// Получаем сообщение обмена во временный каталог.
Если Не ОбработкаТранспортаСообщенийОбмена.ПодключениеУстановлено()
Или Не ОбработкаТранспортаСообщенийОбмена.ПолучитьСообщение() Тогда
СтекОшибок.Добавить(ОбработкаТранспортаСообщенийОбмена.СтрокаСообщенияОбОшибкеЖР);
Если Не ИспользоватьПсевдоним Тогда
// Больше попыток поиска файла не будет, поэтому регистрируем все накопленные ошибки.
Для Каждого ТекущаяОшибка Из СтекОшибок Цикл
ЗаписьЖурналаРегистрацииОбменаДанными(ТекущаяОшибка, СтруктураНастроекОбмена, Истина);
КонецЦикла;
КонецЕсли;
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения;
КонецЕсли;
Если ИспользоватьПсевдоним
И СтруктураНастроекОбмена.РезультатВыполненияОбмена <> Неопределено Тогда
// Возможно, сообщение удастся получить если применить виртуальный код узла (псевдоним).
Транслитерация = Неопределено;
Если СтруктураНастроекОбмена.ВидТранспортаОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.FILE Тогда
СтруктураНастроекОбмена.НастройкиТранспорта.Свойство("FILEТранслитерироватьИменаФайловСообщенийОбмена", Транслитерация);
ИначеЕсли СтруктураНастроекОбмена.ВидТранспортаОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.EMAIL Тогда
СтруктураНастроекОбмена.НастройкиТранспорта.Свойство("EMAILТранслитерироватьИменаФайловСообщенийОбмена", Транслитерация);
ИначеЕсли СтруктураНастроекОбмена.ВидТранспортаОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.FTP Тогда
СтруктураНастроекОбмена.НастройкиТранспорта.Свойство("FTPТранслитерироватьИменаФайловСообщенийОбмена", Транслитерация);
КонецЕсли;
Транслитерация = ?(Транслитерация = Неопределено, Ложь, Транслитерация);
ШаблонИмениФайлаСтарый = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена.ШаблонИмениФайлаСообщения;
СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена.ШаблонИмениФайлаСообщения = ШаблонИмениФайлаСообщения(
СтруктураНастроекОбмена.ТекущийУзелПланаОбмена,
СтруктураНастроекОбмена.УзелИнформационнойБазы,
Ложь,
Транслитерация,
Истина);
Если ШаблонИмениФайлаСтарый <> СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена.ШаблонИмениФайлаСообщения Тогда
// Попытка повторного выполнения транспорта с новым шаблоном.
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено;
ВыполнитьТранспортСообщенияОбменаПолучение(СтруктураНастроекОбмена, Ложь, СтекОшибок);
Иначе
// Больше попыток поиска файла не будет, поэтому регистрируем все накопленные ошибки.
Для Каждого ТекущаяОшибка Из СтекОшибок Цикл
ЗаписьЖурналаРегистрацииОбменаДанными(ТекущаяОшибка, СтруктураНастроекОбмена, Истина);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьТранспортСообщенияОбменаПослеОбработки(СтруктураНастроекОбмена)
// Получаем инициализированную обработку транспорта сообщений.
ОбработкаТранспортаСообщенийОбмена = СтруктураНастроекОбмена.ОбработкаТранспортаСообщенийОбмена;
// Выполняем действия после отправки сообщения.
ОбработкаТранспортаСообщенийОбмена.ВыполнитьДействияПослеОбработкиСообщения();
КонецПроцедуры
// Получает настройки прокси сервера.
//
Функция НастройкиПроксиСервера(ЗащищенноеСоединение)
Прокси = Неопределено;
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПолучениеФайловИзИнтернета") Тогда
МодульПолучениеФайловИзИнтернета = ОбщегоНазначения.ОбщийМодуль("ПолучениеФайловИзИнтернета");
Протокол = ?(ЗащищенноеСоединение = Неопределено, "ftp", "ftps");
Прокси = МодульПолучениеФайловИзИнтернета.ПолучитьПрокси(Протокол);
КонецЕсли;
Возврат Прокси;
КонецФункции
#КонецОбласти
#Область СервисПередачиФайлов
// Функция по переданному идентификатору скачивает файл из сервиса передачи файлов.
//
// Параметры:
// ИдентификаторФайла - УникальныйИдентификатор - идентификатор получаемого файла.
// ПараметрыДоступаКСервису - Структура: АдресСервиса, ИмяПользователя, ПарольПользователя.
// РазмерЧасти - Число - размер части в килобайтах. Если значение равно 0,
// то разбивка на части не производится.
// Возвращаемое значение:
// Строка - путь к полученному файлу.
//
Функция ПолучитьФайлИзХранилищаВСервисе(Знач ИдентификаторФайла, Знач УзелИнформационнойБазы, Знач РазмерЧасти = 1024, Знач ПараметрыАутентификации = Неопределено) Экспорт
// Возвращаемое значение функции.
ИмяФайлаРезультата = "";
ДополнительныеПараметры = Новый Структура("ПараметрыАутентификации", ПараметрыАутентификации);
СообщениеОбОшибке = "";
Прокси = WSПроксиДляУзлаИнформационнойБазы(УзелИнформационнойБазы, СообщениеОбОшибке, ДополнительныеПараметры);
Если Прокси = Неопределено Тогда
ВызватьИсключение СообщениеОбОшибке;
КонецЕсли;
ИдентификаторСессии = Неопределено;
КоличествоЧастей = Неопределено;
Прокси.PrepareGetFile(ИдентификаторФайла, РазмерЧасти, ИдентификаторСессии, КоличествоЧастей);
ИменаФайлов = Новый Массив;
КаталогСборки = ПолучитьИмяВременногоФайла();
СоздатьКаталог(КаталогСборки);
ШаблонИмениФайла = "data.zip.[n]";
// Протоколирование событий обмена.
СтруктураНастроекОбмена = Новый Структура("КлючСообщенияЖурналаРегистрации");
СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации = КлючСообщенияЖурналаРегистрации(УзелИнформационнойБазы, Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
Комментарий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Начало получения сообщения обмена из Интернета (количество частей файла %1).'"),
Формат(КоличествоЧастей, "ЧН=0; ЧГ=0"));
ЗаписьЖурналаРегистрацииОбменаДанными(Комментарий, СтруктураНастроекОбмена);
Для НомерЧасти = 1 По КоличествоЧастей Цикл
ДанныеЧасти = Неопределено; // ДвоичныеДанные
Попытка
Прокси.GetFilePart(ИдентификаторСессии, НомерЧасти, ДанныеЧасти);
Исключение
Прокси.ReleaseFile(ИдентификаторСессии);
ВызватьИсключение;
КонецПопытки;
ИмяФайла = СтрЗаменить(ШаблонИмениФайла, "[n]", Формат(НомерЧасти, "ЧГ=0"));
ИмяФайлаЧасти = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогСборки, ИмяФайла);
ДанныеЧасти.Записать(ИмяФайлаЧасти);
ИменаФайлов.Добавить(ИмяФайлаЧасти);
КонецЦикла;
ДанныеЧасти = Неопределено;
Прокси.ReleaseFile(ИдентификаторСессии);
ИмяАрхива = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогСборки, "data.zip");
ОбъединитьФайлы(ИменаФайлов, ИмяАрхива);
Разархиватор = Новый ЧтениеZipФайла(ИмяАрхива);
Если Разархиватор.Элементы.Количество() = 0 Тогда
Попытка
УдалитьФайлы(КаталогСборки);
Исключение
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУдалениеВременногоФайла(),
УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
ВызватьИсключение(НСтр("ru = 'Файл архива не содержит данных.'"));
КонецЕсли;
// Протоколирование событий обмена.
ФайлАрхива = Новый Файл(ИмяАрхива);
Комментарий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Окончание получения сообщения обмена из Интернета (размер сжатого сообщения обмена %1 Мб).'"),
Формат(Окр(ФайлАрхива.Размер() / 1024 / 1024, 3), "ЧН=0; ЧГ=0"));
ЗаписьЖурналаРегистрацииОбменаДанными(Комментарий, СтруктураНастроекОбмена);
ЭлементАрхива = Разархиватор.Элементы.Получить(0);
ИмяФайла = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогСборки, ЭлементАрхива.Имя);
Разархиватор.Извлечь(ЭлементАрхива, КаталогСборки);
Разархиватор.Закрыть();
Файл = Новый Файл(ИмяФайла);
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
ИмяФайлаРезультата = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(ВременныйКаталог, Файл.Имя);
ПереместитьФайл(ИмяФайла, ИмяФайлаРезультата);
Попытка
УдалитьФайлы(КаталогСборки);
Исключение
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУдалениеВременногоФайла(),
УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Возврат ИмяФайлаРезультата;
КонецФункции
// Функция передает указанный файл в сервис передачи файлов.
//
// Параметры:
// ИмяФайла - Строка - путь к передаваемому файлу.
// ПараметрыДоступаКСервису - Структура: АдресСервиса, ИмяПользователя, ПарольПользователя.
// РазмерЧасти - Число - размер части в килобайтах. Если значение равно 0,
// то разбивка на части не производится.
// Возвращаемое значение:
// УникальныйИдентификатор - идентификатор файла в сервисе передачи файлов.
//
Функция ПоместитьФайлВХранилищеВСервисе(Знач ИмяФайла, Знач УзелИнформационнойБазы, Знач РазмерЧасти = 1024, Знач ПараметрыАутентификации = Неопределено)
// Возвращаемое значение функции.
ИдентификаторФайла = Неопределено;
ДополнительныеПараметры = Новый Структура("ПараметрыАутентификации", ПараметрыАутентификации);
СообщениеОбОшибке = "";
Прокси = WSПроксиДляУзлаИнформационнойБазы(УзелИнформационнойБазы, СообщениеОбОшибке, ДополнительныеПараметры);
Если Прокси = Неопределено Тогда
ВызватьИсключение СообщениеОбОшибке;
КонецЕсли;
КаталогФайлов = ПолучитьИмяВременногоФайла();
СоздатьКаталог(КаталогФайлов);
// Архивирование файла.
ИмяНеразделенногоФайла = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогФайлов, "data.zip");
Архиватор = Новый ЗаписьZipФайла(ИмяНеразделенногоФайла,,,, УровеньСжатияZIP.Максимальный);
Архиватор.Добавить(ИмяФайла);
Архиватор.Записать();
// Разделение файла на части.
ИдентификаторСессии = Новый УникальныйИдентификатор;
КоличествоЧастей = 1;
Если ЗначениеЗаполнено(РазмерЧасти) Тогда
ИменаФайлов = РазделитьФайл(ИмяНеразделенногоФайла, РазмерЧасти * 1024);
КоличествоЧастей = ИменаФайлов.Количество();
Для НомерЧасти = 1 По КоличествоЧастей Цикл
ИмяФайлаЧасти = ИменаФайлов[НомерЧасти - 1];
ДанныеФайла = Новый ДвоичныеДанные(ИмяФайлаЧасти);
Прокси.PutFilePart(ИдентификаторСессии, НомерЧасти, ДанныеФайла);
КонецЦикла;
Иначе
ДанныеФайла = Новый ДвоичныеДанные(ИмяНеразделенногоФайла);
Прокси.PutFilePart(ИдентификаторСессии, 1, ДанныеФайла);
КонецЕсли;
Попытка
УдалитьФайлы(КаталогФайлов);
Исключение
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУдалениеВременногоФайла(),
УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Прокси.SaveFileFromParts(ИдентификаторСессии, КоличествоЧастей, ИдентификаторФайла);
Возврат ИдентификаторФайла;
КонецФункции
// Получение имени файла по его идентификатору из хранилища.
// Если файла с указанным идентификатором нет, то вызывается исключение.
// Если файл найден, то возвращается его имя, при этом удаляется информация об этом файле из хранилища.
//
// Параметры:
// ИдентификаторФайла - УникальныйИдентификатор - идентификатор получаемого файла.
// ИмяФайла - Строка - имя файла, из хранилища.
//
Процедура ПриПолученииФайлаИзХранилища(Знач ИдентификаторФайла, ИмяФайла)
ТекстЗапроса =
"ВЫБРАТЬ
| СообщенияОбменаДанными.ИмяФайлаСообщения КАК ИмяФайла
|ИЗ
| РегистрСведений.СообщенияОбменаДанными КАК СообщенияОбменаДанными
|ГДЕ
| СообщенияОбменаДанными.ИдентификаторСообщения = &ИдентификаторСообщения";
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ИдентификаторСообщения", Строка(ИдентификаторФайла));
Запрос.Текст = ТекстЗапроса;
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Описание = НСтр("ru = 'Файл с идентификатором %1 не обнаружен.'");
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Описание, Строка(ИдентификаторФайла));
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
ИмяФайла = Выборка.ИмяФайла;
// Удаляем информацию о файле сообщения обмена из хранилища.
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("ИдентификаторСообщения", Строка(ИдентификаторФайла));
РегистрыСведений.СообщенияОбменаДанными.УдалитьЗапись(СтруктураЗаписи);
КонецПроцедуры
// Помещение файла в хранилище.
//
Процедура ПриПомещенииФайлаВХранилище(Знач СтруктураЗаписи)
РегистрыСведений.СообщенияОбменаДанными.ДобавитьЗапись(СтруктураЗаписи);
КонецПроцедуры
#КонецОбласти
#Область РегистрацияИзмененийНачальнойВыгрузкиДанных
// Выполняет регистрацию изменений для начальной выгрузки данных с учетом даты начала выгрузки и списка организаций.
// Процедура является универсальной и может быть использована для регистрации изменений данных по дате начала выгрузки
// и списку организаций для объектных типов данных и наборов записей регистров.
// Если список организаций не задан (Организации = Неопределено), то изменения регистрируются только по дате начала
// выгрузки.
// Регистрации подлежат данные для всех объектов метаданных, включенных в состав плана обмена.
// Если для объекта метаданных в составе плана обмена установлен признак авторегистрации
// или если признак авторегистрации не установлен и правила регистрации не заданы,
// то регистрация изменений будет выполнена безусловно для всех данных этого типа.
// Если для объекта метаданных заданы правила регистрации, то регистрация изменений будет выполнена
// с учетом даты начала выгрузки и списка организаций.
// Для документов поддерживается регистрация изменений по дате начала выгрузки и по списку организаций.
// Для бизнес-процессов и для задач поддерживается регистрация изменений по дате начала выгрузки.
// Для наборов записей регистров поддерживается регистрация изменений по дате начала выгрузки и по списку организаций.
// Данная процедура может служить прототипом для разработки собственных процедур регистрации изменений
// для начальной выгрузки данных.
//
// Параметры:
//
// Получатель - ПланОбменаСсылка - узел плана обмена,
// для которого требуется выполнить регистрацию изменений данных.
// ДатаНачалаВыгрузки - Дата - дата, относительно которой необходимо выполнить
// регистрацию изменений данных для выгрузки. Изменения будут зарегистрированы для данных,
// которые на оси времени располагаются после этой даты.
// Организации - Массив
// - Неопределено - список организаций, для которых необходимо выполнить регистрацию
// изменений данных. Если параметр не задан, то организации не будут
// учитываться при регистрации изменений.
//
Процедура ЗарегистрироватьДанныеПоДатеНачалаВыгрузкиИОрганизациям(Знач Получатель, ДатаНачалаВыгрузки,
Организации = Неопределено,
Данные = Неопределено) Экспорт
ОтборПоОрганизациям = (Организации <> Неопределено);
ОтборПоДатеНачалаВыгрузки = ЗначениеЗаполнено(ДатаНачалаВыгрузки);
Если Не ОтборПоОрганизациям И Не ОтборПоДатеНачалаВыгрузки Тогда
Если ТипЗнч(Данные) = Тип("Массив") Тогда
Для Каждого ОбъектМетаданных Из Данные Цикл
ПланыОбмена.ЗарегистрироватьИзменения(Получатель, ОбъектМетаданных);
КонецЦикла;
Иначе
ПланыОбмена.ЗарегистрироватьИзменения(Получатель, Данные);
КонецЕсли;
Возврат;
КонецЕсли;
ОтборПоДатеНачалаВыгрузкиИОрганизациям = ОтборПоДатеНачалаВыгрузки И ОтборПоОрганизациям;
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(Получатель);
СоставПланаОбмена = Метаданные.ПланыОбмена[ИмяПланаОбмена].Состав;
ИспользоватьФильтрПоМетаданным = (ТипЗнч(Данные) = Тип("Массив"));
Для Каждого ЭлементСоставаПланаОбмена Из СоставПланаОбмена Цикл
Если ИспользоватьФильтрПоМетаданным
И Данные.Найти(ЭлементСоставаПланаОбмена.Метаданные) = Неопределено Тогда
Продолжить;
КонецЕсли;
ПолноеИмяОбъекта = ЭлементСоставаПланаОбмена.Метаданные.ПолноеИмя();
Если ЭлементСоставаПланаОбмена.АвтоРегистрация = АвтоРегистрацияИзменений.Запретить
И ОбменДаннымиПовтИсп.ПравилаРегистрацииОбъектаСуществуют(ИмяПланаОбмена, ПолноеИмяОбъекта) Тогда
Если ОбщегоНазначения.ЭтоДокумент(ЭлементСоставаПланаОбмена.Метаданные) Тогда // Документы
Если ОтборПоДатеНачалаВыгрузкиИОрганизациям
// Регистрация по дате и организациям.
И ЭлементСоставаПланаОбмена.Метаданные.Реквизиты.Найти("Организация") <> Неопределено Тогда
Выборка = ВыборкаДокументовПоДатеНачалаВыгрузкиИОрганизациям(ПолноеИмяОбъекта, ДатаНачалаВыгрузки, Организации);
Пока Выборка.Следующий() Цикл
ПланыОбмена.ЗарегистрироватьИзменения(Получатель, Выборка.Ссылка);
КонецЦикла;
Продолжить;
Иначе // Регистрация по дате
Выборка = ВыборкаОбъектовПоДатеНачалаВыгрузки(ПолноеИмяОбъекта, ДатаНачалаВыгрузки);
Пока Выборка.Следующий() Цикл
ПланыОбмена.ЗарегистрироватьИзменения(Получатель, Выборка.Ссылка);
КонецЦикла;
Продолжить;
КонецЕсли;
ИначеЕсли ОбщегоНазначения.ЭтоБизнесПроцесс(ЭлементСоставаПланаОбмена.Метаданные)
ИЛИ ОбщегоНазначения.ЭтоЗадача(ЭлементСоставаПланаОбмена.Метаданные) Тогда // Бизнес-процессы и Задачи
// Регистрация по дате
Выборка = ВыборкаОбъектовПоДатеНачалаВыгрузки(ПолноеИмяОбъекта, ДатаНачалаВыгрузки);
Пока Выборка.Следующий() Цикл
ПланыОбмена.ЗарегистрироватьИзменения(Получатель, Выборка.Ссылка);
КонецЦикла;
Продолжить;
ИначеЕсли ОбщегоНазначения.ЭтоРегистр(ЭлементСоставаПланаОбмена.Метаданные) Тогда // Регистры
// Регистры сведений (независимые).
Если ОбщегоНазначения.ЭтоРегистрСведений(ЭлементСоставаПланаОбмена.Метаданные)
И ЭлементСоставаПланаОбмена.Метаданные.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый Тогда
ОсновнойОтбор = ОсновнойОтборРегистраСведений(ЭлементСоставаПланаОбмена.Метаданные);
ОтборПоПериоду = (ОсновнойОтбор.Найти("Период") <> Неопределено);
ОтборПоОрганизации = (ОсновнойОтбор.Найти("Организация") <> Неопределено);
// Регистрация по дате и организациям.
Если ОтборПоДатеНачалаВыгрузкиИОрганизациям И ОтборПоПериоду И ОтборПоОрганизации Тогда
Выборка = ВыборкаЗначенийОсновногоОтбораРегистраСведенийПоДатеНачалаВыгрузкиИОрганизациям(ОсновнойОтбор, ПолноеИмяОбъекта, ДатаНачалаВыгрузки, Организации);
ИначеЕсли ОтборПоДатеНачалаВыгрузки И ОтборПоПериоду Тогда // Регистрация по дате
Выборка = ВыборкаЗначенийОсновногоОтбораРегистраСведенийПоДатеНачалаВыгрузки(ОсновнойОтбор, ПолноеИмяОбъекта, ДатаНачалаВыгрузки);
ИначеЕсли ОтборПоОрганизациям И ОтборПоОрганизации Тогда // Регистрация по организациям.
Выборка = ВыборкаЗначенийОсновногоОтбораРегистраСведенийПоОрганизациям(ОсновнойОтбор, ПолноеИмяОбъекта, Организации);
Иначе
Выборка = Неопределено;
КонецЕсли;
Если Выборка <> Неопределено Тогда
НаборЗаписей = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмяОбъекта).СоздатьНаборЗаписей();
Пока Выборка.Следующий() Цикл
Для Каждого ИмяИзмерения Из ОсновнойОтбор Цикл
НаборЗаписей.Отбор[ИмяИзмерения].Значение = Выборка[ИмяИзмерения];
НаборЗаписей.Отбор[ИмяИзмерения].Использование = Истина;
КонецЦикла;
ПланыОбмена.ЗарегистрироватьИзменения(Получатель, НаборЗаписей);
КонецЦикла;
Продолжить;
КонецЕсли;
Иначе // Регистры (прочие)
ЕстьПериодВРегистре = ОбщегоНазначения.ЭтоРегистрБухгалтерии(ЭлементСоставаПланаОбмена.Метаданные)
ИЛИ ОбщегоНазначения.ЭтоРегистрНакопления(ЭлементСоставаПланаОбмена.Метаданные)
ИЛИ (ОбщегоНазначения.ЭтоРегистрСведений(ЭлементСоставаПланаОбмена.Метаданные)
И ЭлементСоставаПланаОбмена.Метаданные.ПериодичностьРегистраСведений
<> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический);
Если ОтборПоДатеНачалаВыгрузкиИОрганизациям
И ЕстьПериодВРегистре
// Регистрация по дате и организациям.
И ЭлементСоставаПланаОбмена.Метаданные.Измерения.Найти("Организация") <> Неопределено Тогда
Выборка = ВыборкаРегистраторовНаборовЗаписейПоДатеНачалаВыгрузкиИОрганизациям(ПолноеИмяОбъекта, ДатаНачалаВыгрузки, Организации);
НаборЗаписей = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмяОбъекта).СоздатьНаборЗаписей();
Пока Выборка.Следующий() Цикл
НаборЗаписей.Отбор.Регистратор.Значение = Выборка.Регистратор;
НаборЗаписей.Отбор.Регистратор.Использование = Истина;
ПланыОбмена.ЗарегистрироватьИзменения(Получатель, НаборЗаписей);
КонецЦикла;
Продолжить;
// Регистрация по дате
ИначеЕсли ЕстьПериодВРегистре Тогда
Выборка = ВыборкаРегистраторовНаборовЗаписейПоДатеНачалаВыгрузки(ПолноеИмяОбъекта, ДатаНачалаВыгрузки);
НаборЗаписей = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмяОбъекта).СоздатьНаборЗаписей();
Пока Выборка.Следующий() Цикл
НаборЗаписей.Отбор.Регистратор.Значение = Выборка.Регистратор;
НаборЗаписей.Отбор.Регистратор.Использование = Истина;
ПланыОбмена.ЗарегистрироватьИзменения(Получатель, НаборЗаписей);
КонецЦикла;
Продолжить;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ПланыОбмена.ЗарегистрироватьИзменения(Получатель, ЭлементСоставаПланаОбмена.Метаданные);
КонецЦикла;
КонецПроцедуры
Функция ВыборкаДокументовПоДатеНачалаВыгрузкиИОрганизациям(ПолноеИмяОбъекта, ДатаНачалаВыгрузки, Организации)
ТекстЗапроса =
"ВЫБРАТЬ
| Таблица.Ссылка КАК Ссылка
|ИЗ
| &ПолноеИмяОбъекта КАК Таблица
|ГДЕ
| Таблица.Организация В(&Организации)
| И Таблица.Дата >= &ДатаНачалаВыгрузки";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолноеИмяОбъекта", ПолноеИмяОбъекта);
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДатаНачалаВыгрузки", ДатаНачалаВыгрузки);
Запрос.УстановитьПараметр("Организации", Организации);
Запрос.Текст = ТекстЗапроса;
Возврат Запрос.Выполнить().Выбрать();
КонецФункции
Функция ВыборкаОбъектовПоДатеНачалаВыгрузки(ПолноеИмяОбъекта, ДатаНачалаВыгрузки)
ТекстЗапроса =
"ВЫБРАТЬ
| Таблица.Ссылка КАК Ссылка
|ИЗ
| &ПолноеИмяОбъекта КАК Таблица
|ГДЕ
| Таблица.Дата >= &ДатаНачалаВыгрузки";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолноеИмяОбъекта", ПолноеИмяОбъекта);
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДатаНачалаВыгрузки", ДатаНачалаВыгрузки);
Запрос.Текст = ТекстЗапроса;
Возврат Запрос.Выполнить().Выбрать();
КонецФункции
Функция ВыборкаРегистраторовНаборовЗаписейПоДатеНачалаВыгрузкиИОрганизациям(ПолноеИмяОбъекта, ДатаНачалаВыгрузки, Организации)
ТекстЗапроса =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ТаблицаРегистра.Регистратор КАК Регистратор
|ИЗ
| &ПолноеИмяОбъекта КАК ТаблицаРегистра
|ГДЕ
| ТаблицаРегистра.Организация В(&Организации)
| И ТаблицаРегистра.Период >= &ДатаНачалаВыгрузки";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолноеИмяОбъекта", ПолноеИмяОбъекта);
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДатаНачалаВыгрузки", ДатаНачалаВыгрузки);
Запрос.УстановитьПараметр("Организации", Организации);
Запрос.Текст = ТекстЗапроса;
Возврат Запрос.Выполнить().Выбрать();
КонецФункции
Функция ВыборкаРегистраторовНаборовЗаписейПоДатеНачалаВыгрузки(ПолноеИмяОбъекта, ДатаНачалаВыгрузки)
ТекстЗапроса =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ТаблицаРегистра.Регистратор КАК Регистратор
|ИЗ
| &ПолноеИмяОбъекта КАК ТаблицаРегистра
|ГДЕ
| ТаблицаРегистра.Период >= &ДатаНачалаВыгрузки";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолноеИмяОбъекта", ПолноеИмяОбъекта);
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДатаНачалаВыгрузки", ДатаНачалаВыгрузки);
Запрос.Текст = ТекстЗапроса;
Возврат Запрос.Выполнить().Выбрать();
КонецФункции
Функция ВыборкаЗначенийОсновногоОтбораРегистраСведенийПоДатеНачалаВыгрузкиИОрганизациям(ОсновнойОтбор,
ПолноеИмяОбъекта,
ДатаНачалаВыгрузки,
Организации)
ТекстЗапроса =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| &Измерения
|ИЗ
| &ПолноеИмяОбъекта КАК ТаблицаРегистра
|ГДЕ
| ТаблицаРегистра.Организация В(&Организации)
| И ТаблицаРегистра.Период >= &ДатаНачалаВыгрузки";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолноеИмяОбъекта", ПолноеИмяОбъекта);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Измерения", СтрСоединить(ОсновнойОтбор, ","));
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДатаНачалаВыгрузки", ДатаНачалаВыгрузки);
Запрос.УстановитьПараметр("Организации", Организации);
Запрос.Текст = ТекстЗапроса;
Возврат Запрос.Выполнить().Выбрать();
КонецФункции
Функция ВыборкаЗначенийОсновногоОтбораРегистраСведенийПоДатеНачалаВыгрузки(ОсновнойОтбор, ПолноеИмяОбъекта, ДатаНачалаВыгрузки)
ТекстЗапроса =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| &Измерения
|ИЗ
| &ПолноеИмяОбъекта КАК ТаблицаРегистра
|ГДЕ
| ТаблицаРегистра.Период >= &ДатаНачалаВыгрузки";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолноеИмяОбъекта", ПолноеИмяОбъекта);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Измерения", СтрСоединить(ОсновнойОтбор, ","));
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДатаНачалаВыгрузки", ДатаНачалаВыгрузки);
Запрос.Текст = ТекстЗапроса;
Возврат Запрос.Выполнить().Выбрать();
КонецФункции
Функция ВыборкаЗначенийОсновногоОтбораРегистраСведенийПоОрганизациям(ОсновнойОтбор, ПолноеИмяОбъекта, Организации)
ТекстЗапроса =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| &Измерения
|ИЗ
| &ПолноеИмяОбъекта КАК ТаблицаРегистра
|ГДЕ
| ТаблицаРегистра.Организация В(&Организации)";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ПолноеИмяОбъекта", ПолноеИмяОбъекта);
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Измерения", СтрСоединить(ОсновнойОтбор, ","));
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Организации", Организации);
Запрос.Текст = ТекстЗапроса;
Возврат Запрос.Выполнить().Выбрать();
КонецФункции
Функция ОсновнойОтборРегистраСведений(ОбъектМетаданных)
Результат = Новый Массив;
Если ОбъектМетаданных.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический
И ОбъектМетаданных.ОсновнойОтборПоПериоду Тогда
Результат.Добавить("Период");
КонецЕсли;
Для Каждого Измерение Из ОбъектМетаданных.Измерения Цикл
Если Измерение.ОсновнойОтбор Тогда
Результат.Добавить(Измерение.Имя);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
#КонецОбласти
#Область ОберткиДляРаботыСПрограммнымИнтерфейсомМенеджераПланаОбмена
Функция ОбщиеДанныеУзлов(Знач ИмяПланаОбмена, Знач ВерсияКорреспондента, Знач ИдентификаторНастройки) Экспорт
Если ПустаяСтрока(ВерсияКорреспондента) Тогда
ВерсияКорреспондента = "0.0.0.0";
КонецЕсли;
ОписаниеВариантаНастройки = ОбменДаннымиПовтИсп.ОписаниеВариантаНастройки(ИмяПланаОбмена,
ИдентификаторНастройки, ВерсияКорреспондента);
Результат = ОписаниеВариантаНастройки.ОбщиеДанныеУзлов;
Возврат СтрЗаменить(Результат, " ", "");
КонецФункции
Процедура ПриПодключенииККорреспонденту(Знач ИмяПланаОбмена, Знач ВерсияКорреспондента) Экспорт
Если НЕ ЕстьАлгоритмМенеджераПланаОбмена("ПриПодключенииККорреспонденту", ИмяПланаОбмена) Тогда
Возврат;
ИначеЕсли ПустаяСтрока(ВерсияКорреспондента) Тогда
ВерсияКорреспондента = "0.0.0.0";
КонецЕсли;
ПланыОбмена[ИмяПланаОбмена].ПриПодключенииККорреспонденту(ВерсияКорреспондента);
КонецПроцедуры
// Заполняет настройки для плана обмена, которые далее используются подсистемой обмена данными.
// Параметры:
// ИмяПланаОбмена - Строка - имя плана обмена.
// ВерсияКорреспондента - Строка - версия конфигурации-корреспондента.
// ИмяКорреспондента - Строка - имя конфигурации корреспондента.
// КорреспондентВМоделиСервиса - Булево, Неопределено - признак того, что корреспондент находится в модели сервиса.
// Возвращаемое значение:
// см. НастройкиПланаОбменаПоУмолчанию.
//
Функция НастройкиПланаОбмена(ИмяПланаОбмена, ВерсияКорреспондента, ИмяКорреспондента, КорреспондентВМоделиСервиса) Экспорт
НастройкиПланаОбмена = НастройкиПланаОбменаПоУмолчанию(ИмяПланаОбмена);
УстановитьПривилегированныйРежим(Истина);
ПланыОбмена[ИмяПланаОбмена].ПриПолученииНастроек(НастройкиПланаОбмена);
ЕстьОбработчикПолученияВариантов = НастройкиПланаОбмена.Алгоритмы.ПриПолученииВариантовНастроекОбмена;
// Требуется инициализация вариантов.
Если ЕстьОбработчикПолученияВариантов Тогда
ПараметрыОтбора = ПараметрыКонтекстаПолученияВариантовНастроек(ИмяКорреспондента, ВерсияКорреспондента, КорреспондентВМоделиСервиса);
ПланыОбмена[ИмяПланаОбмена].ПриПолученииВариантовНастроекОбмена(НастройкиПланаОбмена.ВариантыНастроекОбмена, ПараметрыОтбора);
Иначе
// Варианты не используются - следует добавить служебный вариант.
ВариантНастройки = НастройкиПланаОбмена.ВариантыНастроекОбмена.Добавить();
ВариантНастройки.ИдентификаторНастройки = "";
ВариантНастройки.КорреспондентВМоделиСервиса = ОбщегоНазначения.РазделениеВключено()
И НастройкиПланаОбмена.ПланОбменаИспользуетсяВМоделиСервиса;
ВариантНастройки.КорреспондентВЛокальномРежиме = Истина;
КонецЕсли;
УстановитьПривилегированныйРежим(Ложь);
Возврат НастройкиПланаОбмена;
КонецФункции
// Заполняет настройки, относящиеся к варианту настройки обмена, которые далее используются подсистемой обмена данными.
//
// Параметры:
// ИмяПланаОбмена - Строка - имя плана обмена.
// ИдентификаторНастройки - Строка - идентификатор варианта настройки обмена.
// ВерсияКорреспондента - Строка - версия конфигурации-корреспондента.
// ИмяКорреспондента - Строка - имя конфигурации корреспондента.
//
// Возвращаемое значение:
// см. ОписаниеВариантаНастройкиОбменаПоУмолчанию
//
Функция ОписаниеВариантаНастройки(ИмяПланаОбмена, ИдентификаторНастройки,
ВерсияКорреспондента, ИмяКорреспондента) Экспорт
ОписаниеВариантаНастройки = ОписаниеВариантаНастройкиОбменаПоУмолчанию(ИмяПланаОбмена);
ЕстьОбработчикОписанияВарианта = ЕстьАлгоритмМенеджераПланаОбмена("ПриПолученииОписанияВариантаНастройки", ИмяПланаОбмена);
Если ЕстьОбработчикОписанияВарианта Тогда
ПараметрыВарианта = ПараметрыКонтекстаПолученияОписанияВариантаНастройки(ИмяКорреспондента, ВерсияКорреспондента);
ПланыОбмена[ИмяПланаОбмена].ПриПолученииОписанияВариантаНастройки(
ОписаниеВариантаНастройки, ИдентификаторНастройки, ПараметрыВарианта);
КонецЕсли;
Возврат ОписаниеВариантаНастройки;
КонецФункции
#КонецОбласти
#Область РаботаСПаролямиСинхронизацииДанных
// Возвращает значения пароля синхронизации данных для заданного узла.
// Если пароля нет, то возвращается Неопределено.
//
// Возвращаемое значение:
// Строка, Неопределено - значения пароля синхронизации данных.
//
Функция ПарольСинхронизацииДанных(Знач УзелИнформационнойБазы) Экспорт
УстановитьПривилегированныйРежим(Истина);
Возврат ПараметрыСеанса.ПаролиСинхронизацииДанных.Получить(УзелИнформационнойБазы);
КонецФункции
// Возвращает признак того, что пароль синхронизации данных был задан пользователем.
//
Функция ПарольСинхронизацииДанныхЗадан(Знач УзелИнформационнойБазы) Экспорт
Возврат ПарольСинхронизацииДанных(УзелИнформационнойБазы) <> Неопределено;
КонецФункции
// Устанавливает пароль синхронизации данных для заданного узла.
// Пароль сохраняется в параметре сеанса.
//
Процедура УстановитьПарольСинхронизацииДанных(Знач УзелИнформационнойБазы, Знач Пароль)
УстановитьПривилегированныйРежим(Истина);
ПаролиСинхронизацииДанных = Новый Соответствие;
Для Каждого Элемент Из ПараметрыСеанса.ПаролиСинхронизацииДанных Цикл
ПаролиСинхронизацииДанных.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
ПаролиСинхронизацииДанных.Вставить(УзелИнформационнойБазы, Пароль);
ПараметрыСеанса.ПаролиСинхронизацииДанных = Новый ФиксированноеСоответствие(ПаролиСинхронизацииДанных);
КонецПроцедуры
// Сбрасывает пароль синхронизации данных для заданного узла.
//
Процедура СброситьПарольСинхронизацииДанных(Знач УзелИнформационнойБазы)
УстановитьПарольСинхронизацииДанных(УзелИнформационнойБазы, Неопределено);
КонецПроцедуры
#КонецОбласти
#Область КонтрольНеразделенныхДанных
// Вызывается при проверке доступности неразделенных данных для записи.
//
Процедура ВыполнитьКонтрольЗаписиНеразделенныхДанных(Знач Данные) Экспорт
Если ОбщегоНазначения.РазделениеВключено()
И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных()
И Не ЭтоРазделенныйОбъект(Данные) Тогда
ТекстИсключения = НСтр("ru = 'Недостаточно прав для выполнения действия.'", ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрации(
ТекстИсключения,
УровеньЖурналаРегистрации.Ошибка,
Данные.Метаданные());
ВызватьИсключение ТекстИсключения;
КонецЕсли;
КонецПроцедуры
Функция ЭтоРазделенныйОбъект(Знач Объект)
ПолноеИмя = Объект.Метаданные().ПолноеИмя();
Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
ЭтоРазделенныйОбъектМетаданных = МодульРаботаВМоделиСервиса.ЭтоРазделенныйОбъектМетаданных(ПолноеИмя);
Иначе
ЭтоРазделенныйОбъектМетаданных = Ложь;
КонецЕсли;
Возврат ЭтоРазделенныйОбъектМетаданных;
КонецФункции
#КонецОбласти
#Область РаботаСМониторомОбменаДанными
// Возвращает структуру с данными последнего обмена для заданного узла информационной базы.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// СостоянияОбменовДанными - Структура - структура с данными последнего обмена для заданного узла информационной базы.
//
Функция СостоянияОбменовДаннымиДляУзлаИнформационнойБазы(Знач УзелИнформационнойБазы) Экспорт
УстановитьПривилегированныйРежим(Истина);
// Возвращаемое значение функции.
СостоянияОбменовДанными = Новый Структура;
СостоянияОбменовДанными.Вставить("УзелИнформационнойБазы");
СостоянияОбменовДанными.Вставить("РезультатЗагрузкиДанных", "Неопределено");
СостоянияОбменовДанными.Вставить("РезультатВыгрузкиДанных", "Неопределено");
ТекстЗапроса = "
|// {ЗАПРОС №0}
|////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВЫБОР
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Выполнено)
| ТОГДА ""Успех""
|
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями)
| ТОГДА ""ВыполненоСПредупреждениями""
|
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято)
| ТОГДА ""Предупреждение_СообщениеОбменаБылоРанееПринято""
|
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения)
| ТОГДА ""Ошибка_ТранспортСообщения""
|
| ИНАЧЕ ""Ошибка""
|
| КОНЕЦ КАК РезультатВыполненияОбмена
|ИЗ
| РегистрСведений.СостоянияОбменовДанными КАК СостоянияОбменовДанными
|ГДЕ
| СостоянияОбменовДанными.УзелИнформационнойБазы = &УзелИнформационнойБазы
| И СостоянияОбменовДанными.ДействиеПриОбмене = ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ЗагрузкаДанных)
|;
|// {ЗАПРОС №1}
|////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВЫБОР
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Выполнено)
| ТОГДА ""Успех""
|
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями)
| ТОГДА ""ВыполненоСПредупреждениями""
|
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято)
| ТОГДА ""Предупреждение_СообщениеОбменаБылоРанееПринято""
|
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Ошибка_ТранспортСообщения)
| ТОГДА ""Ошибка_ТранспортСообщения""
|
| ИНАЧЕ ""Ошибка""
| КОНЕЦ КАК РезультатВыполненияОбмена
|
|ИЗ
| РегистрСведений.СостоянияОбменовДанными КАК СостоянияОбменовДанными
|ГДЕ
| СостоянияОбменовДанными.УзелИнформационнойБазы = &УзелИнформационнойБазы
| И СостоянияОбменовДанными.ДействиеПриОбмене = ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ВыгрузкаДанных)
|;
|";
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса") Тогда
МодульОбменДаннымиВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиВМоделиСервиса");
МодульОбменДаннымиВМоделиСервиса.АдаптироватьТекстЗапросаОРезультатахОбменаВСервисе(ТекстЗапроса);
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("УзелИнформационнойБазы", УзелИнформационнойБазы);
МассивРезультатовЗапроса = Запрос.ВыполнитьПакет(); // Массив из РезультатЗапроса
ВыборкаРезультатовЗагрузкиДанных = МассивРезультатовЗапроса[0].Выбрать();
ВыборкаРезультатовВыгрузкиДанных = МассивРезультатовЗапроса[1].Выбрать();
Если ВыборкаРезультатовЗагрузкиДанных.Следующий() Тогда
СостоянияОбменовДанными.РезультатЗагрузкиДанных = ВыборкаРезультатовЗагрузкиДанных.РезультатВыполненияОбмена;
КонецЕсли;
Если ВыборкаРезультатовВыгрузкиДанных.Следующий() Тогда
СостоянияОбменовДанными.РезультатВыгрузкиДанных = ВыборкаРезультатовВыгрузкиДанных.РезультатВыполненияОбмена;
КонецЕсли;
СостоянияОбменовДанными.УзелИнформационнойБазы = УзелИнформационнойБазы;
Возврат СостоянияОбменовДанными;
КонецФункции
// Возвращает структуру с данными последнего обмена для заданного узла информационной базы и действия при обмене.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// СостоянияОбменовДанными - Структура - структура с данными последнего обмена для заданного узла информационной базы.
//
Функция СостоянияОбменовДанными(Знач УзелИнформационнойБазы, ДействиеПриОбмене) Экспорт
// Возвращаемое значение функции.
СостоянияОбменовДанными = Новый Структура;
СостоянияОбменовДанными.Вставить("ДатаНачала", Дата('00010101'));
СостоянияОбменовДанными.Вставить("ДатаОкончания", Дата('00010101'));
ТекстЗапроса = "
|ВЫБРАТЬ
| ДатаНачала,
| ДатаОкончания
|ИЗ
| РегистрСведений.СостоянияОбменовДанными КАК СостоянияОбменовДанными
|ГДЕ
| СостоянияОбменовДанными.УзелИнформационнойБазы = &УзелИнформационнойБазы
| И СостоянияОбменовДанными.ДействиеПриОбмене = &ДействиеПриОбмене
|";
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса") Тогда
МодульОбменДаннымиВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиВМоделиСервиса");
МодульОбменДаннымиВМоделиСервиса.АдаптироватьТекстЗапросаОРезультатахОбменаВСервисе(ТекстЗапроса);
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("УзелИнформационнойБазы", УзелИнформационнойБазы);
Запрос.УстановитьПараметр("ДействиеПриОбмене", ДействиеПриОбмене);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ЗаполнитьЗначенияСвойств(СостоянияОбменовДанными, Выборка);
КонецЕсли;
Возврат СостоянияОбменовДанными;
КонецФункции
#КонецОбласти
#Область ИнициализацияСеанса
// Получает массив всех планов обмена по которым выполняется обмен данными.
// Наличие обмена с каким либо планом обмена определяется по наличию у этого плана обмена узлов кроме предопределенного.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// МассивПлановОбмена - Массив - массив строк (имен) всех планов обмена по которым выполняется обмен данными.
//
Функция ПолучитьИспользуемыеПланыОбмена() Экспорт
// возвращаемое значение
МассивПлановОбмена = Новый Массив;
Для Каждого ИмяПланаОбмена Из ОбменДаннымиПовтИсп.ПланыОбменаБСП() Цикл
Если Не ПланОбменаНеСодержитУзлов(ИмяПланаОбмена) Тогда
МассивПлановОбмена.Добавить(ИмяПланаОбмена);
КонецЕсли;
КонецЦикла;
Возврат МассивПлановОбмена;
КонецФункции
// Получает таблицу правил регистрации объектов из информационной базы.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// ПравилаРегистрацииОбъектов - ТаблицаЗначений - таблица общих правил регистрации объектов для МРО.
//
Функция ПолучитьПравилаРегистрацииОбъектов() Экспорт
// Возвращаемое значение функции.
ПравилаРегистрацииОбъектов = ИнициализацияТаблицыПравилРегистрацииОбъектов();
ТекстЗапроса = "
|ВЫБРАТЬ
| ПравилаДляОбменаДанными.ПравилаЗачитанные КАК ПравилаЗачитанные
|ИЗ
| РегистрСведений.ПравилаДляОбменаДанными КАК ПравилаДляОбменаДанными
|ГДЕ
| ПравилаДляОбменаДанными.ВидПравил = ЗНАЧЕНИЕ(Перечисление.ВидыПравилДляОбменаДанными.ПравилаРегистрацииОбъектов)
| И ПравилаДляОбменаДанными.ПравилаЗагружены
|";
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ПравилаЗачитанные = Выборка.ПравилаЗачитанные.Получить();
Если ПравилаЗачитанные = Неопределено Тогда
Продолжить;
КонецЕсли;
ЗаполнитьЗначенияСвойствДляТаблицыЗначенийПРО(ПравилаРегистрацииОбъектов, ПравилаЗачитанные);
КонецЦикла;
Возврат ПравилаРегистрацииОбъектов;
КонецФункции
// Получает таблицу правил выборочной регистрации объектов из информационной базы.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// ПравилаВыборочнойРегистрацииОбъектов - ТаблицаЗначений - таблица общих правил выборочной регистрации объектов для
// МРО.
//
Функция ПолучитьПравилаВыборочнойРегистрацииОбъектов() Экспорт
// Возвращаемое значение функции.
ПравилаВыборочнойРегистрацииОбъектов = ИнициализацияТаблицыПравилВыборочнойРегистрацииОбъектов();
ТекстЗапроса = "
|ВЫБРАТЬ
| ПравилаДляОбменаДанными.ПравилаЗачитанные КАК ПравилаЗачитанные
|ИЗ
| РегистрСведений.ПравилаДляОбменаДанными КАК ПравилаДляОбменаДанными
|ГДЕ
| ПравилаДляОбменаДанными.ВидПравил = ЗНАЧЕНИЕ(Перечисление.ВидыПравилДляОбменаДанными.ПравилаКонвертацииОбъектов)
| И ПравилаДляОбменаДанными.ИспользоватьФильтрВыборочнойРегистрацииОбъектов
| И ПравилаДляОбменаДанными.ПравилаЗагружены
|";
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СтруктураПравилОбмена = Выборка.ПравилаЗачитанные.Получить();
ЗаполнитьЗначенияСвойствДляТаблицыЗначений(ПравилаВыборочнойРегистрацииОбъектов, СтруктураПравилОбмена["ПравилаВыборочнойРегистрацииОбъектов"]);
КонецЦикла;
Возврат ПравилаВыборочнойРегистрацииОбъектов;
КонецФункции
Функция ИнициализацияТаблицыПравилРегистрацииОбъектов() Экспорт
// Возвращаемое значение функции.
Правила = Новый ТаблицаЗначений;
Колонки = Правила.Колонки;
Колонки.Добавить("ОбъектМетаданныхИмя", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("ИмяПланаОбмена", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("ИмяРеквизитаФлага", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("ТекстЗапроса", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("СвойстваОбъекта", Новый ОписаниеТипов("Структура"));
Колонки.Добавить("СвойстваОбъектаСтрокой", Новый ОписаниеТипов("Строка"));
// Признаки того, что правила пустые.
Колонки.Добавить("ПравилоПоСвойствамОбъектаПустое", Новый ОписаниеТипов("Булево"));
// обработчики событий
Колонки.Добавить("ПередОбработкой", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("ПриОбработке", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("ПриОбработкеДополнительный", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("ПослеОбработки", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("ЕстьОбработчикПередОбработкой", Новый ОписаниеТипов("Булево"));
Колонки.Добавить("ЕстьОбработчикПриОбработке", Новый ОписаниеТипов("Булево"));
Колонки.Добавить("ЕстьОбработчикПриОбработкеДополнительный", Новый ОписаниеТипов("Булево"));
Колонки.Добавить("ЕстьОбработчикПослеОбработки", Новый ОписаниеТипов("Булево"));
Колонки.Добавить("ОтборПоСвойствамОбъекта", Новый ОписаниеТипов("ДеревоЗначений"));
// Поле для оперативного хранения данных из объекта или ссылки.
Колонки.Добавить("ОтборПоСвойствам", Новый ОписаниеТипов("ДеревоЗначений"));
// добавляем индекс
Правила.Индексы.Добавить("ИмяПланаОбмена, ОбъектМетаданныхИмя");
Возврат Правила;
КонецФункции
Функция ИнициализацияТаблицыПравилВыборочнойРегистрацииОбъектов() Экспорт
// Возвращаемое значение функции.
Правила = Новый ТаблицаЗначений;
Колонки = Правила.Колонки;
Колонки.Добавить("Порядок", Новый ОписаниеТипов("Число"));
Колонки.Добавить("ИмяОбъекта", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("ИмяПланаОбмена", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("ИмяТабличнойЧасти", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("РеквизитыРегистрации", Новый ОписаниеТипов("Строка"));
Колонки.Добавить("СтруктураРеквизитовРегистрации", Новый ОписаниеТипов("Структура"));
// добавляем индекс
Правила.Индексы.Добавить("ИмяПланаОбмена, ИмяОбъекта");
Возврат Правила;
КонецФункции
Функция ПланОбменаНеСодержитУзлов(Знач ИмяПланаОбмена)
Запрос = Новый Запрос(
"ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
|ИЗ
| #ИмяТаблицыПланаОбмена КАК ПланОбмена
|ГДЕ
| НЕ ПланОбмена.ЭтотУзел");
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ИмяТаблицыПланаОбмена", "ПланОбмена." + ИмяПланаОбмена);
Возврат Запрос.Выполнить().Пустой();
КонецФункции
Процедура ЗаполнитьЗначенияСвойствДляТаблицыЗначенийПРО(ТаблицаПриемник, ТаблицаИсточник)
Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл
ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаИсточника);
КонецЦикла;
КонецПроцедуры
Процедура ЗаполнитьЗначенияСвойствДляТаблицыЗначений(ТаблицаПриемник, ТаблицаИсточник)
Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл
ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаИсточника);
КонецЦикла;
КонецПроцедуры
Функция ОписаниеПравилСинхронизацииДанных(Знач УзелИнформационнойБазы) Экспорт
УстановитьПривилегированныйРежим(Истина);
ВерсияКорреспондента = ВерсияКорреспондента(УзелИнформационнойБазы);
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелИнформационнойБазы);
Настройка = ЗначенияНастроекОтборовНаУзле(УзелИнформационнойБазы, ВерсияКорреспондента);
ОписаниеПравилСинхронизацииДанных = ОписаниеОграниченийПередачиДанных(
ИмяПланаОбмена, Настройка, ВерсияКорреспондента,СохраненныйВариантНастройкиУзлаПланаОбмена(УзелИнформационнойБазы));
УстановитьПривилегированныйРежим(Ложь);
Возврат ОписаниеПравилСинхронизацииДанных;
КонецФункции
Функция ЗначенияНастроекОтборовНаУзле(Знач УзелИнформационнойБазы, Знач ВерсияКорреспондента)
Результат = Новый Структура;
УзелИнформационнойБазыОбъект = УзелИнформационнойБазы.ПолучитьОбъект();
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелИнформационнойБазы);
НастройкаОтборовНаУзле = НастройкаОтборовНаУзле(ИмяПланаОбмена,
ВерсияКорреспондента, СохраненныйВариантНастройкиУзлаПланаОбмена(УзелИнформационнойБазы));
Для Каждого Настройка Из НастройкаОтборовНаУзле Цикл
Если ТипЗнч(Настройка.Значение) = Тип("Структура") Тогда
ТабличнаяЧасть = Новый Структура;
Для Каждого Колонка Из Настройка.Значение Цикл
ТабличнаяЧасть.Вставить(Колонка.Ключ, УзелИнформационнойБазыОбъект[Настройка.Ключ].ВыгрузитьКолонку(Колонка.Ключ));
КонецЦикла;
Результат.Вставить(Настройка.Ключ, ТабличнаяЧасть);
Иначе
Результат.Вставить(Настройка.Ключ, УзелИнформационнойБазыОбъект[Настройка.Ключ]);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура УстановитьРежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском(Знач Свойство, Знач ВключитьРежим) Экспорт
// Перед вызовом требуется установить привилегированный режим.
Если ЭтоПодчиненныйУзелРИБ() Тогда
НоваяСтруктура = Новый Структура(ПараметрыСеанса.РежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском);
Если ВключитьРежим Тогда
Если НЕ НоваяСтруктура.Свойство(Свойство) Тогда
НоваяСтруктура.Вставить(Свойство);
КонецЕсли;
Иначе
Если НоваяСтруктура.Свойство(Свойство) Тогда
НоваяСтруктура.Удалить(Свойство);
КонецЕсли;
КонецЕсли;
ПараметрыСеанса.РежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском =
Новый ФиксированнаяСтруктура(НоваяСтруктура);
Иначе
ПараметрыСеанса.РежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском = Новый ФиксированнаяСтруктура;
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ИнициализацияСтруктурыНастроекОбмена
// Выполняет инициализацию подсистемы обмена данными для выполнения процесса обмена.
//
// Параметры:
//
// Возвращаемое значение:
// СтруктураНастроекОбмена - Структура - структура со всеми необходимыми данными и объектами для выполнения обмена.
//
Функция НастройкиОбменаДляУзлаИнформационнойБазы(
УзелИнформационнойБазы,
ДействиеПриОбмене,
ВидТранспортаСообщенийОбмена,
ИспользоватьНастройкиТранспорта = Истина) Экспорт
// Возвращаемое значение функции.
СтруктураНастроекОбмена = СтруктураНастроекОбменаБазовая();
СтруктураНастроекОбмена.УзелИнформационнойБазы = УзелИнформационнойБазы;
СтруктураНастроекОбмена.ДействиеПриОбмене = ДействиеПриОбмене;
СтруктураНастроекОбмена.ВидТранспортаОбмена = ВидТранспортаСообщенийОбмена;
СтруктураНастроекОбмена.ЭтоОбменВРИБ = ОбменДаннымиПовтИсп.ЭтоУзелРаспределеннойИнформационнойБазы(УзелИнформационнойБазы);
ВыполнитьИнициализациюСтруктурыНастроекОбменаДляУзлаИнформационнойБазы(СтруктураНастроекОбмена, ИспользоватьНастройкиТранспорта);
УстановитьНастройкиРежимаОтладкиДляСтруктуры(СтруктураНастроекОбмена);
// Проверяем структуру настроек на валидность значений для выполнения обмена. Ошибки фиксируем в ЖР.
ВыполнитьПроверкуСтруктурыОбменаНаВалидность(СтруктураНастроекОбмена, ИспользоватьНастройкиТранспорта);
// Если настройки содержат ошибки, то выходим.
Если СтруктураНастроекОбмена.Отказ Тогда
Возврат СтруктураНастроекОбмена;
КонецЕсли;
Если ИспользоватьНастройкиТранспорта Тогда
// Инициализируем обработку транспорта сообщений обмена.
ВыполнитьИнициализациюОбработкиТранспортаСообщенийОбмена(СтруктураНастроекОбмена);
КонецЕсли;
// Инициализируем обработку обмена данными.
Если СтруктураНастроекОбмена.ЭтоОбменВРИБ Тогда
ВыполнитьИнициализациюОбработкиОбмена(СтруктураНастроекОбмена);
ИначеЕсли СтруктураНастроекОбмена.ОбменПоПравиламКонвертацииОбъектов Тогда
ВыполнитьИнициализациюОбработкиОбменаПоПравиламКонвертации(СтруктураНастроекОбмена);
КонецЕсли;
Возврат СтруктураНастроекОбмена;
КонецФункции
Функция НастройкиОбменаДляВнешнегоСоединения(УзелИнформационнойБазы, ДействиеПриОбмене, КоличествоЭлементовВТранзакции)
// Возвращаемое значение функции.
СтруктураНастроекОбмена = СтруктураНастроекОбменаБазовая();
СтруктураНастроекОбмена.УзелИнформационнойБазы = УзелИнформационнойБазы;
СтруктураНастроекОбмена.ДействиеПриОбмене = ДействиеПриОбмене;
СтруктураНастроекОбмена.ЭтоОбменВРИБ = ОбменДаннымиПовтИсп.ЭтоУзелРаспределеннойИнформационнойБазы(УзелИнформационнойБазы);
СтруктураСвойств = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(СтруктураНастроекОбмена.УзелИнформационнойБазы, "Код, Наименование");
СтруктураНастроекОбмена.УзелИнформационнойБазыКод = ИдентификаторУзлаКорреспондентаДляОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураНастроекОбмена.УзелИнформационнойБазыНаименование = СтруктураСвойств.Наименование;
СтруктураНастроекОбмена.НастройкиТранспорта = РегистрыСведений.НастройкиТранспортаОбменаДанными.НастройкиТранспорта(СтруктураНастроекОбмена.УзелИнформационнойБазы);
Если КоличествоЭлементовВТранзакции = Неопределено Тогда
КоличествоЭлементовВТранзакции = КоличествоЭлементовВТранзакцииВыполняемогоДействия(ДействиеПриОбмене);
КонецЕсли;
СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции = КоличествоЭлементовВТранзакции;
// ВЫЧИСЛЯЕМЫЕ ЗНАЧЕНИЯ
СтруктураНастроекОбмена.ПроизводитьЗагрузкуДанных = (СтруктураНастроекОбмена.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
СтруктураНастроекОбмена.ПроизводитьВыгрузкуДанных = (СтруктураНастроекОбмена.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ВыгрузкаДанных);
СтруктураНастроекОбмена.ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураНастроекОбмена.ТекущийУзелПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьЭтотУзелПланаОбмена(СтруктураНастроекОбмена.ИмяПланаОбмена);
СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод = ИдентификаторЭтогоУзлаДляОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы);
// Получаем ключ сообщения для ЖР.
СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации = КлючСообщенияЖурналаРегистрации(СтруктураНастроекОбмена.УзелИнформационнойБазы, СтруктураНастроекОбмена.ДействиеПриОбмене);
СтруктураНастроекОбмена.ВидТранспортаОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.COM;
УстановитьНастройкиРежимаОтладкиДляСтруктуры(СтруктураНастроекОбмена);
// Проверяем структуру настроек на валидность значений для выполнения обмена. Ошибки фиксируем в ЖР.
ВыполнитьПроверкуСтруктурыОбменаНаВалидность(СтруктураНастроекОбмена);
// Если настройки содержат ошибки, то выходим.
Если СтруктураНастроекОбмена.Отказ Тогда
Возврат СтруктураНастроекОбмена;
КонецЕсли;
// Инициализируем обработку обмена данными.
ВыполнитьИнициализациюОбработкиОбменаПоПравиламКонвертации(СтруктураНастроекОбмена);
Возврат СтруктураНастроекОбмена;
КонецФункции
// Выполняет инициализацию подсистемы обмена данными для выполнения процесса обмена.
//
// Параметры:
//
// Возвращаемое значение:
// СтруктураНастроекОбмена - Структура - структура со всеми необходимыми данными и объектами для выполнения обмена.
//
Функция НастройкиОбменаДанными(НастройкаВыполненияОбмена, НомерСтроки)
// Возвращаемое значение функции.
СтруктураНастроекОбмена = СтруктураНастроекОбменаБазовая();
ВыполнитьИнициализациюСтруктурыНастроекОбмена(СтруктураНастроекОбмена, НастройкаВыполненияОбмена, НомерСтроки);
Если СтруктураНастроекОбмена.Отказ Тогда
Возврат СтруктураНастроекОбмена;
КонецЕсли;
УстановитьНастройкиРежимаОтладкиДляСтруктуры(СтруктураНастроекОбмена);
// Проверяем структуру настроек на валидность значений для выполнения обмена. Ошибки фиксируем в ЖР.
ВыполнитьПроверкуСтруктурыОбменаНаВалидность(СтруктураНастроекОбмена);
// Если настройки содержат ошибки, то выходим.
Если СтруктураНастроекОбмена.Отказ Тогда
Возврат СтруктураНастроекОбмена;
КонецЕсли;
// Инициализируем обработку транспорта сообщений обмена.
ВыполнитьИнициализациюОбработкиТранспортаСообщенийОбмена(СтруктураНастроекОбмена);
// Инициализируем обработку обмена данными.
Если СтруктураНастроекОбмена.ЭтоОбменВРИБ Тогда
ВыполнитьИнициализациюОбработкиОбмена(СтруктураНастроекОбмена);
ИначеЕсли СтруктураНастроекОбмена.ОбменПоПравиламКонвертацииОбъектов Тогда
ВыполнитьИнициализациюОбработкиОбменаПоПравиламКонвертации(СтруктураНастроекОбмена);
КонецЕсли;
Возврат СтруктураНастроекОбмена;
КонецФункции
// Получает структуру настроек транспорта для выполнения обмена данными.
//
Функция НастройкиТранспортаОбмена(УзелИнформационнойБазы, ВидТранспортаСообщенийОбмена) Экспорт
// Возвращаемое значение функции.
СтруктураНастроекОбмена = СтруктураНастроекОбменаБазовая();
СтруктураНастроекОбмена.УзелИнформационнойБазы = УзелИнформационнойБазы;
СтруктураНастроекОбмена.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ЗагрузкаДанных;
СтруктураНастроекОбмена.ВидТранспортаОбмена = ВидТранспортаСообщенийОбмена;
ВыполнитьИнициализациюСтруктурыНастроекОбменаДляУзлаИнформационнойБазы(СтруктураНастроекОбмена, Истина);
// Проверяем структуру настроек на валидность значений для выполнения обмена. Ошибки фиксируем в ЖР.
ВыполнитьПроверкуСтруктурыОбменаНаВалидность(СтруктураНастроекОбмена);
// Если настройки содержат ошибки, то выходим.
Если СтруктураНастроекОбмена.Отказ Тогда
Возврат СтруктураНастроекОбмена;
КонецЕсли;
// Инициализируем обработку транспорта сообщений обмена.
ВыполнитьИнициализациюОбработкиТранспортаСообщенийОбмена(СтруктураНастроекОбмена);
Возврат СтруктураНастроекОбмена;
КонецФункции
Функция СтруктураНастроекОбменаДляСеансаИнтерактивнойЗагрузки(Знач УзелИнформационнойБазы, Знач ИмяФайлаСообщенияОбмена) Экспорт
Возврат ОбменДаннымиПовтИсп.СтруктураНастроекОбменаДляСеансаИнтерактивнойЗагрузки(УзелИнформационнойБазы, ИмяФайлаСообщенияОбмена);
КонецФункции
Процедура ВыполнитьИнициализациюСтруктурыНастроекОбмена(СтруктураНастроекОбмена, НастройкаВыполненияОбмена, НомерСтроки)
ТекстЗапроса = "
|ВЫБРАТЬ
| НастройкиВыполненияОбменаНастройкиОбмена.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| НастройкиВыполненияОбменаНастройкиОбмена.УзелИнформационнойБазы.Код КАК УзелИнформационнойБазыКод,
| НастройкиВыполненияОбменаНастройкиОбмена.ВидТранспортаОбмена КАК ВидТранспортаОбмена,
| НастройкиВыполненияОбменаНастройкиОбмена.ВыполняемоеДействие КАК ДействиеПриОбмене,
| НастройкиВыполненияОбменаНастройкиОбмена.Ссылка КАК НастройкаВыполненияОбмена,
| НастройкиВыполненияОбменаНастройкиОбмена.Ссылка.Наименование КАК НастройкаВыполненияОбменаНаименование,
| ВЫБОР
| КОГДА НастройкиВыполненияОбменаНастройкиОбмена.ВыполняемоеДействие = ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ЗагрузкаДанных) ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК ПроизводитьЗагрузкуДанных,
| ВЫБОР
| КОГДА НастройкиВыполненияОбменаНастройкиОбмена.ВыполняемоеДействие = ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ВыгрузкаДанных) ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК ПроизводитьВыгрузкуДанных
|ИЗ
| Справочник.СценарииОбменовДанными.НастройкиОбмена КАК НастройкиВыполненияОбменаНастройкиОбмена
|ГДЕ
| НастройкиВыполненияОбменаНастройкиОбмена.Ссылка = &НастройкаВыполненияОбмена
| И НастройкиВыполненияОбменаНастройкиОбмена.НомерСтроки = &НомерСтроки
|";
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("НастройкаВыполненияОбмена", НастройкаВыполненияОбмена);
Запрос.УстановитьПараметр("НомерСтроки", НомерСтроки);
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
// Заполняем значения свойств структуры.
ЗаполнитьЗначенияСвойств(СтруктураНастроекОбмена, Выборка);
СтруктураНастроекОбмена.ЭтоОбменВРИБ = ОбменДаннымиПовтИсп.ЭтоУзелРаспределеннойИнформационнойБазы(СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации = НСтр("ru = 'Обмен данными'");
// Выполняем проверку задания основных полей структуры настроек обмена.
ВыполнитьПроверкуОсновныхПолейСтруктурыНастроекОбмена(СтруктураНастроекОбмена);
Если СтруктураНастроекОбмена.Отказ Тогда
Возврат;
КонецЕсли;
//
СтруктураНастроекОбмена.ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураНастроекОбмена.ОбменПоПравиламКонвертацииОбъектов = ОбменДаннымиПовтИсп.ЭтоУзелУниверсальногоОбменаДанными(СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураНастроекОбмена.ТекущийУзелПланаОбмена = ПланыОбмена[СтруктураНастроекОбмена.ИмяПланаОбмена].ЭтотУзел();
СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод = СтруктураНастроекОбмена.ТекущийУзелПланаОбмена.Код;
СтруктураНастроекОбмена.ИмяОбработкиТранспортаСообщенийОбмена = ИмяОбработкиТранспортаСообщенийОбмена(СтруктураНастроекОбмена.ВидТранспортаОбмена);
// Получаем ключ сообщения для ЖР.
СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации = КлючСообщенияЖурналаРегистрации(СтруктураНастроекОбмена.УзелИнформационнойБазы, СтруктураНастроекОбмена.ДействиеПриОбмене);
Если ОбменДаннымиПовтИсп.ЭтоУзелОбменаСообщениями(СтруктураНастроекОбмена.УзелИнформационнойБазы) Тогда
МодульНастройкиТранспортаОбменаСообщениями = РегистрыСведений["НастройкиТранспортаОбменаСообщениями"];
СтруктураНастроекОбмена.НастройкиТранспорта = МодульНастройкиТранспортаОбменаСообщениями.НастройкиТранспортаWS(СтруктураНастроекОбмена.УзелИнформационнойБазы);
Иначе
СтруктураНастроекОбмена.НастройкиТранспорта = РегистрыСведений.НастройкиТранспортаОбменаДанными.НастройкиТранспорта(СтруктураНастроекОбмена.УзелИнформационнойБазы, СтруктураНастроекОбмена.ВидТранспортаОбмена);
КонецЕсли;
СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции = КоличествоЭлементовВТранзакцииВыполняемогоДействия(СтруктураНастроекОбмена.ДействиеПриОбмене);
КонецПроцедуры
Процедура ВыполнитьИнициализациюСтруктурыНастроекОбменаДляУзлаИнформационнойБазы(
СтруктураНастроекОбмена,
ИспользоватьНастройкиТранспорта)
СтруктураСвойств = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(СтруктураНастроекОбмена.УзелИнформационнойБазы, "Код, Наименование");
СтруктураНастроекОбмена.УзелИнформационнойБазыКод = ИдентификаторУзлаКорреспондентаДляОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураНастроекОбмена.УзелИнформационнойБазыНаименование = СтруктураСвойств.Наименование;
// Получаем настройки транспорта обмена.
Если ОбменДаннымиПовтИсп.ЭтоУзелОбменаСообщениями(СтруктураНастроекОбмена.УзелИнформационнойБазы) Тогда
МодульНастройкиТранспортаОбменаСообщениями = РегистрыСведений["НастройкиТранспортаОбменаСообщениями"];
СтруктураНастроекОбмена.НастройкиТранспорта = МодульНастройкиТранспортаОбменаСообщениями.НастройкиТранспортаWS(
СтруктураНастроекОбмена.УзелИнформационнойБазы);
Иначе
СтруктураНастроекОбмена.НастройкиТранспорта = РегистрыСведений.НастройкиТранспортаОбменаДанными.НастройкиТранспорта(СтруктураНастроекОбмена.УзелИнформационнойБазы);
КонецЕсли;
Если СтруктураНастроекОбмена.НастройкиТранспорта <> Неопределено Тогда
Если ИспользоватьНастройкиТранспорта Тогда
// Если не указан вид транспорта, то используем значение по умолчанию.
Если СтруктураНастроекОбмена.ВидТранспортаОбмена = Неопределено Тогда
СтруктураНастроекОбмена.ВидТранспортаОбмена = СтруктураНастроекОбмена.НастройкиТранспорта.ВидТранспортаСообщенийОбменаПоУмолчанию;
КонецЕсли;
// Если вид транспорта не задан, то используем транспорт FILE.
Если Не ЗначениеЗаполнено(СтруктураНастроекОбмена.ВидТранспортаОбмена) Тогда
СтруктураНастроекОбмена.ВидТранспортаОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.FILE;
КонецЕсли;
СтруктураНастроекОбмена.ИмяОбработкиТранспортаСообщенийОбмена = ИмяОбработкиТранспортаСообщенийОбмена(СтруктураНастроекОбмена.ВидТранспортаОбмена);
КонецЕсли;
СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции = КоличествоЭлементовВТранзакцииВыполняемогоДействия(СтруктураНастроекОбмена.ДействиеПриОбмене);
Если СтруктураНастроекОбмена.НастройкиТранспорта.Свойство("WSИспользоватьПередачуБольшогоОбъемаДанных") Тогда
СтруктураНастроекОбмена.ИспользоватьПередачуБольшогоОбъемаДанных = СтруктураНастроекОбмена.НастройкиТранспорта.WSИспользоватьПередачуБольшогоОбъемаДанных;
КонецЕсли;
КонецЕсли;
// ЗНАЧЕНИЯ ПО УМОЛЧАНИЮ
СтруктураНастроекОбмена.НастройкаВыполненияОбмена = Неопределено;
СтруктураНастроекОбмена.НастройкаВыполненияОбменаНаименование = "";
// ВЫЧИСЛЯЕМЫЕ ЗНАЧЕНИЯ
СтруктураНастроекОбмена.ПроизводитьЗагрузкуДанных = (СтруктураНастроекОбмена.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
СтруктураНастроекОбмена.ПроизводитьВыгрузкуДанных = (СтруктураНастроекОбмена.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ВыгрузкаДанных);
СтруктураНастроекОбмена.ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураНастроекОбмена.ОбменПоПравиламКонвертацииОбъектов = ОбменДаннымиПовтИсп.ЭтоУзелУниверсальногоОбменаДанными(СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураНастроекОбмена.НаличиеПравилКонвертацииОбязательно = ЗначениеНастройкиПланаОбмена(СтруктураНастроекОбмена.ИмяПланаОбмена, "НаличиеПравилКонвертацииОбязательно");
СтруктураНастроекОбмена.ТекущийУзелПланаОбмена = ПланыОбмена[СтруктураНастроекОбмена.ИмяПланаОбмена].ЭтотУзел();
СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод = ИдентификаторЭтогоУзлаДляОбмена(СтруктураНастроекОбмена.УзелИнформационнойБазы);
// Получаем ключ сообщения для ЖР.
СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации = КлючСообщенияЖурналаРегистрации(СтруктураНастроекОбмена.УзелИнформационнойБазы, СтруктураНастроекОбмена.ДействиеПриОбмене);
КонецПроцедуры
Функция СтруктураНастроекОбменаБазовая()
СтруктураНастроекОбмена = Новый Структура;
// Структура настроек по полям запроса.
СтруктураНастроекОбмена.Вставить("ДатаНачала", ТекущаяДатаСеанса());
СтруктураНастроекОбмена.Вставить("ДатаОкончания");
СтруктураНастроекОбмена.Вставить("НомерСтроки");
СтруктураНастроекОбмена.Вставить("НастройкаВыполненияОбмена");
СтруктураНастроекОбмена.Вставить("НастройкаВыполненияОбменаНаименование");
СтруктураНастроекОбмена.Вставить("УзелИнформационнойБазы");
СтруктураНастроекОбмена.Вставить("УзелИнформационнойБазыКод", "");
СтруктураНастроекОбмена.Вставить("УзелИнформационнойБазыНаименование", "");
СтруктураНастроекОбмена.Вставить("ВидТранспортаОбмена");
СтруктураНастроекОбмена.Вставить("ДействиеПриОбмене");
СтруктураНастроекОбмена.Вставить("КоличествоЭлементовВТранзакции", 1); // На каждый элемент отдельная транзакция.
СтруктураНастроекОбмена.Вставить("ПроизводитьЗагрузкуДанных", Ложь);
СтруктураНастроекОбмена.Вставить("ПроизводитьВыгрузкуДанных", Ложь);
СтруктураНастроекОбмена.Вставить("ИспользоватьПередачуБольшогоОбъемаДанных", Ложь);
// Структура настроек дополнительная.
СтруктураНастроекОбмена.Вставить("Отказ", Ложь);
СтруктураНастроекОбмена.Вставить("ЭтоОбменВРИБ", Ложь);
СтруктураНастроекОбмена.Вставить("ОбработкаОбменаДанными");
СтруктураНастроекОбмена.Вставить("ОбработкаТранспортаСообщенийОбмена");
СтруктураНастроекОбмена.Вставить("ИмяПланаОбмена");
СтруктураНастроекОбмена.Вставить("ТекущийУзелПланаОбмена");
СтруктураНастроекОбмена.Вставить("ТекущийУзелПланаОбменаКод");
СтруктураНастроекОбмена.Вставить("ОбменПоПравиламКонвертацииОбъектов", Ложь);
СтруктураНастроекОбмена.Вставить("НаличиеПравилКонвертацииОбязательно", Истина);
СтруктураНастроекОбмена.Вставить("ИмяОбработкиТранспортаСообщенийОбмена");
СтруктураНастроекОбмена.Вставить("КлючСообщенияЖурналаРегистрации");
СтруктураНастроекОбмена.Вставить("НастройкиТранспорта");
СтруктураНастроекОбмена.Вставить("ПравилаКонвертацииОбъектов");
СтруктураНастроекОбмена.Вставить("ПравилаЗагружены", Ложь);
СтруктураНастроекОбмена.Вставить("ОтладкаОбработчиковВыгрузки ", Ложь);
СтруктураНастроекОбмена.Вставить("ОтладкаОбработчиковЗагрузки", Ложь);
СтруктураНастроекОбмена.Вставить("ИмяФайлаВнешнейОбработкиОтладкиВыгрузки", "");
СтруктураНастроекОбмена.Вставить("ИмяФайлаВнешнейОбработкиОтладкиЗагрузки", "");
СтруктураНастроекОбмена.Вставить("РежимПротоколированияОбменаДанными", Ложь);
СтруктураНастроекОбмена.Вставить("ИмяФайлаПротоколаОбмена", "");
СтруктураНастроекОбмена.Вставить("ПродолжитьПриОшибке", Ложь);
// Структура для передачи произвольных дополнительных параметров.
СтруктураНастроекОбмена.Вставить("ДополнительныеПараметры", Новый Структура);
// Структура для регистрации событий в ЖР.
СтруктураНастроекОбмена.Вставить("РезультатВыполненияОбмена");
СтруктураНастроекОбмена.Вставить("ДействиеПриОбмене");
СтруктураНастроекОбмена.Вставить("КоличествоОбъектовОбработано", 0);
СтруктураНастроекОбмена.Вставить("СообщениеПриОбмене", "");
СтруктураНастроекОбмена.Вставить("СтрокаСообщенияОбОшибке", "");
Возврат СтруктураНастроекОбмена;
КонецФункции
Процедура ВыполнитьПроверкуОсновныхПолейСтруктурыНастроекОбмена(СтруктураНастроекОбмена)
Если НЕ ЗначениеЗаполнено(СтруктураНастроекОбмена.УзелИнформационнойБазы) Тогда
// Узел информационной базы не должен быть пустым.
СтрокаСообщенияОбОшибке = НСтр(
"ru = 'Не задан узел информационной базы, с которой нужно производить обмен информацией. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
ИначеЕсли НЕ ЗначениеЗаполнено(СтруктураНастроекОбмена.ВидТранспортаОбмена) Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Не задан вид транспорта обмена. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
ИначеЕсли НЕ ЗначениеЗаполнено(СтруктураНастроекОбмена.ДействиеПриОбмене) Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Не указано выполняемое действие (выгрузка / загрузка). Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьПроверкуСтруктурыОбменаНаВалидность(СтруктураНастроекОбмена, ИспользоватьНастройкиТранспорта = Истина)
Если НЕ ЗначениеЗаполнено(СтруктураНастроекОбмена.УзелИнформационнойБазы) Тогда
// Узел информационной базы не должен быть пустым.
СтрокаСообщенияОбОшибке = НСтр(
"ru = 'Не задан узел информационной базы, с которой нужно производить обмен информацией. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
ИначеЕсли ИспользоватьНастройкиТранспорта И НЕ ЗначениеЗаполнено(СтруктураНастроекОбмена.ВидТранспортаОбмена) Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Не задан вид транспорта обмена. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
ИначеЕсли НЕ ЗначениеЗаполнено(СтруктураНастроекОбмена.ДействиеПриОбмене) Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Не указано выполняемое действие (выгрузка / загрузка). Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
ИначеЕсли СтруктураНастроекОбмена.УзелИнформационнойБазы.ПометкаУдаления Тогда
// Узел информационной базы не должен быть помечен на удаление.
СтрокаСообщенияОбОшибке = НСтр("ru = 'Узел информационной базы помечен на удаление. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
ИначеЕсли СтруктураНастроекОбмена.УзелИнформационнойБазы = СтруктураНастроекОбмена.ТекущийУзелПланаОбмена Тогда
// Сами с собой не обмениваемся.
СтрокаСообщенияОбОшибке = НСтр(
"ru = 'Нельзя организовать обмен данными с текущим узлом информационной базы. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
ИначеЕсли ПустаяСтрока(СтруктураНастроекОбмена.УзелИнформационнойБазыКод)
ИЛИ ПустаяСтрока(СтруктураНастроекОбмена.ТекущийУзелПланаОбменаКод) Тогда
// У узлов участвующих в обмене должен быть не пустой код.
СтрокаСообщенияОбОшибке = НСтр("ru = 'Один из узлов обмена имеет пустой код. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
ИначеЕсли СтруктураНастроекОбмена.ОтладкаОбработчиковВыгрузки Тогда
ФайлОбработкиВыгрузки = Новый Файл(СтруктураНастроекОбмена.ИмяФайлаВнешнейОбработкиОтладкиВыгрузки);
Если Не ФайлОбработкиВыгрузки.Существует() Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Файл внешней обработки для отладки выгрузки не существует. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
КонецЕсли;
ИначеЕсли СтруктураНастроекОбмена.ОтладкаОбработчиковЗагрузки Тогда
ФайлОбработкиЗагрузки = Новый Файл(СтруктураНастроекОбмена.ИмяФайлаВнешнейОбработкиОтладкиЗагрузки);
Если Не ФайлОбработкиЗагрузки.Существует() Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Файл внешней обработки для отладки загрузки не существует. Обмен отменен.'",
ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьИнициализациюОбработкиОбмена(СтруктураНастроекОбмена)
// Если настройки содержат ошибки, то не производим инициализацию.
Если СтруктураНастроекОбмена.Отказ Тогда
Возврат;
КонецЕсли;
// создание
ОбработкаОбменаДанными = Обработки.КонвертацияОбъектовРаспределенныхИнформационныхБаз.Создать();
// инициализация свойств
ОбработкаОбменаДанными.УзелИнформационнойБазы = СтруктураНастроекОбмена.УзелИнформационнойБазы;
ОбработкаОбменаДанными.КоличествоЭлементовВТранзакции = СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции;
ОбработкаОбменаДанными.КлючСообщенияЖурналаРегистрации = СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации;
СтруктураНастроекОбмена.Вставить("ОбработкаОбменаДанными", ОбработкаОбменаДанными);
КонецПроцедуры
Процедура ВыполнитьИнициализациюОбработкиОбменаПоПравиламКонвертации(СтруктураНастроекОбмена)
Перем ОбработкаОбменаДанными;
// Если настройки содержат ошибки, то не производим инициализацию.
Если СтруктураНастроекОбмена.Отказ Тогда
Возврат;
КонецЕсли;
Если СтруктураНастроекОбмена.ПроизводитьВыгрузкуДанных Тогда
ОбработкаОбменаДанными = ОбработкаОбменаДаннымиДляВыгрузки(СтруктураНастроекОбмена);
ИначеЕсли СтруктураНастроекОбмена.ПроизводитьЗагрузкуДанных Тогда
ОбработкаОбменаДанными = ОбработкаОбменаДаннымиДляЗагрузки(СтруктураНастроекОбмена);
КонецЕсли;
СтруктураНастроекОбмена.Вставить("ОбработкаОбменаДанными", ОбработкаОбменаДанными);
КонецПроцедуры
Процедура ВыполнитьИнициализациюОбработкиТранспортаСообщенийОбмена(СтруктураНастроекОбмена)
Если СтруктураНастроекОбмена.ВидТранспортаОбмена = Перечисления.ВидыТранспортаСообщенийОбмена.ВнешняяСистема Тогда
ВыполнитьИнициализациюОбработкиТранспортаСообщенийОбменаСВнешнейСистемой(СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
// Создаем обработку транспорта.
ОбработкаТранспортаСообщенийОбмена = Обработки[СтруктураНастроекОбмена.ИмяОбработкиТранспортаСообщенийОбмена].Создать();
ЭтоИсходящееСообщение = СтруктураНастроекОбмена.ПроизводитьВыгрузкуДанных;
Транслитерация = Неопределено;
СловарьНастроек = Новый Соответствие;
СловарьНастроек.Вставить(Перечисления.ВидыТранспортаСообщенийОбмена.FILE, "FILEТранслитерироватьИменаФайловСообщенийОбмена");
СловарьНастроек.Вставить(Перечисления.ВидыТранспортаСообщенийОбмена.EMAIL, "EMAILТранслитерироватьИменаФайловСообщенийОбмена");
СловарьНастроек.Вставить(Перечисления.ВидыТранспортаСообщенийОбмена.FTP, "FTPТранслитерироватьИменаФайловСообщенийОбмена");
ИмяСвойстваТранслитерация = СловарьНастроек.Получить(СтруктураНастроекОбмена.ВидТранспортаОбмена);
Если ЗначениеЗаполнено(ИмяСвойстваТранслитерация) Тогда
СтруктураНастроекОбмена.НастройкиТранспорта.Свойство(ИмяСвойстваТранслитерация, Транслитерация);
КонецЕсли;
Транслитерация = ?(Транслитерация = Неопределено, Ложь, Транслитерация);
// Заполняем общие реквизиты, одинаковые для всех обработок транспорта.
ОбработкаТранспортаСообщенийОбмена.ШаблонИмениФайлаСообщения = ШаблонИмениФайлаСообщения(
СтруктураНастроекОбмена.ТекущийУзелПланаОбмена,
СтруктураНастроекОбмена.УзелИнформационнойБазы,
ЭтоИсходящееСообщение,
Транслитерация);
// Заполняем настойки транспорта, различные для каждой обработки транспорта.
ЗаполнитьЗначенияСвойств(ОбработкаТранспортаСообщенийОбмена, СтруктураНастроекОбмена.НастройкиТранспорта);
// Инициализируем транспорт
ОбработкаТранспортаСообщенийОбмена.Инициализация();
СтруктураНастроекОбмена.Вставить("ОбработкаТранспортаСообщенийОбмена", ОбработкаТранспортаСообщенийОбмена);
КонецПроцедуры
Функция ОбработкаОбменаДаннымиДляВыгрузки(СтруктураНастроекОбмена)
МенеджерОбработки = ?(ЭтоПланОбменаXDTO(СтруктураНастроекОбмена.УзелИнформационнойБазы),
Обработки.КонвертацияОбъектовXDTO,
Обработки.КонвертацияОбъектовИнформационныхБаз);
ОбработкаОбменаДанными = МенеджерОбработки.Создать();
ОбработкаОбменаДанными.РежимОбмена = "Выгрузка";
// Если обработка поддерживает механизм правил конвертации.
Если ОбработкаОбменаДанными.Метаданные().Реквизиты.Найти("ИмяФайлаПравилОбмена") <> Неопределено Тогда
УстановитьПравилаОбменаВыгрузкиДанных(ОбработкаОбменаДанными, СтруктураНастроекОбмена);
ОбработкаОбменаДанными.НеВыгружатьОбъектыПоСсылкам = Истина;
ОбработкаОбменаДанными.ИмяФайлаПравилОбмена = "1";
КонецЕсли;
// Если обработка поддерживает механизм фонового обмена.
Если ОбработкаОбменаДанными.Метаданные().Реквизиты.Найти("УзелДляФоновогоОбмена") <> Неопределено Тогда
ОбработкаОбменаДанными.УзелДляФоновогоОбмена = Неопределено;
КонецЕсли;
ОбработкаОбменаДанными.УзелДляОбмена = СтруктураНастроекОбмена.УзелИнформационнойБазы;
УстановитьОбщиеПараметрыДляОбработкиОбменаДанными(ОбработкаОбменаДанными, СтруктураНастроекОбмена);
Возврат ОбработкаОбменаДанными;
КонецФункции
Функция ОбработкаОбменаДаннымиДляЗагрузки(СтруктураНастроекОбмена)
МенеджерОбработки = ?(ЭтоПланОбменаXDTO(СтруктураНастроекОбмена.УзелИнформационнойБазы),
Обработки.КонвертацияОбъектовXDTO,
Обработки.КонвертацияОбъектовИнформационныхБаз);
ОбработкаОбменаДанными = МенеджерОбработки.Создать();
ОбработкаОбменаДанными.РежимОбмена = "Загрузка";
ОбработкаОбменаДанными.УзелОбменаЗагрузкаДанных = СтруктураНастроекОбмена.УзелИнформационнойБазы;
Если ОбработкаОбменаДанными.Метаданные().Реквизиты.Найти("ИмяФайлаПравилОбмена") <> Неопределено Тогда
УстановитьПравилаОбменаЗагрузкиДанных(ОбработкаОбменаДанными, СтруктураНастроекОбмена);
КонецЕсли;
УстановитьОбщиеПараметрыДляОбработкиОбменаДанными(ОбработкаОбменаДанными, СтруктураНастроекОбмена);
Возврат ОбработкаОбменаДанными
КонецФункции
Процедура УстановитьОбщиеПараметрыДляОбработкиОбменаДанными(ОбработкаОбменаДанными, СтруктураНастроекОбмена, ОбменСБСП20 = Ложь)
ОбработкаОбменаДанными.ДописыватьДанныеВПротоколОбмена = Ложь;
ОбработкаОбменаДанными.ВыгружатьТолькоРазрешенные = Ложь;
ОбработкаОбменаДанными.ИспользоватьТранзакции = СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции <> 1;
ОбработкаОбменаДанными.КоличествоОбъектовНаТранзакцию = СтруктураНастроекОбмена.КоличествоЭлементовВТранзакции;
ОбработкаОбменаДанными.КлючСообщенияЖурналаРегистрации = СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации;
Если Не ОбменСБСП20 Тогда
УстановитьНастройкиРежимаОтладкиДляОбработки(ОбработкаОбменаДанными, СтруктураНастроекОбмена);
КонецЕсли;
КонецПроцедуры
Процедура УстановитьПравилаОбменаВыгрузкиДанных(ОбработкаОбменаДаннымиXML, СтруктураНастроекОбмена)
ПравилаКонвертацииОбъектов = РегистрыСведений.ПравилаДляОбменаДанными.ЗачитанныеПравилаКонвертацииОбъектов(СтруктураНастроекОбмена.ИмяПланаОбмена);
Если ПравилаКонвертацииОбъектов = Неопределено Тогда
// Правила обмена должны быть указаны.
СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не заданы правила конвертации для плана обмена %1. Выгрузка данных отменена.'", ОбщегоНазначения.КодОсновногоЯзыка()),
СтруктураНастроекОбмена.ИмяПланаОбмена);
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
ОбработкаОбменаДаннымиXML.СохраненныеНастройки = ПравилаКонвертацииОбъектов;
Попытка
ОбработкаОбменаДаннымиXML.ВосстановитьПравилаИзВнутреннегоФормата();
Исключение
ЗаписьЖурналаРегистрацииОбменаДанными(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
Возврат;
КонецПопытки;
КонецПроцедуры
Процедура УстановитьПравилаОбменаЗагрузкиДанных(ОбработкаОбменаДаннымиXML, СтруктураНастроекОбмена)
ПравилаКонвертацииОбъектов = РегистрыСведений.ПравилаДляОбменаДанными.ЗачитанныеПравилаКонвертацииОбъектов(СтруктураНастроекОбмена.ИмяПланаОбмена, Истина);
Если ПравилаКонвертацииОбъектов = Неопределено Тогда
Если Не СтруктураНастроекОбмена.Свойство("НаличиеПравилКонвертацииОбязательно")
Или СтруктураНастроекОбмена.НаличиеПравилКонвертацииОбязательно = Истина Тогда
// Правила обмена должны быть указаны.
НСтрока = НСтр("ru = 'Не заданы правила конвертации для плана обмена %1. Загрузка данных отменена.'",
ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтрока, СтруктураНастроекОбмена.ИмяПланаОбмена);
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
Возврат;
КонецЕсли;
КонецЕсли;
ОбработкаОбменаДаннымиXML.СохраненныеНастройки = ПравилаКонвертацииОбъектов;
Попытка
ОбработкаОбменаДаннымиXML.ВосстановитьПравилаИзВнутреннегоФормата();
Исключение
ЗаписьЖурналаРегистрацииОбменаДанными(КраткоеПредставлениеОшибки(ИнформацияОбОшибке()), СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена);
Возврат;
КонецПопытки;
КонецПроцедуры
// Считывает настройки отладки из ИБ и устанавливает их для структуры обмена.
//
Процедура УстановитьНастройкиРежимаОтладкиДляСтруктуры(СтруктураНастроекОбмена, ЭтоВнешнееСоединение = Ложь)
ТекстЗапроса = "ВЫБРАТЬ
| ВЫБОР
| КОГДА &ПроизводитьВыгрузку
| ТОГДА ПравилаДляОбменаДанными.РежимОтладкиВыгрузки
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК ОтладкаОбработчиковВыгрузки,
| ВЫБОР
| КОГДА &ПроизводитьВыгрузку
| ТОГДА ПравилаДляОбменаДанными.ИмяФайлаОбработкиДляОтладкиВыгрузки
| ИНАЧЕ """"
| КОНЕЦ КАК ИмяФайлаВнешнейОбработкиОтладкиВыгрузки,
| ВЫБОР
| КОГДА &ПроизводитьЗагрузку
| ТОГДА ПравилаДляОбменаДанными.РежимОтладкиЗагрузки
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК ОтладкаОбработчиковЗагрузки,
| ВЫБОР
| КОГДА &ПроизводитьЗагрузку
| ТОГДА ПравилаДляОбменаДанными.ИмяФайлаОбработкиДляОтладкиЗагрузки
| ИНАЧЕ """"
| КОНЕЦ КАК ИмяФайлаВнешнейОбработкиОтладкиЗагрузки,
| ПравилаДляОбменаДанными.РежимПротоколированияОбменаДанными КАК РежимПротоколированияОбменаДанными,
| ПравилаДляОбменаДанными.ИмяФайлаПротоколаОбмена КАК ИмяФайлаПротоколаОбмена,
| ПравилаДляОбменаДанными.НеОстанавливатьПоОшибке КАК ПродолжитьПриОшибке
|ИЗ
| РегистрСведений.ПравилаДляОбменаДанными КАК ПравилаДляОбменаДанными
|ГДЕ
| ПравилаДляОбменаДанными.ИмяПланаОбмена = &ИмяПланаОбмена
| И ПравилаДляОбменаДанными.ВидПравил = ЗНАЧЕНИЕ(Перечисление.ВидыПравилДляОбменаДанными.ПравилаКонвертацииОбъектов)
| И ПравилаДляОбменаДанными.РежимОтладки";
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
ПроизводитьВыгрузкуДанных = Ложь;
Если Не СтруктураНастроекОбмена.Свойство("ПроизводитьВыгрузкуДанных", ПроизводитьВыгрузкуДанных) Тогда
ПроизводитьВыгрузкуДанных = (СтруктураНастроекОбмена.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ВыгрузкаДанных);
КонецЕсли;
ПроизводитьЗагрузкуДанных = Ложь;
Если Не СтруктураНастроекОбмена.Свойство("ПроизводитьЗагрузкуДанных", ПроизводитьЗагрузкуДанных) Тогда
ПроизводитьЗагрузкуДанных = (СтруктураНастроекОбмена.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
КонецЕсли;
Запрос.УстановитьПараметр("ИмяПланаОбмена", СтруктураНастроекОбмена.ИмяПланаОбмена);
Запрос.УстановитьПараметр("ПроизводитьВыгрузку", ПроизводитьВыгрузкуДанных);
Запрос.УстановитьПараметр("ПроизводитьЗагрузку", ПроизводитьЗагрузкуДанных);
Результат = Запрос.Выполнить();
ИмяФайлаПротокола = "";
Если ЭтоВнешнееСоединение И СтруктураНастроекОбмена.Свойство("ИмяФайлаПротоколаОбмена", ИмяФайлаПротокола)
И Не ПустаяСтрока(ИмяФайлаПротокола) Тогда
СтруктураНастроекОбмена.ИмяФайлаПротоколаОбмена = ДобавитьЛитералКИмениФайла(ИмяФайлаПротокола, "ВнешнееСоединение")
КонецЕсли;
Если Не Результат.Пустой() И Не ОбщегоНазначения.РазделениеВключено() Тогда
ТаблицаНастроек = Результат.Выгрузить();
СтрокаТаблицы = ТаблицаНастроек[0];
ЗаполнитьЗначенияСвойств(СтруктураНастроекОбмена, СтрокаТаблицы);
КонецЕсли;
КонецПроцедуры
// Считывает настройки отладки из ИБ и устанавливает их для структуры настроек обмена.
//
Процедура УстановитьНастройкиРежимаОтладкиДляОбработки(ОбработкаОбменаДанными, СтруктураНастроекОбмена)
Если СтруктураНастроекОбмена.Свойство("ИмяФайлаВнешнейОбработкиОтладкиВыгрузки")
И ОбработкаОбменаДанными.Метаданные().Реквизиты.Найти("ИмяФайлаВнешнейОбработкиОтладкиВыгрузки") <> Неопределено Тогда
ОбработкаОбменаДанными.ОтладкаОбработчиковВыгрузки = СтруктураНастроекОбмена.ОтладкаОбработчиковВыгрузки;
ОбработкаОбменаДанными.ОтладкаОбработчиковЗагрузки = СтруктураНастроекОбмена.ОтладкаОбработчиковЗагрузки;
ОбработкаОбменаДанными.ИмяФайлаВнешнейОбработкиОтладкиВыгрузки = СтруктураНастроекОбмена.ИмяФайлаВнешнейОбработкиОтладкиВыгрузки;
ОбработкаОбменаДанными.ИмяФайлаВнешнейОбработкиОтладкиЗагрузки = СтруктураНастроекОбмена.ИмяФайлаВнешнейОбработкиОтладкиЗагрузки;
ОбработкаОбменаДанными.РежимПротоколированияОбменаДанными = СтруктураНастроекОбмена.РежимПротоколированияОбменаДанными;
ОбработкаОбменаДанными.ИмяФайлаПротоколаОбмена = СтруктураНастроекОбмена.ИмяФайлаПротоколаОбмена;
ОбработкаОбменаДанными.ПродолжитьПриОшибке = СтруктураНастроекОбмена.ПродолжитьПриОшибке;
Если СтруктураНастроекОбмена.РежимПротоколированияОбменаДанными Тогда
Если СтруктураНастроекОбмена.ИмяФайлаПротоколаОбмена = "" Тогда
ОбработкаОбменаДанными.ВыводВОкноСообщенийИнформационныхСообщений = Истина;
ОбработкаОбменаДанными.ВыводВПротоколИнформационныхСообщений = Ложь;
Иначе
ОбработкаОбменаДанными.ВыводВОкноСообщенийИнформационныхСообщений = Ложь;
ОбработкаОбменаДанными.ВыводВПротоколИнформационныхСообщений = Истина;
ОбработкаОбменаДанными.ИмяФайлаПротоколаОбмена = СтруктураНастроекОбмена.ИмяФайлаПротоколаОбмена;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Устанавливает для обработки настройки выгрузки.
//
Процедура УстановитьНастройкиОтладкиВыгрузкиДляПравилОбмена(ОбработкаОбменаДанными, ИмяПланаОбмена, РежимОтладки) Экспорт
ТекстЗапроса = "ВЫБРАТЬ
| ПравилаДляОбменаДанными.РежимОтладкиВыгрузки КАК ОтладкаОбработчиковВыгрузки,
| ПравилаДляОбменаДанными.ИмяФайлаОбработкиДляОтладкиВыгрузки КАК ИмяФайлаВнешнейОбработкиОтладкиВыгрузки
|ИЗ
| РегистрСведений.ПравилаДляОбменаДанными КАК ПравилаДляОбменаДанными
|ГДЕ
| ПравилаДляОбменаДанными.ИмяПланаОбмена = &ИмяПланаОбмена
| И ПравилаДляОбменаДанными.ВидПравил = ЗНАЧЕНИЕ(Перечисление.ВидыПравилДляОбменаДанными.ПравилаКонвертацииОбъектов)
| И &РежимОтладки = ИСТИНА";
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.УстановитьПараметр("ИмяПланаОбмена", ИмяПланаОбмена);
Запрос.УстановитьПараметр("РежимОтладки", РежимОтладки);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Или ОбщегоНазначения.РазделениеВключено() Тогда
ОбработкаОбменаДанными.ОтладкаОбработчиковВыгрузки = Ложь;
ОбработкаОбменаДанными.ИмяФайлаВнешнейОбработкиОтладкиВыгрузки = "";
Иначе
ТаблицаНастроек = Результат.Выгрузить();
НастройкиОтладки = ТаблицаНастроек[0];
ЗаполнитьЗначенияСвойств(ОбработкаОбменаДанными, НастройкиОтладки);
КонецЕсли;
КонецПроцедуры
Процедура ЗафиксироватьЗавершениеИнициализацииОбмена(СтруктураНастроекОбмена)
СтруктураНастроекОбмена.Отказ = Истина;
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Отменено;
КонецПроцедуры
Функция ШаблонИмениФайлаСообщения(ТекущийУзелПланаОбмена, УзелИнформационнойБазы, ЭтоИсходящееСообщение, Транслитерация = Ложь, ИспользоватьВиртуальныйКодУзлаПриПолучении = Ложь) Экспорт
Если ЭтоИсходящееСообщение Тогда
КодОтправителя = ИдентификаторЭтогоУзлаДляОбмена(УзелИнформационнойБазы);
КодПолучателя = ИдентификаторУзлаКорреспондентаДляОбмена(УзелИнформационнойБазы);
Иначе
КодОтправителя = ИдентификаторУзлаКорреспондентаДляОбмена(УзелИнформационнойБазы);
КодПолучателя = ИдентификаторЭтогоУзлаДляОбмена(УзелИнформационнойБазы);
КонецЕсли;
Если ЭтоИсходящееСообщение Или ИспользоватьВиртуальныйКодУзлаПриПолучении Тогда
// Обмен с корреспондентом, который не знаком с новым кодом предопределенного узла -
// при формировании имени файла сообщения обмена вместо кода предопределенного узла используется код из регистра.
ПсевдонимПредопределенногоУзла = ПсевдонимПредопределенногоУзла(УзелИнформационнойБазы);
Если ЗначениеЗаполнено(ПсевдонимПредопределенногоУзла) Тогда
Если ЭтоИсходящееСообщение Тогда
КодОтправителя = ПсевдонимПредопределенногоУзла;
Иначе
КодПолучателя = ПсевдонимПредопределенногоУзла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИмяФайлаСообщения = ИмяФайлаСообщенияОбмена(КодОтправителя, КодПолучателя, ЭтоИсходящееСообщение);
// Учитываем настройку транслитерации для узла плана обмена.
Если Транслитерация Тогда
ИмяФайлаСообщения = СтроковыеФункции.СтрокаЛатиницей(ИмяФайлаСообщения);
КонецЕсли;
Возврат ИмяФайлаСообщения;
КонецФункции
Процедура ВыполнитьИнициализациюОбработкиТранспортаСообщенийОбменаСВнешнейСистемой(СтруктураНастроекОбмена)
Если ОбщегоНазначения.ПодсистемаСуществует("ИнтернетПоддержкаПользователей.ОбменДаннымиСВнешнимиСистемами") Тогда
ОбработкаТранспортаСообщенийОбмена = Обработки[СтруктураНастроекОбмена.ИмяОбработкиТранспортаСообщенийОбмена].Создать();
ПараметрыПодключения = РегистрыСведений.НастройкиТранспортаОбменаДанными.НастройкиТранспортаВнешнейСистемы(
СтруктураНастроекОбмена.УзелИнформационнойБазы);
// Инициализируем транспорт.
ОбработкаТранспортаСообщенийОбмена.Инициализация(ПараметрыПодключения);
СтруктураНастроекОбмена.Вставить("ОбработкаТранспортаСообщенийОбмена", ОбработкаТранспортаСообщенийОбмена);
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область РаботаСМониторомПроблемОбменаДанными
Функция КоличествоПроблемОбменаДанными(УзлыОбмена = Неопределено)
ПараметрыПоискаПроблем = РегистрыСведений.РезультатыОбменаДанными.ПараметрыПоискаПроблем();
ПараметрыПоискаПроблем.УзлыПланаОбмена = УзлыОбмена;
ТипыПроблем = Новый Массив;
ТипыПроблем.Добавить(Перечисления.ТипыПроблемОбменаДанными.НезаполненныеРеквизиты);
ТипыПроблем.Добавить(Перечисления.ТипыПроблемОбменаДанными.НепроведенныйДокумент);
ТипыПроблем.Добавить(Перечисления.ТипыПроблемОбменаДанными.ОшибкаПроверкиСконвертированногоОбъекта);
ПараметрыПоискаПроблем.ТипПроблемы = ТипыПроблем;
Возврат РегистрыСведений.РезультатыОбменаДанными.КоличествоПроблем(ПараметрыПоискаПроблем);
КонецФункции
Функция КоличествоПроблемВерсионирования(УзлыОбмена = Неопределено, Знач ПараметрыЗапроса = Неопределено) Экспорт
Если ПараметрыЗапроса = Неопределено Тогда
ПараметрыЗапроса = ПараметрыЗапросаКоличествоПроблемВерсионирования();
КонецЕсли;
ИспользуетсяВерсионирование = ОбменДаннымиПовтИсп.ИспользуетсяВерсионирование(, Истина);
Если ИспользуетсяВерсионирование Тогда
МодульВерсионированиеОбъектов = ОбщегоНазначения.ОбщийМодуль("ВерсионированиеОбъектов");
Возврат МодульВерсионированиеОбъектов.КоличествоКоллизийИлиНепринятых(
УзлыОбмена,
ПараметрыЗапроса.ЭтоКоличествоКоллизий,
ПараметрыЗапроса.УчитыватьПроигнорированные,
ПараметрыЗапроса.Период,
ПараметрыЗапроса.СтрокаПоиска);
КонецЕсли;
Возврат 0;
КонецФункции
Функция ПараметрыЗапросаКоличествоПроблемВерсионирования() Экспорт
Результат = Новый Структура;
Результат.Вставить("ЭтоКоличествоКоллизий", Неопределено);
Результат.Вставить("УчитыватьПроигнорированные", Ложь);
Результат.Вставить("Период", Неопределено);
Результат.Вставить("СтрокаПоиска", "");
Возврат Результат;
КонецФункции
// Регистрирует ошибки при отложенном проведении документа в мониторе проблем обмена.
//
// Параметры:
// Объект - ДокументОбъект - документ при отложенном проведении которого возникли ошибки.
// УзелОбмена - ПланОбменаСсылка - узел информационной базы из которой получен документ.
// СообщениеОбОшибке - Строка - текст сообщения для журнала регистрации.
// Рекомендуется передавать в качестве этого параметра КраткоеПредставлениеОшибки(ИнформацияОбОшибке()).
// Текст сообщения для отображения в мониторе формируется из системных сообщений пользователю, которые
// были сформированы, но еще не были выведены пользователю. Поэтому рекомендуется, чтобы к моменту вызова
// данного метода в буфере сообщений системы не содержалось сообщений.
// РегистрироватьПроблемыВРезультатахОбмена - Булево - необходимо регистрировать проблемы.
//
// Пример:
// Процедура ПровестиДокументПриЗагрузке(Документ, УзелОбмена)
// Документ.ОбменДанными.Загрузка = Истина;
// Документ.Записать();
// Документ.ОбменДанными.Загрузка = Ложь;
// Отказ = Ложь;
//
// Попытка
// Документ.Записать(РежимЗаписиДокумента.Проведение);
// Исключение
// СообщениеОбОшибке = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
// Отказ = Истина;
// КонецПопытки;
//
// Если Отказ Тогда
// ОбменДаннымиСервер.ЗарегистрироватьОшибкуПроведенияДокумента(Документ, УзелОбмена, СообщениеОбОшибке);
// КонецЕсли;
//
// КонецПроцедуры;
//
Процедура ЗарегистрироватьОшибкуПроведенияДокумента(
Объект,
УзелОбмена,
ТекстИсключения,
РегистрироватьПроблемыВРезультатахОбмена = Истина)
СообщенияПользователю = ПолучитьСообщенияПользователю(Истина);
ТекстСообщения = ТекстИсключения;
Для Каждого Сообщение Из СообщенияПользователю Цикл
Если СтрНайти(Сообщение.Текст, ДлительныеОперации.СообщениеПрогресса()) > 0 Тогда
Продолжить;
КонецЕсли;
ТекстСообщения = ТекстСообщения + ?(ПустаяСтрока(ТекстСообщения), "", Символы.ПС) + Сообщение.Текст;
КонецЦикла;
ТекстСообщения = СокрЛП(ТекстСообщения);
СтрокаСообщения = "";
Если Не ПустаяСтрока(ТекстСообщения) Тогда
СтрокаСообщения = НСтр("ru = 'Не удалось провести документ %1, полученный из другой информационной базы.
|По причине: %2.
|Возможно, не заполнены все реквизиты, обязательные к заполнению.'",
ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
СтрокаСообщения, Строка(Объект), ТекстСообщения);
Иначе
СтрокаСообщения = НСтр("ru = 'Не удалось провести документ %1, полученный из другой информационной базы.
|Возможно, не заполнены все реквизиты, обязательные к заполнению.'",
ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
СтрокаСообщения, Строка(Объект));
КонецЕсли;
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(), УровеньЖурналаРегистрации.Предупреждение,,, СтрокаСообщения);
Если РегистрироватьПроблемыВРезультатахОбмена Тогда
РегистрыСведений.РезультатыОбменаДанными.ЗарегистрироватьОшибкуПроверкиОбъекта(Объект.Ссылка, УзелОбмена,
ТекстСообщения, Перечисления.ТипыПроблемОбменаДанными.НепроведенныйДокумент);
КонецЕсли;
КонецПроцедуры
// Регистрирует ошибки при отложенной записи объекта в мониторе проблем обмена.
//
// Параметры:
// Объект - СправочникОбъект, ДокументОбъект и т.п. - объект, при отложенной записи которого возникли ошибки.
// УзелОбмена - ПланОбменаСсылка - узел информационной базы из которой получен объект.
// СообщениеОбОшибке - Строка - текст сообщения для журнала регистрации.
// Рекомендуется передавать в качестве этого параметра КраткоеПредставлениеОшибки(ИнформацияОбОшибке()).
// Текст сообщения для отображения в мониторе формируется из системных сообщений пользователю, которые
// были сформированы, но еще не были выведены пользователю. Поэтому рекомендуется, чтобы к моменту вызова
// данного метода в буфере сообщений системы не содержалось сообщений.
//
// Пример:
// Процедура ЗаписатьОбъектПриЗагрузке(Объект, УзелОбмена)
// Объект.ОбменДанными.Загрузка = Истина;
// Объект.Записать();
// Объект.ОбменДанными.Загрузка = Ложь;
// Отказ = Ложь;
//
// Попытка
// Объект.Записать();
// Исключение
// СообщениеОбОшибке = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
// Отказ = Истина;
// КонецПопытки;
//
// Если Отказ Тогда
// ОбменДаннымиСервер.ЗарегистрироватьОшибкуЗаписиОбъекта(Объект, УзелОбмена, СообщениеОбОшибке);
// КонецЕсли;
//
// КонецПроцедуры;
//
Процедура ЗарегистрироватьОшибкуЗаписиОбъекта(
Объект,
УзелОбмена,
ТекстИсключения)
СообщенияПользователю = ПолучитьСообщенияПользователю(Истина);
ТекстСообщения = ТекстИсключения;
Для Каждого Сообщение Из СообщенияПользователю Цикл
Если СтрНайти(Сообщение.Текст, ДлительныеОперации.СообщениеПрогресса()) > 0 Тогда
Продолжить;
КонецЕсли;
ТекстСообщения = ТекстСообщения + ?(ПустаяСтрока(ТекстСообщения), "", Символы.ПС) + Сообщение.Текст;
КонецЦикла;
ПричинаОшибки = ТекстСообщения;
Если Не ПустаяСтрока(СокрЛП(ТекстСообщения)) Тогда
ПричинаОшибки = " " + НСтр("ru = 'По причине %1.'");
ПричинаОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ПричинаОшибки, ТекстСообщения);
КонецЕсли;
СтрокаСообщения = НСтр("ru = 'Не удалось записать объект %1, полученный из другой информационной базы.%2
|Возможно не заполнены все реквизиты, обязательные к заполнению.'",
ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, Строка(Объект), ПричинаОшибки);
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(), УровеньЖурналаРегистрации.Предупреждение,,, СтрокаСообщения);
РегистрыСведений.РезультатыОбменаДанными.ЗарегистрироватьОшибкуПроверкиОбъекта(Объект.Ссылка, УзелОбмена,
ТекстСообщения, Перечисления.ТипыПроблемОбменаДанными.НезаполненныеРеквизиты);
КонецПроцедуры
#КонецОбласти
#Область ПрогрессБар
// Подсчет количества объектов ИБ, подлежащих выгрузке при создании начального образа.
//
// Параметры:
// Получатель - ПланОбменаОбъект - узел плана обмена, соответствующий получателю.
//
// Возвращаемое значение:
// Число
//
Функция РассчитатьКоличествоОбъектовВБазе(Получатель)
ИмяПланаОбмена = Получатель.Метаданные().Имя;
СчетчикОбъектов = 0;
СоставПланаОбмена = Метаданные.ПланыОбмена[ИмяПланаОбмена].Состав;
// 1. "Ссылочные" объекты.
СтруктураСсылочныхОбъектов = Новый Структура;
СтруктураСсылочныхОбъектов.Вставить("Справочник", Метаданные.Справочники);
СтруктураСсылочныхОбъектов.Вставить("Документ", Метаданные.Документы);
СтруктураСсылочныхОбъектов.Вставить("ПланВидовХарактеристик", Метаданные.ПланыВидовХарактеристик);
СтруктураСсылочныхОбъектов.Вставить("ПланВидовРасчета", Метаданные.ПланыВидовРасчета);
СтруктураСсылочныхОбъектов.Вставить("ПланСчетов", Метаданные.ПланыСчетов);
СтруктураСсылочныхОбъектов.Вставить("БизнесПроцесс", Метаданные.БизнесПроцессы);
СтруктураСсылочныхОбъектов.Вставить("Задача", Метаданные.Задачи);
СтруктураСсылочныхОбъектов.Вставить("ПланСчетов", Метаданные.ПланыСчетов);
ШаблонТекстаЗапросаСсылки =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(ПсевдонимТаблицыМетаданных.Ссылка) КАК КоличествоОбъектов
|ИЗ
| &ИмяТаблицыМетаданных КАК ПсевдонимТаблицыМетаданных";
Для Каждого СсылочныйОбъект Из СтруктураСсылочныхОбъектов Цикл
Для Каждого ОбъектМетаданных Из СсылочныйОбъект.Значение Цикл
Если СоставПланаОбмена.Найти(ОбъектМетаданных) = Неопределено Тогда
Продолжить;
КонецЕсли;
ПолноеИмяОбъекта = СсылочныйОбъект.Ключ + "." + ОбъектМетаданных.Имя;
ТекстЗапроса = СтрЗаменить(ШаблонТекстаЗапросаСсылки, "&ИмяТаблицыМетаданных", ПолноеИмяОбъекта);
Запрос = Новый Запрос(ТекстЗапроса);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
СчетчикОбъектов = СчетчикОбъектов + Выборка.КоличествоОбъектов;
КонецЕсли;
КонецЦикла;
КонецЦикла;
// 2. Константы.
Для Каждого ОбъектМетаданных Из Метаданные.Константы Цикл
Если СоставПланаОбмена.Найти(ОбъектМетаданных) = Неопределено Тогда
Продолжить;
КонецЕсли;
СчетчикОбъектов = СчетчикОбъектов + 1;
КонецЦикла;
// 3. Регистры сведений.
ШаблонТекстаЗапросаБезРегистратора =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(*) КАК КоличествоОбъектов
|ИЗ
| &ИмяТаблицыМетаданных КАК ПсевдонимТаблицыМетаданных";
ШаблонТекстаЗапросаСРегистратором =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ПсевдонимТаблицыМетаданных.Регистратор) КАК КоличествоОбъектов
|ИЗ
| &ИмяТаблицыМетаданных КАК ПсевдонимТаблицыМетаданных";
Для Каждого ОбъектМетаданных Из Метаданные.РегистрыСведений Цикл
Если СоставПланаОбмена.Найти(ОбъектМетаданных) = Неопределено Тогда
Продолжить;
КонецЕсли;
ПолноеИмяОбъекта = "РегистрСведений."+ОбъектМетаданных.Имя;
Если ОбъектМетаданных.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.ПозицияРегистратора Тогда
ТекстЗапроса = СтрЗаменить(ШаблонТекстаЗапросаСРегистратором, "&ИмяТаблицыМетаданных", ПолноеИмяОбъекта);
Иначе
ТекстЗапроса = СтрЗаменить(ШаблонТекстаЗапросаБезРегистратора, "&ИмяТаблицыМетаданных", ПолноеИмяОбъекта);
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
СчетчикОбъектов = СчетчикОбъектов + Выборка.КоличествоОбъектов;
КонецЕсли;
КонецЦикла;
// 4. Регистры (подчиненные регистратору) и последовательности.
СтруктураРегистров = Новый Структура;
СтруктураРегистров.Вставить("РегистрНакопления", Метаданные.РегистрыНакопления);
СтруктураРегистров.Вставить("РегистрРасчета", Метаданные.РегистрыРасчета);
СтруктураРегистров.Вставить("РегистрБухгалтерии", Метаданные.РегистрыБухгалтерии);
СтруктураРегистров.Вставить("Последовательность", Метаданные.Последовательности);
Для Каждого Регистр Из СтруктураРегистров Цикл
Для Каждого ОбъектМетаданных Из Регистр.Значение Цикл
Если СоставПланаОбмена.Найти(ОбъектМетаданных) = Неопределено Тогда
Продолжить;
КонецЕсли;
ПолноеИмяОбъекта = Регистр.Ключ +"."+ОбъектМетаданных.Имя;
ТекстЗапроса = СтрЗаменить(ШаблонТекстаЗапросаСРегистратором, "&ИмяТаблицыМетаданных", ПолноеИмяОбъекта);
Запрос = Новый Запрос(ТекстЗапроса);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
СчетчикОбъектов = СчетчикОбъектов + Выборка.КоличествоОбъектов;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат СчетчикОбъектов;
КонецФункции
// Подсчет количества объектов, зарегистрированных в плане обмена.
//
// Параметры:
// Получатель - ПланОбменаОбъект
//
// Возвращаемое значение:
// Число
//
Функция РассчитатьКоличествоЗарегистрированныхОбъектов(Получатель) Экспорт
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(Получатель.Ссылка, Получатель.НомерОтправленного + 1);
КоличествоОбъектовКВыгрузке = 0;
Пока ВыборкаИзменений.Следующий() Цикл
КоличествоОбъектовКВыгрузке = КоличествоОбъектовКВыгрузке + 1;
КонецЦикла;
Возврат КоличествоОбъектовКВыгрузке;
КонецФункции
#КонецОбласти
#Область ОбщегоНазначения
Функция ДополнительныеСвойстваПланаОбменаСтрокой(Знач СвойстваСтрокой)
Результат = "";
Шаблон = "ПланыОбмена.[СвойствоСтрокой] КАК [СвойствоСтрокой]";
СвойстваМассив = СтрРазделить(СвойстваСтрокой, ",", Ложь);
Для Каждого СвойствоСтрокой Из СвойстваМассив Цикл
СвойствоСтрокойВЗапросе = СтрЗаменить(Шаблон, "[СвойствоСтрокой]", СвойствоСтрокой);
Результат = Результат + СвойствоСтрокойВЗапросе + ", ";
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ФильтрПлановОбменаПоПризнакуРазделенияДанных(ПланыОбменаМассив)
Результат = Новый Массив;
Если ОбщегоНазначения.РазделениеВключено() Тогда
Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
Для Каждого ИмяПланаОбмена Из ПланыОбменаМассив Цикл
Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
ЭтоРазделенныйОбъектМетаданных = МодульРаботаВМоделиСервиса.ЭтоРазделенныйОбъектМетаданных("ПланОбмена." + ИмяПланаОбмена);
Иначе
ЭтоРазделенныйОбъектМетаданных = Ложь;
КонецЕсли;
Если ЭтоРазделенныйОбъектМетаданных Тогда
Результат.Добавить(ИмяПланаОбмена);
КонецЕсли;
КонецЦикла;
Иначе
Для Каждого ИмяПланаОбмена Из ПланыОбменаМассив Цикл
Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
ЭтоРазделенныйОбъектМетаданных = МодульРаботаВМоделиСервиса.ЭтоРазделенныйОбъектМетаданных("ПланОбмена." + ИмяПланаОбмена);
Иначе
ЭтоРазделенныйОбъектМетаданных = Ложь;
КонецЕсли;
Если Не ЭтоРазделенныйОбъектМетаданных Тогда
Результат.Добавить(ИмяПланаОбмена);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Иначе
Для Каждого ИмяПланаОбмена Из ПланыОбменаМассив Цикл
Результат.Добавить(ИмяПланаОбмена);
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ФильтрПлановОбменаПоПризнакуАвтономнойРаботы(ПланыОбменаМассив)
Результат = Новый Массив;
Для Каждого ИмяПланаОбмена Из ПланыОбменаМассив Цикл
Если ИмяПланаОбмена <> ОбменДаннымиПовтИсп.ПланОбменаАвтономнойРаботы() Тогда
Результат.Добавить(ИмяПланаОбмена);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Процедура удаляет неактуальные записи в регистре сведений.
// Запись считается неактуальной, если план обмена, для которого была создана запись,
// был переименован или удален.
//
// Параметры:
// Нет.
//
Процедура УдалитьНеактуальныеЗаписиВРегистреПравилДляОбменаДанными()
Запрос = Новый Запрос(
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ПравилаДляОбменаДанными.ИмяПланаОбмена КАК ИмяПланаОбмена
|ИЗ
| РегистрСведений.ПравилаДляОбменаДанными КАК ПравилаДляОбменаДанными
|ГДЕ
| НЕ ПравилаДляОбменаДанными.ИмяПланаОбмена В (&ПланыОбменаБСП)");
Запрос.УстановитьПараметр("ПланыОбменаБСП", ОбменДаннымиПовтИсп.ПланыОбменаБСП());
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
НаборЗаписей = ОбменДаннымиСлужебный.СоздатьНаборЗаписейРегистраСведений(Новый Структура("ИмяПланаОбмена", Выборка.ИмяПланаОбмена),
"ПравилаДляОбменаДанными");
НаборЗаписей.Записать();
КонецЦикла;
КонецПроцедуры
Процедура ПолучитьПланыОбменаДляМонитора(МенеджерВременныхТаблиц, ПланыОбменаМассив, Знач ДополнительныеСвойстваПланаОбмена)
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
// Логика по формированию запроса вынесена в отдельную функцию.
ПараметрыЗапроса = ПараметрыЗапросаПланыОбменаДляМонитора();
ПараметрыЗапроса.ПланыОбменаМассив = ПланыОбменаМассив;
ПараметрыЗапроса.ДополнительныеСвойстваПланаОбмена = ДополнительныеСвойстваПланаОбмена;
ПараметрыЗапроса.РезультатВоВременнуюТаблицу = Истина;
Запрос.Текст = ТекстЗапросаПланыОбменаДляМонитора(ПараметрыЗапроса);
Запрос.Выполнить();
КонецПроцедуры
// Функция для объявления структуры параметров функции ТекстЗапросаПланыОбменаДляМонитора.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Структура.
//
Функция ПараметрыЗапросаПланыОбменаДляМонитора()
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("ПланыОбменаМассив", Новый Массив);
ПараметрыЗапроса.Вставить("ДополнительныеСвойстваПланаОбмена", "");
ПараметрыЗапроса.Вставить("РезультатВоВременнуюТаблицу", Ложь);
Возврат ПараметрыЗапроса;
КонецФункции
// Возвращает текст запроса для получения данных узлов планов обмена.
//
// Параметры:
// ПараметрыЗапроса - см. ПараметрыЗапросаПланыОбменаДляМонитора
// ИсключитьПланыОбменаАвтономнойРаботы - Булево - если Истина, то из текста запроса исключаются планы обмена
// автономной работы.
//
// Возвращаемое значение:
// Строка - результирующий текст запроса.
//
Функция ТекстЗапросаПланыОбменаДляМонитора(ПараметрыЗапроса = Неопределено, ИсключитьПланыОбменаАвтономнойРаботы = Истина) Экспорт
Если ПараметрыЗапроса = Неопределено Тогда
ПараметрыЗапроса = ПараметрыЗапросаПланыОбменаДляМонитора();
КонецЕсли;
ПланыОбменаМассив = ПараметрыЗапроса.ПланыОбменаМассив;
ДополнительныеСвойстваПланаОбмена = ПараметрыЗапроса.ДополнительныеСвойстваПланаОбмена;
РезультатВоВременнуюТаблицу = ПараметрыЗапроса.РезультатВоВременнуюТаблицу;
Если Не ЗначениеЗаполнено(ПланыОбменаМассив) Тогда
ПланыОбменаМассив = ОбменДаннымиПовтИсп.ПланыОбменаБСП();
КонецЕсли;
ПланыОбменаМетода = ФильтрПлановОбменаПоПризнакуРазделенияДанных(ПланыОбменаМассив);
Если ОбменДаннымиПовтИсп.АвтономнаяРаботаПоддерживается()
И ИсключитьПланыОбменаАвтономнойРаботы Тогда
// Для плана обмена автономной работы используется отдельный монитор.
ПланыОбменаМетода = ФильтрПлановОбменаПоПризнакуАвтономнойРаботы(ПланыОбменаМетода);
КонецЕсли;
ДополнительныеСвойстваПланаОбменаСтрокой = ?(ПустаяСтрока(ДополнительныеСвойстваПланаОбмена), "", ДополнительныеСвойстваПланаОбмена + ", ");
СекцияОбъединения = "
|
|ОБЪЕДИНИТЬ ВСЕ
|";
ШаблонЗапроса = СекцияОбъединения +
"//////////////////////////////////////////////////////// {&ИмяТаблицыПланаОбмена}
|ВЫБРАТЬ
|
| &ДополнительныеСвойстваПланаОбмена,
|
| Ссылка КАК УзелИнформационнойБазы,
| Наименование КАК Наименование,
| ""&ИмяПланаОбменаСиноним"" КАК ИмяПланаОбмена
|ИЗ
| &ИмяТаблицыПланаОбмена
|ГДЕ
| НЕ ЭтотУзел
| И НЕ ПометкаУдаления
|";
ТекстЗапроса = "";
Если ПланыОбменаМетода.Количество() > 0 Тогда
ШаблонИмениТаблицыПланаОбмена = "ПланОбмена.%1";
Для Каждого ИмяПланаОбмена Из ПланыОбменаМетода Цикл
ИмяТаблицыПланаОбмена = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонИмениТаблицыПланаОбмена, ИмяПланаОбмена);
ТекстЗапросаДляПланаОбмена = СтрЗаменить(ШаблонЗапроса, "&ИмяТаблицыПланаОбмена", ИмяТаблицыПланаОбмена);
ТекстЗапросаДляПланаОбмена = СтрЗаменить(ТекстЗапросаДляПланаОбмена, "&ИмяПланаОбменаСиноним", Метаданные.ПланыОбмена[ИмяПланаОбмена].Синоним);
ТекстЗапросаДляПланаОбмена = СтрЗаменить(ТекстЗапросаДляПланаОбмена, "&ДополнительныеСвойстваПланаОбмена,", ДополнительныеСвойстваПланаОбменаСтрокой);
// Удаляем литерал объединения для первой таблицы.
Если ПустаяСтрока(ТекстЗапроса) Тогда
ТекстЗапросаДляПланаОбмена = СтрЗаменить(ТекстЗапросаДляПланаОбмена, "ОБЪЕДИНИТЬ ВСЕ", "");
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + ТекстЗапросаДляПланаОбмена;
КонецЦикла;
Иначе
ДополнительныеСвойстваБезИсточникаДанныхСтрокой = "";
Если Не ПустаяСтрока(ДополнительныеСвойстваПланаОбмена) Тогда
ДополнительныеСвойства = СтрРазделить(ДополнительныеСвойстваПланаОбмена, ",");
ДополнительныеСвойстваБезИсточникаДанных = Новый Массив;
Для Каждого Свойство Из ДополнительныеСвойства Цикл
ДополнительныеСвойстваБезИсточникаДанных.Добавить(СтрЗаменить("Неопределено КАК [Свойство]", "[Свойство]", Свойство));
КонецЦикла;
ДополнительныеСвойстваБезИсточникаДанныхСтрокой = СтрСоединить(ДополнительныеСвойстваБезИсточникаДанных, ",") + ", ";
КонецЕсли;
ТекстЗапроса = "
|ВЫБРАТЬ
|
| &ДополнительныеСвойстваБезИсточникаДанныхСтрокой,
|
| Неопределено КАК УзелИнформационнойБазы,
| Неопределено КАК Наименование,
| Неопределено КАК ИмяПланаОбмена
|";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ДополнительныеСвойстваБезИсточникаДанныхСтрокой,", ДополнительныеСвойстваБезИсточникаДанныхСтрокой);
КонецЕсли;
ТекстЗапросаРезультат = "
|//////////////////////////////////////////////////////// {ПланыОбменаКонфигурации}
|ВЫБРАТЬ
|
| &ДополнительныеСвойстваПланаОбмена,
|
| УзелИнформационнойБазы,
| Наименование,
| ИмяПланаОбмена
|ПОМЕСТИТЬ ПланыОбменаКонфигурации
|ИЗ
| &ТекстЗапроса КАК ВложенныйЗапрос
|;
|";
Если РезультатВоВременнуюТаблицу <> Истина Тогда
ТекстЗапросаРезультат = СтрЗаменить(ТекстЗапросаРезультат, "ПОМЕСТИТЬ ПланыОбменаКонфигурации", "");
КонецЕсли;
ОбернутыйТекстЗапроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("(%1)", ТекстЗапроса);
ТекстЗапросаРезультат = СтрЗаменить(ТекстЗапросаРезультат, "&ТекстЗапроса", ОбернутыйТекстЗапроса);
ТекстЗапросаРезультат = СтрЗаменить(ТекстЗапросаРезультат, "&ДополнительныеСвойстваПланаОбмена,", ДополнительныеСвойстваПланаОбменаСтрокой);
Возврат ТекстЗапросаРезультат;
КонецФункции
Процедура ПолучитьСостоянияОбменовДанными(МенеджерВременныхТаблиц)
Если ОбщегоНазначения.РазделениеВключено()
И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных()
И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса") Тогда
МодульОбменДаннымиВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиВМоделиСервиса");
МодульОбменДаннымиВМоделиСервиса.ПолучитьСостоянияОбменовДанными(МенеджерВременныхТаблиц);
Иначе
Запрос = Новый Запрос(
"ВЫБРАТЬ
| СостоянияОбменовДанными.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| СостоянияОбменовДанными.ДатаНачала КАК ДатаНачала,
| СостоянияОбменовДанными.ДатаОкончания КАК ДатаОкончания,
| ВЫБОР
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Предупреждение_СообщениеОбменаБылоРанееПринято)
| ИЛИ СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями)
| ТОГДА 2
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Выполнено)
| ТОГДА ВЫБОР
| КОГДА ЕСТЬNULL(КоличествоПроблем.Количество, 0) > 0
| ТОГДА 2
| ИНАЧЕ 0
| КОНЕЦ
| ИНАЧЕ 1
| КОНЕЦ КАК РезультатВыполненияОбмена
|ПОМЕСТИТЬ СостоянияОбменовДаннымиЗагрузка
|ИЗ
| РегистрСведений.СостоянияОбменовДанными КАК СостоянияОбменовДанными
| ЛЕВОЕ СОЕДИНЕНИЕ КоличествоПроблем КАК КоличествоПроблем
| ПО СостоянияОбменовДанными.УзелИнформационнойБазы = КоличествоПроблем.УзелИнформационнойБазы
| И СостоянияОбменовДанными.ДействиеПриОбмене = КоличествоПроблем.ДействиеПриОбмене
|ГДЕ
| СостоянияОбменовДанными.ДействиеПриОбмене = ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ЗагрузкаДанных)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| СостоянияОбменовДанными.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| СостоянияОбменовДанными.ДатаНачала КАК ДатаНачала,
| СостоянияОбменовДанными.ДатаОкончания КАК ДатаОкончания,
| ВЫБОР
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями)
| ТОГДА 2
| КОГДА СостоянияОбменовДанными.РезультатВыполненияОбмена = ЗНАЧЕНИЕ(Перечисление.РезультатыВыполненияОбмена.Выполнено)
| ТОГДА ВЫБОР
| КОГДА ЕСТЬNULL(КоличествоПроблем.Количество, 0) > 0
| ТОГДА 2
| ИНАЧЕ 0
| КОНЕЦ
| ИНАЧЕ 1
| КОНЕЦ КАК РезультатВыполненияОбмена
|ПОМЕСТИТЬ СостоянияОбменовДаннымиВыгрузка
|ИЗ
| РегистрСведений.СостоянияОбменовДанными КАК СостоянияОбменовДанными
| ЛЕВОЕ СОЕДИНЕНИЕ КоличествоПроблем КАК КоличествоПроблем
| ПО СостоянияОбменовДанными.УзелИнформационнойБазы = КоличествоПроблем.УзелИнформационнойБазы
| И СостоянияОбменовДанными.ДействиеПриОбмене = КоличествоПроблем.ДействиеПриОбмене
|ГДЕ
| СостоянияОбменовДанными.ДействиеПриОбмене = ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ВыгрузкаДанных)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| СостоянияУспешныхОбменовДанными.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| СостоянияУспешныхОбменовДанными.ДатаОкончания КАК ДатаОкончания
|ПОМЕСТИТЬ СостоянияУспешныхОбменовДаннымиЗагрузка
|ИЗ
| РегистрСведений.СостоянияУспешныхОбменовДанными КАК СостоянияУспешныхОбменовДанными
|ГДЕ
| СостоянияУспешныхОбменовДанными.ДействиеПриОбмене = ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ЗагрузкаДанных)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| СостоянияУспешныхОбменовДанными.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| СостоянияУспешныхОбменовДанными.ДатаОкончания КАК ДатаОкончания
|ПОМЕСТИТЬ СостоянияУспешныхОбменовДаннымиВыгрузка
|ИЗ
| РегистрСведений.СостоянияУспешныхОбменовДанными КАК СостоянияУспешныхОбменовДанными
|ГДЕ
| СостоянияУспешныхОбменовДанными.ДействиеПриОбмене = ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ВыгрузкаДанных)");
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.Выполнить();
КонецЕсли;
КонецПроцедуры
Процедура ПолучитьРезультатыОбменаДляМонитора(МенеджерВременныхТаблиц)
Запрос = Новый Запрос;
Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
ТекстЗапросаРезультат =
"ВЫБРАТЬ
| РезультатыОбменаДанными.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| ВЫБОР
| КОГДА РезультатыОбменаДанными.ТипПроблемы В (ЗНАЧЕНИЕ(Перечисление.ТипыПроблемОбменаДанными.НепроведенныйДокумент), ЗНАЧЕНИЕ(Перечисление.ТипыПроблемОбменаДанными.НезаполненныеРеквизиты), ЗНАЧЕНИЕ(Перечисление.ТипыПроблемОбменаДанными.ОшибкаВыполненияКодаОбработчиковПриПолученииДанных))
| ТОГДА ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ЗагрузкаДанных)
| КОГДА РезультатыОбменаДанными.ТипПроблемы В (ЗНАЧЕНИЕ(Перечисление.ТипыПроблемОбменаДанными.ОшибкаВыполненияКодаОбработчиковПриОтправкеДанных), ЗНАЧЕНИЕ(Перечисление.ТипыПроблемОбменаДанными.ОшибкаПроверкиСконвертированногоОбъекта))
| ТОГДА ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ВыгрузкаДанных)
| ИНАЧЕ НЕОПРЕДЕЛЕНО
| КОНЕЦ КАК ДействиеПриОбмене,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ РезультатыОбменаДанными.ПроблемныйОбъект) КАК Количество
|ПОМЕСТИТЬ КоличествоПроблем
|ИЗ
| РегистрСведений.РезультатыОбменаДанными КАК РезультатыОбменаДанными
|ГДЕ
| РезультатыОбменаДанными.Пропущена = ЛОЖЬ
|
|СГРУППИРОВАТЬ ПО
| РезультатыОбменаДанными.УзелИнформационнойБазы,
| ВЫБОР
| КОГДА РезультатыОбменаДанными.ТипПроблемы В (ЗНАЧЕНИЕ(Перечисление.ТипыПроблемОбменаДанными.НепроведенныйДокумент), ЗНАЧЕНИЕ(Перечисление.ТипыПроблемОбменаДанными.НезаполненныеРеквизиты), ЗНАЧЕНИЕ(Перечисление.ТипыПроблемОбменаДанными.ОшибкаВыполненияКодаОбработчиковПриПолученииДанных))
| ТОГДА ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ЗагрузкаДанных)
| КОГДА РезультатыОбменаДанными.ТипПроблемы В (ЗНАЧЕНИЕ(Перечисление.ТипыПроблемОбменаДанными.ОшибкаВыполненияКодаОбработчиковПриОтправкеДанных), ЗНАЧЕНИЕ(Перечисление.ТипыПроблемОбменаДанными.ОшибкаПроверкиСконвертированногоОбъекта))
| ТОГДА ЗНАЧЕНИЕ(Перечисление.ДействияПриОбмене.ВыгрузкаДанных)
| ИНАЧЕ НЕОПРЕДЕЛЕНО
| КОНЕЦ";
Иначе
ТекстЗапросаРезультат =
"ВЫБРАТЬ
| НЕОПРЕДЕЛЕНО КАК УзелИнформационнойБазы,
| НЕОПРЕДЕЛЕНО КАК ДействиеПриОбмене,
| НЕОПРЕДЕЛЕНО КАК Количество
|ПОМЕСТИТЬ КоличествоПроблем";
КонецЕсли;
Запрос.Текст = ТекстЗапросаРезультат;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.Выполнить();
КонецПроцедуры
Процедура ПолучитьСообщенияДляСопоставленияДанных(МенеджерВременныхТаблиц)
Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
Если ОбщегоНазначения.РазделениеВключено()
И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса") Тогда
МодульОбменДаннымиВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиВМоделиСервиса");
МодульОбменДаннымиВМоделиСервиса.ПолучитьСообщенияДляСопоставленияДанных(МенеджерВременныхТаблиц);
Иначе
Запрос = Новый Запрос(
"ВЫБРАТЬ
| ОбщиеНастройкиУзловИнформационныхБаз.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| ВЫБОР
| КОГДА КОЛИЧЕСТВО(ОбщиеНастройкиУзловИнформационныхБаз.СообщениеДляСопоставленияДанных) > 0
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ КАК ПолученоСообщениеДляСопоставленияДанных,
| МАКСИМУМ(СообщенияОбменаДанными.ДатаЗакладкиСообщения) КАК ДатаЗакладкиПоследнегоСообщения
|ПОМЕСТИТЬ СообщенияДляСопоставленияДанных
|ИЗ
| РегистрСведений.ОбщиеНастройкиУзловИнформационныхБаз КАК ОбщиеНастройкиУзловИнформационныхБаз
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СообщенияОбменаДанными КАК СообщенияОбменаДанными
| ПО (СообщенияОбменаДанными.ИдентификаторСообщения = ОбщиеНастройкиУзловИнформационныхБаз.СообщениеДляСопоставленияДанных)
|
|СГРУППИРОВАТЬ ПО
| ОбщиеНастройкиУзловИнформационныхБаз.УзелИнформационнойБазы");
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.Выполнить();
КонецЕсли;
Иначе
Запрос = Новый Запрос(
"ВЫБРАТЬ
| NULL КАК УзелИнформационнойБазы,
| NULL КАК ПолученоСообщениеДляСопоставленияДанных,
| NULL КАК ДатаЗакладкиПоследнегоСообщения
|ПОМЕСТИТЬ СообщенияДляСопоставленияДанных");
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.Выполнить();
КонецЕсли;
КонецПроцедуры
Процедура ПолучитьОбщиеНастройкиУзловИнформационныхБаз(МенеджерВременныхТаблиц)
Запрос = Новый Запрос;
Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
ТекстЗапросаРезультат =
"ВЫБРАТЬ
| ОбщиеНастройкиУзловИнформационныхБаз.УзелИнформационнойБазы КАК УзелИнформационнойБазы,
| ЕСТЬNULL(ОбщиеНастройкиУзловИнформационныхБаз.ВерсияКорреспондента, """") КАК ВерсияКорреспондента,
| ЕСТЬNULL(ОбщиеНастройкиУзловИнформационныхБаз.ПрефиксКорреспондента, """") КАК ПрефиксКорреспондента,
| ЕСТЬNULL(ОбщиеНастройкиУзловИнформационныхБаз.НастройкаЗавершена, ЛОЖЬ) КАК НастройкаЗавершена
|ПОМЕСТИТЬ ОбщиеНастройкиУзловИнформационныхБаз
|ИЗ
| РегистрСведений.ОбщиеНастройкиУзловИнформационныхБаз КАК ОбщиеНастройкиУзловИнформационныхБаз";
Иначе
ТекстЗапросаРезультат =
"ВЫБРАТЬ
| NULL КАК УзелИнформационнойБазы,
| """" КАК ВерсияКорреспондента,
| """" КАК ПрефиксКорреспондента,
| ЛОЖЬ КАК НастройкаЗавершена
|ПОМЕСТИТЬ ОбщиеНастройкиУзловИнформационныхБаз";
КонецЕсли;
Запрос.Текст = ТекстЗапросаРезультат;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.Выполнить();
КонецПроцедуры
Функция ПланыОбменаСПравиламиИзФайла()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПравилаДляОбменаДанными.ИмяПланаОбмена
|ИЗ
| РегистрСведений.ПравилаДляОбменаДанными КАК ПравилаДляОбменаДанными
|ГДЕ
| ПравилаДляОбменаДанными.ИсточникПравил = &ИсточникПравил";
Запрос.УстановитьПараметр("ИсточникПравил", Перечисления.ИсточникиПравилДляОбменаДанными.Файл);
Результат = Запрос.Выполнить().Выгрузить();
Возврат Результат.Количество();
КонецФункции
Процедура ПроверитьВозможностьВнешнегоСоединения()
Если ОбщегоНазначения.ЭтоLinuxСервер() Тогда
ВызватьИсключение НСтр("ru = 'Синхронизация данных через прямое подключение на сервере под управлением ОС Linux недоступно.
|Для синхронизации данных через прямое подключение требуется использовать ОС Windows.'");
КонецЕсли;
КонецПроцедуры
// Заполняет список значений доступными видами транспорта для узла плана обмена.
//
Процедура ЗаполнитьСписокВыбораДоступнымиВидамиТранспорта(УзелИнформационнойБазы, ЭлементФормы, Отбор = Неопределено) Экспорт
ОтборЗадан = (Отбор <> Неопределено);
ИспользуемыеТранспорты = ОбменДаннымиПовтИсп.ИспользуемыеТранспортыСообщенийОбмена(УзелИнформационнойБазы);
ЭлементФормы.СписокВыбора.Очистить();
Для Каждого Элемент Из ИспользуемыеТранспорты Цикл
Если ОтборЗадан Тогда
Если Отбор.Найти(Элемент) <> Неопределено Тогда
ЭлементФормы.СписокВыбора.Добавить(Элемент, Строка(Элемент));
КонецЕсли;
Иначе
ЭлементФормы.СписокВыбора.Добавить(Элемент, Строка(Элемент));
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Регистрирует что обмен был произведен и фиксирует информацию в протоколе.
//
// Параметры:
// СтруктураНастроекОбмена - Структура - структура со всеми необходимыми данными и объектами для выполнения обмена.
//
Процедура ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена) Экспорт
// Статус "Неопределено" в конце обмена свидетельствует об успешном выполнении обмена.
Если СтруктураНастроекОбмена.РезультатВыполненияОбмена = Неопределено Тогда
СтруктураНастроекОбмена.РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Выполнено;
КонецЕсли;
// Формируем итоговое сообщение для протокола.
Если СтруктураНастроекОбмена.ЭтоОбменВРИБ Тогда
СтрокаСообщения = НСтр("ru = '%1, %2'", ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения,
СтруктураНастроекОбмена.РезультатВыполненияОбмена,
СтруктураНастроекОбмена.ДействиеПриОбмене);
Иначе
СтрокаСообщения = НСтр("ru = '%1, %2; Объектов обработано: %3'", ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения,
СтруктураНастроекОбмена.РезультатВыполненияОбмена,
СтруктураНастроекОбмена.ДействиеПриОбмене,
СтруктураНастроекОбмена.КоличествоОбъектовОбработано);
КонецЕсли;
СтруктураНастроекОбмена.ДатаОкончания = ТекущаяДатаСеанса();
УстановитьПривилегированныйРежим(Истина);
// Фиксируем состояние обмена в РС.
ЗафиксироватьЗавершениеОбменаВРегистреСведений(СтруктураНастроекОбмена);
// Если обмен данными был успешно выполнен.
Если РезультатВыполненияОбменаВыполнено(СтруктураНастроекОбмена.РезультатВыполненияОбмена) Тогда
ЗафиксироватьУспешныйОбменДаннымиВРегистреСведений(СтруктураНастроекОбмена);
РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.СнятьПризнакОтправкиДанных(СтруктураНастроекОбмена.УзелИнформационнойБазы);
КонецЕсли;
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщения, СтруктураНастроекОбмена);
КонецПроцедуры
Процедура ЗафиксироватьНачалоОбменаВРегистреСведений(СтруктураНастроекОбмена)
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("УзелИнформационнойБазы", СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураЗаписи.Вставить("ДействиеПриОбмене", СтруктураНастроекОбмена.ДействиеПриОбмене);
СтруктураЗаписи.Вставить("ДатаНачала", СтруктураНастроекОбмена.ДатаНачала);
РегистрыСведений.СостоянияОбменовДанными.ОбновитьЗапись(СтруктураЗаписи);
КонецПроцедуры
// Фиксирует состояние обмена данными в регистре сведений СостоянияОбменовДанными.
//
// Параметры:
// СтруктураНастроекОбмена - Структура - структура со всеми необходимыми данными и объектами для выполнения обмена.
//
Процедура ЗафиксироватьЗавершениеОбменаВРегистреСведений(СтруктураНастроекОбмена)
// Создаем структуру для новой записи в РС.
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("УзелИнформационнойБазы", СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураЗаписи.Вставить("ДействиеПриОбмене", СтруктураНастроекОбмена.ДействиеПриОбмене);
СтруктураЗаписи.Вставить("РезультатВыполненияОбмена", СтруктураНастроекОбмена.РезультатВыполненияОбмена);
СтруктураЗаписи.Вставить("ДатаНачала", СтруктураНастроекОбмена.ДатаНачала);
СтруктураЗаписи.Вставить("ДатаОкончания", СтруктураНастроекОбмена.ДатаОкончания);
РегистрыСведений.СостоянияОбменовДанными.ДобавитьЗапись(СтруктураЗаписи);
КонецПроцедуры
Процедура ЗафиксироватьУспешныйОбменДаннымиВРегистреСведений(СтруктураНастроекОбмена)
// Создаем структуру для новой записи в РС.
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("УзелИнформационнойБазы", СтруктураНастроекОбмена.УзелИнформационнойБазы);
СтруктураЗаписи.Вставить("ДействиеПриОбмене", СтруктураНастроекОбмена.ДействиеПриОбмене);
СтруктураЗаписи.Вставить("ДатаОкончания", СтруктураНастроекОбмена.ДатаОкончания);
РегистрыСведений.СостоянияУспешныхОбменовДанными.ДобавитьЗапись(СтруктураЗаписи);
КонецПроцедуры
Процедура ЗаписьЖурналаРегистрацииНачалаОбменаДанными(СтруктураНастроекОбмена) Экспорт
СтрокаСообщения = НСтр("ru = 'Начало процесса обмена данными для узла %1'", ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, СтруктураНастроекОбмена.УзелИнформационнойБазыНаименование);
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщения, СтруктураНастроекОбмена);
КонецПроцедуры
// Создает запись в журнале регистрации о событии обмена данными/транспорте сообщений обмена.
//
Процедура ЗаписьЖурналаРегистрацииОбменаДанными(Комментарий, СтруктураНастроекОбмена, ЭтоОшибка = Ложь)
Уровень = ?(ЭтоОшибка, УровеньЖурналаРегистрации.Ошибка, УровеньЖурналаРегистрации.Информация);
Если СтруктураНастроекОбмена.Свойство("УзелИнформационнойБазы") Тогда
ЗаписьЖурналаРегистрации(СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации,
Уровень,
СтруктураНастроекОбмена.УзелИнформационнойБазы.Метаданные(),
СтруктураНастроекОбмена.УзелИнформационнойБазы,
Комментарий);
Иначе
ЗаписьЖурналаРегистрации(СтруктураНастроекОбмена.КлючСообщенияЖурналаРегистрации, Уровень,,, Комментарий);
КонецЕсли;
КонецПроцедуры
Процедура ЗаписатьСобытиеПолученияДанных(Знач УзелИнформационнойБазы, Знач Комментарий, Знач ЭтоОшибка = Ложь)
Уровень = ?(ЭтоОшибка, УровеньЖурналаРегистрации.Ошибка, УровеньЖурналаРегистрации.Информация);
КлючСообщенияЖурналаРегистрации = КлючСообщенияЖурналаРегистрации(УзелИнформационнойБазы, Перечисления.ДействияПриОбмене.ЗагрузкаДанных);
ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, Уровень,,, Комментарий);
КонецПроцедуры
Процедура ФормаНастройкиУзлаОбработчикПриСозданииНаСервере(Форма, ИмяРеквизитаФормы)
РеквизитыФормы = ИменаРеквизитовФормы(Форма);
Для Каждого НастройкаОтбора Из Форма[ИмяРеквизитаФормы] Цикл
Ключ = НастройкаОтбора.Ключ;
Если РеквизитыФормы.Найти(Ключ) = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(Форма[Ключ]) = Тип("ДанныеФормыКоллекция") Тогда
Таблица = Новый ТаблицаЗначений;
СтруктураТабличнойЧасти = Форма.Параметры[ИмяРеквизитаФормы][Ключ];
Для Каждого Элемент Из СтруктураТабличнойЧасти Цикл
Пока Таблица.Количество() < Элемент.Значение.Количество() Цикл
Таблица.Добавить();
КонецЦикла;
Таблица.Колонки.Добавить(Элемент.Ключ);
Таблица.ЗагрузитьКолонку(Элемент.Значение, Элемент.Ключ);
КонецЦикла;
Форма[Ключ].Загрузить(Таблица);
Иначе
Форма[Ключ] = Форма.Параметры[ИмяРеквизитаФормы][Ключ];
КонецЕсли;
Форма[ИмяРеквизитаФормы][Ключ] = Форма.Параметры[ИмяРеквизитаФормы][Ключ];
КонецЦикла;
КонецПроцедуры
Функция ИменаРеквизитовФормы(Форма)
// Возвращаемое значение функции.
Результат = Новый Массив;
Для Каждого РеквизитФормы Из Форма.ПолучитьРеквизиты() Цикл
Результат.Добавить(РеквизитФормы.Имя);
КонецЦикла;
Возврат Результат;
КонецФункции
// Распаковывает файл архива ZIP в указанный каталог; Извлекает все файлы архива.
//
// Параметры:
// ПолноеИмяФайлаАрхива - Строка - имя файла архива, который необходимо распаковать.
// ПутьРаспаковкиФайлов - Строка - путь по которому необходимо распаковать файлы.
// ПарольАрхива - Строка - пароль для распаковки архива. По умолчанию пустая строка.
//
// Возвращаемое значение:
// Результат - Булево - Истина, если успешно, Ложь, если нет.
//
Функция РаспаковатьZipФайл(Знач ПолноеИмяФайлаАрхива, Знач ПутьРаспаковкиФайлов, Знач ПарольАрхива = "") Экспорт
Результат = Истина;
Архиватор = Неопределено;
Попытка
Архиватор = Новый ЧтениеZipФайла(ПолноеИмяФайлаАрхива, ПарольАрхива);
Архиватор.ИзвлечьВсе(ПутьРаспаковкиФайлов, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
Исключение
ИнформацияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Ошибка при распаковке файлов архива ""%1"" в каталог ""%2"" по причине:
|%3'"),
ПолноеИмяФайлаАрхива,
ПутьРаспаковкиФайлов,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Ошибка, , , ИнформацияОбОшибке);
Результат = Ложь;
КонецПопытки;
Если Архиватор <> Неопределено Тогда
Архиватор.Закрыть();
КонецЕсли;
Возврат Результат;
КонецФункции
// Запаковывает указанный каталог в файл архива ZIP.
//
// Параметры:
// ПолноеИмяФайлаАрхива - Строка - имя файла архива, в который необходимо запаковать.
// МаскаУпаковкиФайлов - Строка - имя файла, помещаемого в архив, или маска.
// Недопустимо использование в именах файлов и папок букв национальных алфавитов, которые при
// преобразовании из символов UNICODE в узкие символы могут быть преобразованы с потерей информации.
// Рекомендуется использовать в именах файлов и папок символы латинского алфавита.
// ПарольАрхива - Строка - пароль для архива. По умолчанию пустая строка.
//
// Возвращаемое значение:
// Результат - Булево - Истина, если успешно, Ложь, если нет.
//
Функция ЗапаковатьВZipФайл(Знач ПолноеИмяФайлаАрхива, Знач МаскаУпаковкиФайлов, Знач ПарольАрхива = "") Экспорт
// Возвращаемое значение функции.
Результат = Истина;
Попытка
Архиватор = Новый ЗаписьZipФайла(ПолноеИмяФайлаАрхива, ПарольАрхива);
Исключение
Архиватор = Неопределено;
СообщитьОбОшибке(КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат Ложь;
КонецПопытки;
Попытка
Архиватор.Добавить(МаскаУпаковкиФайлов, РежимСохраненияПутейZIP.НеСохранятьПути);
Архиватор.Записать();
Исключение
ИнформацияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Ошибка при запаковке файлов ""%1"" в архив ""%2"" по причине:
|%3'"),
МаскаУпаковкиФайлов,
ПолноеИмяФайлаАрхива,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Ошибка, , , ИнформацияОбОшибке);
Результат = Ложь;
КонецПопытки;
Архиватор = Неопределено;
Возврат Результат;
КонецФункции
// Возвращает количество записей в таблице базы данных.
//
// Параметры:
// ИмяТаблицы - Строка - полное имя таблицы базы данных. Например: "Справочник.Контрагенты.Заказы".
//
// Возвращаемое значение:
// Число - количество записей в таблице базы данных.
//
Функция КоличествоЗаписейВТаблицеБазыДанных(Знач ИмяТаблицы) Экспорт
ТекстЗапроса = "
|ВЫБРАТЬ
| Количество(*) КАК Количество
|ИЗ
| #ИмяТаблицы
|";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ИмяТаблицы", ИмяТаблицы);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
Возврат Выборка["Количество"];
КонецФункции
// Возвращает количество записей во временной таблице базы данных.
//
// Параметры:
// ИмяТаблицы - Строка - имя таблицы. Например: "ВременнаяТаблица1".
// МенеджерВременныхТаблиц - менеджер временных таблиц, который содержит указатель на временную таблицу ИмяТаблицы.
//
// Возвращаемое значение:
// Число - количество записей в таблице базы данных.
//
Функция КоличествоЗаписейВоВременнойТаблицеБазыДанных(Знач ИмяТаблицы, МенеджерВременныхТаблиц) Экспорт
ТекстЗапроса = "
|ВЫБРАТЬ
| Количество(*) КАК Количество
|ИЗ
| #ИмяТаблицы
|";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#ИмяТаблицы", ИмяТаблицы);
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
Возврат Выборка["Количество"];
КонецФункции
// Возвращает ключ сообщения журнала регистрации.
//
Функция КлючСообщенияЖурналаРегистрации(УзелИнформационнойБазы, ДействиеПриОбмене) Экспорт
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелИнформационнойБазы);
КлючСообщения = НСтр("ru = 'Обмен данными.[ИмяПланаОбмена].[ДействиеПриОбмене]'",
ОбщегоНазначения.КодОсновногоЯзыка());
КлючСообщения = СтрЗаменить(КлючСообщения, "[ИмяПланаОбмена]", ИмяПланаОбмена);
КлючСообщения = СтрЗаменить(КлючСообщения, "[ДействиеПриОбмене]", ДействиеПриОбмене);
Возврат КлючСообщения;
КонецФункции
// Возвращает признак того, что реквизит входит в подмножество стандартных реквизитов.
//
// Параметры:
// СтандартныеРеквизиты - ОписанияСтандартныхРеквизитов - коллекция стандартных реквизитов.
// ИмяРеквизита - Строка - имя проверяемого реквизита.
//
// Возвращаемое значение:
// Булево - Истина, если заданный реквизит является стандартным.
//
Функция ЭтоСтандартныйРеквизит(СтандартныеРеквизиты, ИмяРеквизита) Экспорт
Для Каждого Реквизит Из СтандартныеРеквизиты Цикл
Если Реквизит.Имя = ИмяРеквизита Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
// Возвращает признак успешного выполнения обмена данными.
//
Функция РезультатВыполненияОбменаВыполнено(РезультатВыполненияОбмена)
Возврат РезультатВыполненияОбмена = Неопределено
ИЛИ РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.Выполнено
ИЛИ РезультатВыполненияОбмена = Перечисления.РезультатыВыполненияОбмена.ВыполненоСПредупреждениями;
КонецФункции
// Формирует и возвращает ключ таблицы данных.
// Ключ таблицы используется для выборочной загрузки данных из сообщения обмена по заданному ключу.
//
Функция КлючТаблицыДанных(Знач ТипИсточника, Знач ТипПриемника, Знач ЭтоУдалениеОбъекта) Экспорт
Возврат ТипИсточника + "#" + ТипПриемника + "#" + Строка(ЭтоУдалениеОбъекта);
КонецФункции
Функция НадоВыполнитьОбработчик(Объект, Ссылка, ИмяСвойства)
НомерПослеОбработки = Объект[ИмяСвойства];
НомерПередОбработкой = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, ИмяСвойства);
НомерПередОбработкой = ?(НомерПередОбработкой = Неопределено, 0, НомерПередОбработкой);
Возврат НомерПередОбработкой <> НомерПослеОбработки;
КонецФункции
Функция ЗаполнитьПараметрыПодключенияВнешнегоСоединения(НастройкиТранспорта)
ПараметрыПодключения = ОбщегоНазначенияКлиентСервер.СтруктураПараметровДляУстановкиВнешнегоСоединения();
ПараметрыПодключения.ВариантРаботыИнформационнойБазы = НастройкиТранспорта.COMВариантРаботыИнформационнойБазы;
ПараметрыПодключения.КаталогИнформационнойБазы = НастройкиТранспорта.COMКаталогИнформационнойБазы;
ПараметрыПодключения.ИмяСервера1СПредприятия = НастройкиТранспорта.COMИмяСервера1СПредприятия;
ПараметрыПодключения.ИмяИнформационнойБазыНаСервере1СПредприятия = НастройкиТранспорта.COMИмяИнформационнойБазыНаСервере1СПредприятия;
ПараметрыПодключения.АутентификацияОперационнойСистемы = НастройкиТранспорта.COMАутентификацияОперационнойСистемы;
ПараметрыПодключения.ИмяПользователя = НастройкиТранспорта.COMИмяПользователя;
ПараметрыПодключения.ПарольПользователя = НастройкиТранспорта.COMПарольПользователя;
Возврат ПараметрыПодключения;
КонецФункции
Функция ДобавитьЛитералКИмениФайла(Знач ПолноеИмяФайла, Знач Литерал)
Если ПустаяСтрока(ПолноеИмяФайла) Тогда
Возврат "";
КонецЕсли;
ИмяФайлаБезРасширения = Сред(ПолноеИмяФайла, 1, СтрДлина(ПолноеИмяФайла) - 4);
Расширение = Прав(ПолноеИмяФайла, 3);
Результат = "[ИмяФайлаБезРасширения]_[Литерал].[Расширение]";
Результат = СтрЗаменить(Результат, "[ИмяФайлаБезРасширения]", ИмяФайлаБезРасширения);
Результат = СтрЗаменить(Результат, "[Литерал]", Литерал);
Результат = СтрЗаменить(Результат, "[Расширение]", Расширение);
Возврат Результат;
КонецФункции
Функция НаименованиеПредопределенногоУзлаПланаОбмена(ИмяПланаОбмена) Экспорт
УстановитьПривилегированныйРежим(Истина);
Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОбменДаннымиПовтИсп.ПолучитьЭтотУзелПланаОбмена(ИмяПланаОбмена), "Наименование");
КонецФункции
Процедура ОбработчикПриВыгрузкеДанныхБСП(
Обработчики,
ПараметрыВыполнения,
СтандартнаяОбработка,
ДанныеСообщения,
КоличествоОтправленныхОбъектов)
Для Каждого Обработчик Из Обработчики Цикл
Если Не СтандартнаяОбработка Тогда
Прервать;
КонецЕсли;
КоличествоОтправленныхОбъектов = 0;
Обработчик.ПриВыгрузкеДанных(СтандартнаяОбработка,
ПараметрыВыполнения.УзелИнформационнойБазы,
ПараметрыВыполнения.ИмяФайлаСообщенияОбмена,
ДанныеСообщения,
ПараметрыВыполнения.КоличествоЭлементовВТранзакции,
ПараметрыВыполнения.КлючСообщенияЖурналаРегистрации,
КоличествоОтправленныхОбъектов);
КонецЦикла;
КонецПроцедуры
Процедура ОбработчикПриЗагрузкеДанныхБСП(
Обработчики,
ПараметрыВыполнения,
СтандартнаяОбработка,
ДанныеСообщения,
КоличествоПолученныхОбъектов)
Для Каждого Обработчик Из Обработчики Цикл
Если Не СтандартнаяОбработка Тогда
Прервать;
КонецЕсли;
КоличествоПолученныхОбъектов = 0;
Обработчик.ПриЗагрузкеДанных(СтандартнаяОбработка,
ПараметрыВыполнения.УзелИнформационнойБазы,
ПараметрыВыполнения.ИмяФайлаСообщенияОбмена,
ДанныеСообщения,
ПараметрыВыполнения.КоличествоЭлементовВТранзакции,
ПараметрыВыполнения.КлючСообщенияЖурналаРегистрации,
КоличествоПолученныхОбъектов);
КонецЦикла;
КонецПроцедуры
Процедура ЗафиксироватьЗавершениеОбменаСОшибкой(Знач УзелИнформационнойБазы,
Знач ДействиеПриОбмене,
Знач ДатаНачала,
Знач СтрокаСообщенияОбОшибке) Экспорт
Если ТипЗнч(ДействиеПриОбмене) = Тип("Строка") Тогда
ДействиеПриОбмене = Перечисления.ДействияПриОбмене[ДействиеПриОбмене];
КонецЕсли;
СтруктураНастроекОбмена = Новый Структура;
СтруктураНастроекОбмена.Вставить("УзелИнформационнойБазы", УзелИнформационнойБазы);
СтруктураНастроекОбмена.Вставить("РезультатВыполненияОбмена", Перечисления.РезультатыВыполненияОбмена.Ошибка);
СтруктураНастроекОбмена.Вставить("ДействиеПриОбмене", ДействиеПриОбмене);
СтруктураНастроекОбмена.Вставить("КоличествоОбъектовОбработано", 0);
СтруктураНастроекОбмена.Вставить("КлючСообщенияЖурналаРегистрации", КлючСообщенияЖурналаРегистрации(УзелИнформационнойБазы, ДействиеПриОбмене));
СтруктураНастроекОбмена.Вставить("ДатаНачала", ДатаНачала);
СтруктураНастроекОбмена.Вставить("ДатаОкончания", ТекущаяДатаСеанса());
СтруктураНастроекОбмена.Вставить("ЭтоОбменВРИБ", ОбменДаннымиПовтИсп.ЭтоУзелРаспределеннойИнформационнойБазы(УзелИнформационнойБазы));
ЗаписьЖурналаРегистрацииОбменаДанными(СтрокаСообщенияОбОшибке, СтруктураНастроекОбмена, Истина);
ЗафиксироватьЗавершениеОбмена(СтруктураНастроекОбмена);
КонецПроцедуры
// Проверяет наличие указанных реквизитов в форме.
// Если хотя бы один реквизит отсутствует, то вызывает исключение.
//
Процедура ПроверитьОбязательныеРеквизитыФормы(Форма, Знач Реквизиты)
ОтсутствующиеРеквизиты = Новый Массив;
РеквизитыФормы = ИменаРеквизитовФормы(Форма);
Для Каждого Реквизит Из СтрРазделить(Реквизиты, ",") Цикл
Реквизит = СокрЛП(Реквизит);
Если РеквизитыФормы.Найти(Реквизит) = Неопределено Тогда
ОтсутствующиеРеквизиты.Добавить(Реквизит);
КонецЕсли;
КонецЦикла;
Если ОтсутствующиеРеквизиты.Количество() > 0 Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Отсутствуют обязательные реквизиты формы настройки узла: %1'"),
СтрСоединить(ОтсутствующиеРеквизиты, ","));
КонецЕсли;
КонецПроцедуры
Процедура ВнешнееСоединениеОбновитьНастройкиОбменаДанными(Знач ИмяПланаОбмена, Знач КодУзла, Знач ЗначенияПоУмолчаниюНаУзле) Экспорт
УстановитьПривилегированныйРежим(Истина);
УзелИнформационнойБазы = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(КодУзла);
Если Не ЗначениеЗаполнено(УзелИнформационнойБазы) Тогда
Сообщение = НСтр("ru = 'Не найден узел плана обмена; имя плана обмена %1; код узла %2'");
Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ИмяПланаОбмена, КодУзла);
ВызватьИсключение Сообщение;
КонецЕсли;
ПомощникСозданияОбменаДанными = МодульПомощникСозданияОбменаДанными().Создать();
ПомощникСозданияОбменаДанными.УзелИнформационнойБазы = УзелИнформационнойБазы;
ПомощникСозданияОбменаДанными.ВнешнееСоединениеОбновитьНастройкиОбменаДанными(ПолучитьЗначенияНастройкиОтборов(ЗначенияПоУмолчаниюНаУзле));
КонецПроцедуры
Функция ИмяТаблицыИзПервогоРеквизитаТабличнойЧастиПланаОбмена(Знач ИмяПланаОбмена, Знач ИмяТабличнойЧасти)
ТабличнаяЧасть = Метаданные.ПланыОбмена[ИмяПланаОбмена].ТабличныеЧасти[ИмяТабличнойЧасти];
Для Каждого Реквизит Из ТабличнаяЧасть.Реквизиты Цикл
Тип = Реквизит.Тип.Типы()[0];
Если ОбщегоНазначения.ЭтоСсылка(Тип) Тогда
Возврат Метаданные.НайтиПоТипу(Тип).ПолноеИмя();
КонецЕсли;
КонецЦикла;
Возврат "";
КонецФункции
Функция СправочникиПланаОбмена(Знач ИмяПланаОбмена)
Если ТипЗнч(ИмяПланаОбмена) <> Тип("Строка") Тогда
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(ИмяПланаОбмена);
КонецЕсли;
Результат = Новый Массив;
СоставПланаОбмена = Метаданные.ПланыОбмена[ИмяПланаОбмена].Состав;
Для Каждого Элемент Из СоставПланаОбмена Цикл
Если ОбщегоНазначения.ЭтоСправочник(Элемент.Метаданные)
ИЛИ ОбщегоНазначения.ЭтоПланВидовХарактеристик(Элемент.Метаданные) Тогда
Результат.Добавить(Элемент.Метаданные);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ВсеДанныеПланаОбменаКромеСправочников(Знач ИмяПланаОбмена)
Если ТипЗнч(ИмяПланаОбмена) <> Тип("Строка") Тогда
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(ИмяПланаОбмена);
КонецЕсли;
Результат = Новый Массив;
СоставПланаОбмена = Метаданные.ПланыОбмена[ИмяПланаОбмена].Состав;
Для Каждого Элемент Из СоставПланаОбмена Цикл
Если Не (ОбщегоНазначения.ЭтоСправочник(Элемент.Метаданные)
ИЛИ ОбщегоНазначения.ЭтоПланВидовХарактеристик(Элемент.Метаданные)) Тогда
Результат.Добавить(Элемент.Метаданные);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция НастройкиПараметровУчетаВСистемеУстановлены(Знач ИмяПланаОбмена, Знач Корреспондент, СообщениеОбОшибке)
Если ТипЗнч(Корреспондент) = Тип("Строка") Тогда
Если ПустаяСтрока(Корреспондент) Тогда
Возврат Ложь;
КонецЕсли;
КорреспондентКод = Корреспондент;
Корреспондент = ПланыОбмена[ИмяПланаОбмена].НайтиПоКоду(Корреспондент);
Если Не ЗначениеЗаполнено(Корреспондент) Тогда
Сообщение = НСтр("ru = 'Не найден узел плана обмена; имя плана обмена %1; код узла %2'");
Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Сообщение, ИмяПланаОбмена, КорреспондентКод);
ВызватьИсключение Сообщение;
КонецЕсли;
КонецЕсли;
Отказ = Ложь;
Если ЕстьАлгоритмМенеджераПланаОбмена("ОбработчикПроверкиПараметровУчета", ИмяПланаОбмена) Тогда
УстановитьПривилегированныйРежим(Истина);
ПланыОбмена[ИмяПланаОбмена].ОбработчикПроверкиПараметровУчета(Отказ, Корреспондент, СообщениеОбОшибке);
КонецЕсли;
Возврат Не Отказ;
КонецФункции
Функция ПолучитьПараметрыИнформационнойБазы(Знач ИмяПланаОбмена, Знач КодУзла, СообщениеОбОшибке) Экспорт
Возврат ЗначениеВСтрокуВнутр(ПараметрыИнформационнойБазы(ИмяПланаОбмена, КодУзла, СообщениеОбОшибке));
КонецФункции
Функция ПолучитьПараметрыИнформационнойБазы_2_0_1_6(Знач ИмяПланаОбмена, Знач КодУзла, СообщениеОбОшибке) Экспорт
Возврат ОбщегоНазначения.ЗначениеВСтрокуXML(ПараметрыИнформационнойБазы(ИмяПланаОбмена, КодУзла, СообщениеОбОшибке));
КонецФункции
Функция СвойстваОбъектаМетаданных(Знач ПолноеИмяТаблицы) Экспорт
Результат = Новый Структура("Синоним, Иерархический");
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ПолноеИмяТаблицы);
ЗаполнитьЗначенияСвойств(Результат, ОбъектМетаданных);
Возврат Результат;
КонецФункции
Функция ПолучитьОбъектыТаблицы(Знач ПолноеИмяТаблицы) Экспорт
УстановитьПривилегированныйРежим(Истина);
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ПолноеИмяТаблицы);
Если ОбщегоНазначения.ЭтоСправочник(ОбъектМетаданных) Тогда
Если ОбъектМетаданных.Иерархический Тогда
Если ОбъектМетаданных.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
Возврат ЭлементыИерархическогоСправочникаИерархияГруппИЭлементов(ПолноеИмяТаблицы);
КонецЕсли;
Возврат ЭлементыИерархическогоСправочникаИерархияЭлементов(ПолноеИмяТаблицы);
КонецЕсли;
Возврат ЭлементыНеиерархическогоСправочника(ПолноеИмяТаблицы);
ИначеЕсли ОбщегоНазначения.ЭтоПланВидовХарактеристик(ОбъектМетаданных) Тогда
Если ОбъектМетаданных.Иерархический Тогда
Возврат ЭлементыИерархическогоСправочникаИерархияГруппИЭлементов(ПолноеИмяТаблицы);
КонецЕсли;
Возврат ЭлементыНеиерархическогоСправочника(ПолноеИмяТаблицы);
КонецЕсли;
Возврат Неопределено;
КонецФункции
Функция ЭлементыИерархическогоСправочникаИерархияГруппИЭлементов(Знач ПолноеИмяТаблицы)
ШаблонТекстаЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 2000
| ПсевдонимТаблицыМетаданных.Ссылка,
| ПсевдонимТаблицыМетаданных.Представление,
| ВЫБОР
| КОГДА ПсевдонимТаблицыМетаданных.ЭтоГруппа
| И НЕ ПсевдонимТаблицыМетаданных.ПометкаУдаления
| ТОГДА 0
| КОГДА ПсевдонимТаблицыМетаданных.ЭтоГруппа
| И ПсевдонимТаблицыМетаданных.ПометкаУдаления
| ТОГДА 1
| КОГДА НЕ ПсевдонимТаблицыМетаданных.ЭтоГруппа
| И НЕ ПсевдонимТаблицыМетаданных.ПометкаУдаления
| ТОГДА 2
| КОГДА НЕ ПсевдонимТаблицыМетаданных.ЭтоГруппа
| И ПсевдонимТаблицыМетаданных.ПометкаУдаления
| ТОГДА 3
| КОНЕЦ КАК ИндексКартинки
|ИЗ
| &ИмяТаблицыМетаданных КАК ПсевдонимТаблицыМетаданных
|УПОРЯДОЧИТЬ ПО
| ПсевдонимТаблицыМетаданных.ЭтоГруппа ИЕРАРХИЯ,
| ПсевдонимТаблицыМетаданных.Наименование";
ТекстЗапроса = СтрЗаменить(ШаблонТекстаЗапроса, "&ИмяТаблицыМетаданных", ПолноеИмяТаблицы);
Запрос = Новый Запрос(ТекстЗапроса);
Возврат РезультатЗапросаВXMLДерево(Запрос);
КонецФункции
Функция ЭлементыИерархическогоСправочникаИерархияЭлементов(Знач ПолноеИмяТаблицы)
ШаблонТекстаЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 2000
| ПсевдонимТаблицыМетаданных.Ссылка,
| ПсевдонимТаблицыМетаданных.Представление,
| ВЫБОР
| КОГДА ПсевдонимТаблицыМетаданных.ПометкаУдаления
| ТОГДА 3
| ИНАЧЕ 2
| КОНЕЦ КАК ИндексКартинки
|ИЗ
| &ИмяТаблицыМетаданных КАК ПсевдонимТаблицыМетаданных
|УПОРЯДОЧИТЬ ПО
| ПсевдонимТаблицыМетаданных.Наименование ИЕРАРХИЯ";
ТекстЗапроса = СтрЗаменить(ШаблонТекстаЗапроса, "&ИмяТаблицыМетаданных", ПолноеИмяТаблицы);
Запрос = Новый Запрос(ТекстЗапроса);
Возврат РезультатЗапросаВXMLДерево(Запрос);
КонецФункции
Функция ЭлементыНеиерархическогоСправочника(Знач ПолноеИмяТаблицы)
ШаблонТекстаЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 2000
| ПсевдонимТаблицыМетаданных.Ссылка КАК Ссылка,
| ПсевдонимТаблицыМетаданных.Представление КАК Представление,
| ВЫБОР
| КОГДА ПсевдонимТаблицыМетаданных.ПометкаУдаления
| ТОГДА 3
| ИНАЧЕ 2
| КОНЕЦ КАК ИндексКартинки
|ИЗ
| &ИмяТаблицыМетаданных КАК ПсевдонимТаблицыМетаданных
|
|УПОРЯДОЧИТЬ ПО
| ПсевдонимТаблицыМетаданных.Наименование";
ТекстЗапроса = СтрЗаменить(ШаблонТекстаЗапроса, "&ИмяТаблицыМетаданных", ПолноеИмяТаблицы);
Запрос = Новый Запрос(ТекстЗапроса);
Возврат РезультатЗапросаВXMLДерево(Запрос);
КонецФункции
// Параметры:
// Запрос - Запрос - запрос для построения дерева.
//
// Возвращаемое значение:
// ДеревоЗначений:
// * Ссылка - ЛюбаяСсылка - ссылка на объект.
// * Представление - Строка - представление объекта.
// * ИндексКартинки - Число - индекс пиктограммы объекта.
//
Функция ДеревоЭлементов(Знач Запрос)
Возврат Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
КонецФункции
Функция РезультатЗапросаВXMLДерево(Знач Запрос)
Результат = ДеревоЭлементов(Запрос);
Результат.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
ЗаполнитьИдентификаторыСсылокВДереве(Результат.Строки);
КолонкаСсылка = Результат.Колонки.Найти("Ссылка");
Если Не КолонкаСсылка = Неопределено Тогда
Результат.Колонки.Удалить(КолонкаСсылка);
КонецЕсли;
Возврат ОбщегоНазначения.ЗначениеВСтрокуXML(Результат);
КонецФункции
// Параметры:
// СтрокиДерева - КоллекцияСтрокДереваЗначений - строки дерева идентификаторов объектов.
//
Процедура ЗаполнитьИдентификаторыСсылокВДереве(СтрокиДерева)
Для Каждого Строка Из СтрокиДерева Цикл
Строка.Идентификатор = ЗначениеВСтрокуВнутр(Строка.Ссылка);
ЗаполнитьИдентификаторыСсылокВДереве(Строка.Строки);
КонецЦикла;
КонецПроцедуры
Функция ДанныеКорреспондента(Знач ПолноеИмяТаблицы) Экспорт
Результат = Новый Структура("СвойстваОбъектаМетаданных, ТаблицаБазыКорреспондента");
Результат.СвойстваОбъектаМетаданных = СвойстваОбъектаМетаданных(ПолноеИмяТаблицы);
Результат.ТаблицаБазыКорреспондента = ПолучитьОбъектыТаблицы(ПолноеИмяТаблицы);
Возврат Результат;
КонецФункции
Функция ИнформацияСтатистики(ИнформацияСтатистики, Знач ВключатьУдалениеОбъектов = Ложь) Экспорт
ОтборМассив = ИнформацияСтатистики.ВыгрузитьКолонку("ИмяТаблицыПриемника");
ОтборСтрока = СтрСоединить(ОтборМассив, ",");
Отбор = Новый Структура("ПолноеИмя", ОтборСтрока);
// Получаем дерево объектов метаданных конфигурации.
ДеревоИнформацииСтатистики = ОбменДаннымиПовтИсп.МетаданныеКонфигурации(Отбор).Скопировать();
// Добавляем колонки
ДеревоИнформацииСтатистики.Колонки.Добавить("Ключ");
ДеревоИнформацииСтатистики.Колонки.Добавить("КоличествоОбъектовВИсточнике");
ДеревоИнформацииСтатистики.Колонки.Добавить("КоличествоОбъектовВПриемнике");
ДеревоИнформацииСтатистики.Колонки.Добавить("КоличествоОбъектовНесопоставленных");
ДеревоИнформацииСтатистики.Колонки.Добавить("ПроцентСопоставленияОбъектов");
ДеревоИнформацииСтатистики.Колонки.Добавить("ИндексКартинки");
ДеревоИнформацииСтатистики.Колонки.Добавить("ИспользоватьПредварительныйПросмотр");
ДеревоИнформацииСтатистики.Колонки.Добавить("ИмяТаблицыПриемника");
ДеревоИнформацииСтатистики.Колонки.Добавить("ТипОбъектаСтрокой");
ДеревоИнформацииСтатистики.Колонки.Добавить("ПоляТаблицы");
ДеревоИнформацииСтатистики.Колонки.Добавить("ПоляПоиска");
ДеревоИнформацииСтатистики.Колонки.Добавить("ТипИсточникаСтрокой");
ДеревоИнформацииСтатистики.Колонки.Добавить("ТипПриемникаСтрокой");
ДеревоИнформацииСтатистики.Колонки.Добавить("ЭтоУдалениеОбъекта");
ДеревоИнформацииСтатистики.Колонки.Добавить("ДанныеУспешноЗагружены");
// Индексы для поиска в статистике.
Индексы = ИнформацияСтатистики.Индексы;
Если Индексы.Количество() = 0 Тогда
Если ВключатьУдалениеОбъектов Тогда
Индексы.Добавить("ЭтоУдалениеОбъекта");
Индексы.Добавить("ОдинКоМногим, ЭтоУдалениеОбъекта");
Индексы.Добавить("ЭтоКлассификатор, ЭтоУдалениеОбъекта");
Иначе
Индексы.Добавить("ОдинКоМногим");
Индексы.Добавить("ЭтоКлассификатор");
КонецЕсли;
КонецЕсли;
ОбработанныеСтроки = Новый Соответствие;
// Обычные строки
Отбор = Новый Структура("ОдинКоМногим", Ложь);
Если Не ВключатьУдалениеОбъектов Тогда
Отбор.Вставить("ЭтоУдалениеОбъекта", Ложь);
КонецЕсли;
Для Каждого СтрокаТаблицы Из ИнформацияСтатистики.НайтиСтроки(Отбор) Цикл
СтрокаДерева = ДеревоИнформацииСтатистики.Строки.Найти(СтрокаТаблицы.ИмяТаблицыПриемника, "ПолноеИмя", Истина);
ЗаполнитьЗначенияСвойств(СтрокаДерева, СтрокаТаблицы);
СтрокаДерева.Синоним = СинонимДанныхСтрокиДереваСтатистики(СтрокаДерева, СтрокаТаблицы.ТипИсточникаСтрокой);
ОбработанныеСтроки[СтрокаТаблицы] = Истина;
КонецЦикла;
// Добавляем строки с типом ОдинКоМногим.
Отбор = Новый Структура("ОдинКоМногим", Истина);
Если Не ВключатьУдалениеОбъектов Тогда
Отбор.Вставить("ЭтоУдалениеОбъекта", Ложь);
КонецЕсли;
ЗаполнитьДеревоИнформацииСтатистикиОдинКоМногим(ДеревоИнформацииСтатистики, ИнформацияСтатистики, Отбор, ОбработанныеСтроки);
// Добавляем строки классификаторов.
Отбор = Новый Структура("ЭтоКлассификатор", Истина);
Если Не ВключатьУдалениеОбъектов Тогда
Отбор.Вставить("ЭтоУдалениеОбъекта", Ложь);
КонецЕсли;
ЗаполнитьДеревоИнформацииСтатистикиОдинКоМногим(ДеревоИнформацииСтатистики, ИнформацияСтатистики, Отбор, ОбработанныеСтроки);
// Добавляем строки удаления объектов.
Если ВключатьУдалениеОбъектов Тогда
Отбор = Новый Структура("ЭтоУдалениеОбъекта", Истина);
ЗаполнитьДеревоИнформацииСтатистикиОдинКоМногим(ДеревоИнформацииСтатистики, ИнформацияСтатистики, Отбор, ОбработанныеСтроки);
КонецЕсли;
// Очищаем пустые строки
СтрокиСтатистики = ДеревоИнформацииСтатистики.Строки;
ПозицияГруппы = СтрокиСтатистики.Количество() - 1;
Пока ПозицияГруппы >=0 Цикл
Группа = СтрокиСтатистики[ПозицияГруппы];
Элементы = Группа.Строки;
Позиция = Элементы.Количество() - 1;
Пока Позиция >=0 Цикл
Элемент = Элементы[Позиция];
Если Элемент.КоличествоОбъектовВПриемнике = Неопределено
И Элемент.КоличествоОбъектовВИсточнике = Неопределено
И Элемент.Строки.Количество() = 0 Тогда
Элементы.Удалить(Элемент);
КонецЕсли;
Позиция = Позиция - 1;
КонецЦикла;
Если Элементы.Количество() = 0 Тогда
СтрокиСтатистики.Удалить(Группа);
КонецЕсли;
ПозицияГруппы = ПозицияГруппы - 1;
КонецЦикла;
Возврат ДеревоИнформацииСтатистики;
КонецФункции
// Параметры:
// ДеревоИнформацииСтатистики - ДеревоЗначений
// ИнформацияСтатистики - ТаблицаЗначений
// Отбор - Структура
// УжеОбработанныеСтроки - Соответствие
//
Процедура ЗаполнитьДеревоИнформацииСтатистикиОдинКоМногим(ДеревоИнформацииСтатистики, ИнформацияСтатистики, Отбор, УжеОбработанныеСтроки)
СтрокиДляОбработки = ИнформацияСтатистики.НайтиСтроки(Отбор);
// Игнорируем уже обработанные строки источника.
Позиция = СтрокиДляОбработки.ВГраница();
Пока Позиция >= 0 Цикл
Кандидат = СтрокиДляОбработки[Позиция];
Если УжеОбработанныеСтроки[Кандидат] <> Неопределено Тогда
СтрокиДляОбработки.Удалить(Позиция);
Иначе
УжеОбработанныеСтроки[Кандидат] = Истина;
КонецЕсли;
Позиция = Позиция - 1;
КонецЦикла;
Если СтрокиДляОбработки.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ИнформацияСтатистикиОдинКоМногим = ИнформацияСтатистики.Скопировать(СтрокиДляОбработки);
ИнформацияСтатистикиОдинКоМногим.Индексы.Добавить("ИмяТаблицыПриемника");
ИнформацияСтатистикиОдинКоМногимВременная = ИнформацияСтатистикиОдинКоМногим.Скопировать(СтрокиДляОбработки, "ИмяТаблицыПриемника");
ИнформацияСтатистикиОдинКоМногимВременная.Свернуть("ИмяТаблицыПриемника");
Для Каждого СтрокаТаблицы Из ИнформацияСтатистикиОдинКоМногимВременная Цикл
Строки = ИнформацияСтатистикиОдинКоМногим.НайтиСтроки(Новый Структура("ИмяТаблицыПриемника", СтрокаТаблицы.ИмяТаблицыПриемника));
СтрокаДерева = ДеревоИнформацииСтатистики.Строки.Найти(СтрокаТаблицы.ИмяТаблицыПриемника, "ПолноеИмя", Истина);
Для Каждого Строка Из Строки Цикл
НоваяСтрокаДерева = СтрокаДерева.Строки.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрокаДерева, СтрокаДерева);
ЗаполнитьЗначенияСвойств(НоваяСтрокаДерева, Строка);
Если Строка.ЭтоУдалениеОбъекта Тогда
НоваяСтрокаДерева.Картинка = БиблиотекаКартинок.ПометитьНаУдаление;
Иначе
НоваяСтрокаДерева.Синоним = СинонимДанныхСтрокиДереваСтатистики(НоваяСтрокаДерева, Строка.ТипИсточникаСтрокой) ;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция УдалитьИмяКлассаИзИмениОбъекта(Знач Результат)
Результат = СтрЗаменить(Результат, "ДокументСсылка.", "");
Результат = СтрЗаменить(Результат, "СправочникСсылка.", "");
Результат = СтрЗаменить(Результат, "ПланВидовХарактеристикСсылка.", "");
Результат = СтрЗаменить(Результат, "ПланСчетовСсылка.", "");
Результат = СтрЗаменить(Результат, "ПланВидовРасчетаСсылка.", "");
Результат = СтрЗаменить(Результат, "БизнесПроцессСсылка.", "");
Результат = СтрЗаменить(Результат, "ЗадачаСсылка.", "");
Возврат Результат;
КонецФункции
Процедура ВыполнитьПроверкуНаличияПравилОбменаЗагруженныхИзФайла(ПравилаОбменаЗагруженныеИзФайла, ПравилаРегистрацииЗагруженныеИзФайла)
ТекстЗапроса = "ВЫБРАТЬ РАЗЛИЧНЫЕ
| ПравилаДляОбменаДанными.ИмяПланаОбмена КАК ИмяПланаОбмена,
| ПравилаДляОбменаДанными.ВидПравил КАК ВидПравил
|ИЗ
| РегистрСведений.ПравилаДляОбменаДанными КАК ПравилаДляОбменаДанными
|ГДЕ
| ПравилаДляОбменаДанными.ИсточникПравил = ЗНАЧЕНИЕ(Перечисление.ИсточникиПравилДляОбменаДанными.Файл)
| И ПравилаДляОбменаДанными.ПравилаЗагружены";
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапроса;
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
ПланыОбменаМассив = Новый Массив;
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.ВидПравил = Перечисления.ВидыПравилДляОбменаДанными.ПравилаКонвертацииОбъектов Тогда
ПравилаОбменаЗагруженныеИзФайла.Добавить(Выборка.ИмяПланаОбмена);
ИначеЕсли Выборка.ВидПравил = Перечисления.ВидыПравилДляОбменаДанными.ПравилаРегистрацииОбъектов Тогда
ПравилаРегистрацииЗагруженныеИзФайла.Добавить(Выборка.ИмяПланаОбмена);
КонецЕсли;
Если ПланыОбменаМассив.Найти(Выборка.ИмяПланаОбмена) = Неопределено Тогда
ПланыОбменаМассив.Добавить(Выборка.ИмяПланаОбмена);
КонецЕсли;
КонецЦикла;
СтрокаСообщения = НСтр("ru = 'Для планов обмена %1 используются правила обмена, загруженные из файла.
|Эти правила могут быть несовместимы с новой версией программы.
|Для предупреждения возможного возникновения ошибок при работе с программой рекомендуется актуализировать правила обмена из файла.'",
ОбщегоНазначения.КодОсновногоЯзыка());
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, СтрСоединить(ПланыОбменаМассив, ","));
ЗаписьЖурналаРегистрации(ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Ошибка,,, СтрокаСообщения);
КонецЕсли;
КонецПроцедуры
// Основная функция для использования внешнего соединения при обмене.
//
// Параметры:
// СтруктураНастроек - структура настроек транспорта COM обмена.
//
// Возвращаемое значение:
// Структура:
// * Соединение - COMОбъект
// - Неопределено - указатель на COM-объект соединения или Неопределено в
// случае ошибки;
// * КраткоеОписаниеОшибки - Строка - краткое описание ошибки;
// * ПодробноеОписаниеОшибки - Строка - подробное описание ошибки;
// * ОшибкаПодключенияКомпоненты - Булево - флаг ошибки подключения COM.
//
Функция УстановитьВнешнееСоединениеСБазой(СтруктураНастроек) Экспорт
Результат = ОбщегоНазначения.УстановитьВнешнееСоединениеСБазой(
ЗаполнитьПараметрыПодключенияВнешнегоСоединения(СтруктураНастроек));
ВнешнееСоединение = Результат.Соединение;
Если ВнешнееСоединение = Неопределено Тогда
// Ошибка установки соединения.
Возврат Результат;
КонецЕсли;
// Дополнительно проверяем возможность работы с внешней базой.
Попытка
НетПолныхПрав = Не ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.РольДоступнаПолныеПрава();
Исключение
НетПолныхПрав = Истина;
КонецПопытки;
Если НетПолныхПрав Тогда
Результат.ПодробноеОписаниеОшибки = НСтр("ru = 'Пользователю, указанному для подключения к другой программе, должны быть назначены роли ""Администратор системы"" и ""Полные права""'");
Результат.КраткоеОписаниеОшибки = Результат.ПодробноеОписаниеОшибки;
Результат.Соединение = Неопределено;
Иначе
Попытка
СостояниеНеДопустимо = ВнешнееСоединение.ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы();
Исключение
СостояниеНеДопустимо = Ложь
КонецПопытки;
Если СостояниеНеДопустимо Тогда
Результат.ПодробноеОписаниеОшибки = НСтр("ru = 'Другая программа находится в состоянии обновления.'");
Результат.КраткоеОписаниеОшибки = Результат.ПодробноеОписаниеОшибки;
Результат.Соединение = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НастройкиТранспортаПоПараметрамВнешнегоСоединения(Параметры)
// Преобразуем настройки - параметры внешнего соединения в параметры транспорта.
НастройкиТранспорта = Новый Структура;
НастройкиТранспорта.Вставить("COMПарольПользователя",
ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ПарольПользователя"));
НастройкиТранспорта.Вставить("COMИмяПользователя",
ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ИмяПользователя"));
НастройкиТранспорта.Вставить("COMАутентификацияОперационнойСистемы",
ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "АутентификацияОперационнойСистемы"));
НастройкиТранспорта.Вставить("COMИмяИнформационнойБазыНаСервере1СПредприятия",
ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ИмяИнформационнойБазыНаСервере1СПредприятия"));
НастройкиТранспорта.Вставить("COMИмяСервера1СПредприятия",
ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ИмяСервера1СПредприятия"));
НастройкиТранспорта.Вставить("COMКаталогИнформационнойБазы",
ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "КаталогИнформационнойБазы"));
НастройкиТранспорта.Вставить("COMВариантРаботыИнформационнойБазы",
ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ВариантРаботыИнформационнойБазы"));
Возврат НастройкиТранспорта;
КонецФункции
// Инициализирует WS-прокси для выполнения управляющих команд обмена данными,
// предварительно проверяет наличие узла обмена.
//
// Параметры:
// Прокси - WSПрокси - WS-прокси для передачи управляющих команд.
// СтруктураНастроек - Структура - структура параметров для подключения к корреспонденту и идентификации настройки обмена:
// * ИмяПланаОбмена - Строка - имя плана обмена, используемого при синхронизации.
// * УзелИнформационнойБазы - ПланОбменаСсылка - узел плана обмена, соответствующий корреспонденту.
// * КлючСообщенияЖурналаРегистрации - Строка - имя события для записи ошибок в журнал регистрации.
// * ТекущийУзелПланаОбмена - ПланОбменаСсылка - ссылка на ЭтотУзел плана обмена.
// * ТекущийУзелПланаОбменаКод - Строка - идентификатор текущего узла плана обмена.
// * ДействиеПриОбмене - ПеречислениеСсылка.ДействияПриОбмене - указывает на направление обмена.
// ПараметрыПрокси - Структура:
// * ПараметрыАутентификации - Строка
// - Структура - содержит пароль для аутентификации на веб-сервере.
// * СтруктураНастроекАутентификации - Структура - содержит структуру настроек для аутентификации на веб-сервере.
// * МинимальнаяВерсия - Строка - номер минимальной версии интерфейса "ОбменДанными", требуемый для выполнения действий.
// * ТекущаяВерсия - Строка - исходящий, фактическая версия интерфейса инициализированного WS-прокси.
// Отказ - Булево - признак неуспешной инициализации WS-прокси.
// СостояниеНастройки - Структура - исходящий, возвращает состояние настройки синхронизации, описанной в СтруктураНастроек:
// * НастройкаСуществует - Булево - Истина, если настройка с указанными планом обмена и идентификатором узла существует.
// * НастройкаСинхронизацииДанныхЗавершена - Булево - Истина, если настройка синхронизации завершена.
// * ПоддерживаетсяСопоставлениеДанных - Булево - Истина, если корреспондент поддерживает функцию сопоставления данных.
// * ПолученоСообщениеДляСопоставленияДанных - Булево - Истина, в корреспондент загружено сообщение для сопоставления.
// СтрокаСообщенияОбОшибке - Строка - описание ошибки инициализации WS-прокси.
//
Процедура ИнициализироватьWSПроксиДляУправленияОбменомДанными(Прокси,
СтруктураНастроек, ПараметрыПрокси, Отказ, СостояниеНастройки, СтрокаСообщенияОбОшибке = "") Экспорт
МинимальнаяВерсия = "0.0.0.0";
Если ПараметрыПрокси.Свойство("МинимальнаяВерсия") Тогда
МинимальнаяВерсия = ПараметрыПрокси.МинимальнаяВерсия;
КонецЕсли;
ПараметрыАутентификации = Неопределено;
ПараметрыПрокси.Свойство("ПараметрыАутентификации", ПараметрыАутентификации);
СтруктураНастроекАутентификации = Неопределено;
ПараметрыПрокси.Свойство("СтруктураНастроекАутентификации", СтруктураНастроекАутентификации);
ПараметрыПрокси.Вставить("ТекущаяВерсия", Неопределено);
ДополнительныеПараметры = Новый Структура;
ДополнительныеПараметры.Вставить("ПараметрыАутентификации", ПараметрыАутентификации);
ДополнительныеПараметры.Вставить("МинимальнаяВерсия", МинимальнаяВерсия);
ДополнительныеПараметры.Вставить("СтруктураНастроекАутентификации", СтруктураНастроекАутентификации);
Прокси = WSПроксиДляУзлаИнформационнойБазы(
СтруктураНастроек.УзелИнформационнойБазы,
СтрокаСообщенияОбОшибке,
ДополнительныеПараметры);
Если Прокси = Неопределено Тогда
Отказ = Истина;
Возврат;
КонецЕсли;
ПараметрыПрокси.ТекущаяВерсия = ДополнительныеПараметры.ТекущаяВерсия;
УзелСуществует = Ложь;
Если ЭтоПланОбменаXDTO(СтруктураНастроек.ИмяПланаОбмена) Тогда
ПсевдонимУзла = ПсевдонимПредопределенногоУзла(СтруктураНастроек.УзелИнформационнойБазы);
Если ЗначениеЗаполнено(ПсевдонимУзла) Тогда
// Проверка настройки со старым идентификатором (префиксом).
СостояниеНастройки = СостояниеНастройкиСинхронизацииВКорреспонденте(
Прокси,
ПараметрыПрокси,
СтруктураНастроек.ИмяПланаОбмена,
ПсевдонимУзла);
Если Не СостояниеНастройки.НастройкаСуществует Тогда
Если ВКорреспондентеУстаревшийВариантНастроекОбмена(
Прокси, ПараметрыПрокси, СостояниеНастройки, СтруктураНастроек, ПсевдонимУзла, Отказ, СтрокаСообщенияОбОшибке)
Или Отказ Тогда
Возврат;
КонецЕсли;
Иначе
СтруктураНастроек.ТекущийУзелПланаОбменаКод = ПсевдонимУзла;
Возврат;
КонецЕсли;
КонецЕсли;
СостояниеНастройки = СостояниеНастройкиСинхронизацииВКорреспонденте(
Прокси,
ПараметрыПрокси,
СтруктураНастроек.ИмяПланаОбмена,
СтруктураНастроек.ТекущийУзелПланаОбменаКод);
Если Не СостояниеНастройки.НастройкаСуществует Тогда
Если ВКорреспондентеУстаревшийВариантНастроекОбмена(
Прокси, ПараметрыПрокси, СостояниеНастройки, СтруктураНастроек, СтруктураНастроек.ТекущийУзелПланаОбменаКод, Отказ, СтрокаСообщенияОбОшибке)
Или Отказ Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Иначе
СостояниеНастройки = СостояниеНастройкиСинхронизацииВКорреспонденте(
Прокси,
ПараметрыПрокси,
СтруктураНастроек.ИмяПланаОбмена,
СтруктураНастроек.ТекущийУзелПланаОбменаКод);
КонецЕсли;
Если Не СостояниеНастройки.НастройкаСуществует Тогда
СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Не найдена настройка синхронизации данных ""%1"" с идентификатором ""%2"".'"),
СтруктураНастроек.ИмяПланаОбмена,
СтруктураНастроек.ТекущийУзелПланаОбменаКод);
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Функция ВКорреспондентеУстаревшийВариантНастроекОбмена(Прокси, ПараметрыПрокси, СостояниеНастройки, СтруктураНастроек, КодУзла, Отказ, СтрокаСообщенияОбОшибке = "")
// Проверка возможности выполнения перехода.
Для Каждого ВариантНастройки Из УстаревшиеВариантыНастроекОбмена(СтруктураНастроек.УзелИнформационнойБазы) Цикл
СостояниеНастройки = СостояниеНастройкиСинхронизацииВКорреспонденте(
Прокси,
ПараметрыПрокси,
ВариантНастройки.ИмяПланаОбмена,
КодУзла);
Если СостояниеНастройки.НастройкаСуществует Тогда
Если СтруктураНастроек.ДействиеПриОбмене = Перечисления.ДействияПриОбмене.ВыгрузкаДанных Тогда
СтруктураНастроек.ИмяПланаОбмена = ВариантНастройки.ИмяПланаОбмена;
Если КодУзла <> СтруктураНастроек.ТекущийУзелПланаОбменаКод Тогда
СтруктураНастроек.ТекущийУзелПланаОбменаКод = КодУзла;
КонецЕсли;
Иначе
// В этой ИБ выполнен переход на новый план обмена, в корреспонденте еще не выполнен.
// Получение данных необходимо отменить.
СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'В программе ""%1"" выполняется обновление настроек синхронизации.
|Загрузка данных отменена. Необходимо запустить синхронизацию данных повторно.'"),
ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СтруктураНастроек.УзелИнформационнойБазы, "Наименование"));
Отказ = Истина;
КонецЕсли;
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
Функция УстаревшиеВариантыНастроекОбмена(УзелОбмена)
Результат = Новый Массив;
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелОбмена);
ВариантНастройки = "";
Если ОбщегоНазначения.ЕстьРеквизитОбъекта("ВариантНастройки", УзелОбмена.Метаданные()) Тогда
ВариантНастройки = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(УзелОбмена, "ВариантНастройки");
КонецЕсли;
Если ЗначениеЗаполнено(ВариантНастройки) Тогда
Для Каждого ИмяСтарогоПланаОбмена Из ОбменДаннымиПовтИсп.ПланыОбменаБСП() Цикл
Если ИмяСтарогоПланаОбмена = ИмяПланаОбмена Тогда
Продолжить;
КонецЕсли;
Если ОбменДаннымиПовтИсп.ЭтоПланОбменаРаспределеннойИнформационнойБазы(ИмяСтарогоПланаОбмена) Тогда
Продолжить;
КонецЕсли;
НастройкиСтарогоПланаОбмена = ЗначениеНастройкиПланаОбмена(ИмяСтарогоПланаОбмена,
"ИмяПланаОбменаДляПереходаНаНовыйОбмен,ВариантыНастроекОбмена");
Если НастройкиСтарогоПланаОбмена.ИмяПланаОбменаДляПереходаНаНовыйОбмен = ИмяПланаОбмена Тогда
ВариантНастроек = НастройкиСтарогоПланаОбмена.ВариантыНастроекОбмена.Найти(ВариантНастройки, "ИдентификаторНастройки");
Если Не ВариантНастроек = Неопределено Тогда
Результат.Добавить(Новый Структура("ИмяПланаОбмена, ИдентификаторНастройки",
ИмяСтарогоПланаОбмена, ВариантНастроек.ИдентификаторНастройки));
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СостояниеНастройкиСинхронизацииВКорреспонденте(Прокси, ПараметрыПрокси, ИмяПланаОбмена, ИдентификаторУзла)
Результат = Новый Структура;
Результат.Вставить("НастройкаСуществует", Ложь);
Результат.Вставить("НастройкаСинхронизацииДанныхЗавершена", Истина);
Результат.Вставить("ПолученоСообщениеДляСопоставленияДанных", Ложь);
Результат.Вставить("ПоддерживаетсяСопоставлениеДанных", Истина);
СтрокаСообщенияОбОшибке = "";
Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ПараметрыПрокси.ТекущаяВерсия, "2.0.1.6") >= 0 Тогда
НастройкаСуществует = Прокси.TestConnection(ИмяПланаОбмена, ИдентификаторУзла, СтрокаСообщенияОбОшибке);
Если НастройкаСуществует
И ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ПараметрыПрокси.ТекущаяВерсия, "3.0.1.1") >= 0 Тогда
ПараметрыПриемникаПрокси = Прокси.GetIBParameters(ИмяПланаОбмена, ИдентификаторУзла, СтрокаСообщенияОбОшибке);
ПараметрыПриемника = СериализаторXDTO.ПрочитатьXDTO(ПараметрыПриемникаПрокси);
ЗаполнитьЗначенияСвойств(Результат, ПараметрыПриемника);
КонецЕсли;
Результат.НастройкаСуществует = НастройкаСуществует;
Иначе
ПараметрыПриемникаПрокси = Прокси.GetIBParameters(ИмяПланаОбмена, ИдентификаторУзла, СтрокаСообщенияОбОшибке);
ПараметрыПриемника = ЗначениеИзСтрокиВнутр(ПараметрыПриемникаПрокси);
Если ПараметрыПриемника.Свойство("УзелСуществует") Тогда
Результат.НастройкаСуществует = ПараметрыПриемника.УзелСуществует;
Иначе
Результат.НастройкаСуществует = Истина;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция WSПроксиДляУзлаИнформационнойБазы(УзелИнформационнойБазы,
СтрокаСообщенияОбОшибке = "",
ДополнительныеПараметры = Неопределено)
Если ДополнительныеПараметры = Неопределено Тогда
ДополнительныеПараметры = Новый Структура;
КонецЕсли;
ПараметрыАутентификации = Неопределено;
ДополнительныеПараметры.Свойство("ПараметрыАутентификации", ПараметрыАутентификации);
СтруктураНастроекАутентификации = Неопределено;
ДополнительныеПараметры.Свойство("СтруктураНастроекАутентификации", СтруктураНастроекАутентификации);
МинимальнаяВерсия = Неопределено;
Если Не ДополнительныеПараметры.Свойство("МинимальнаяВерсия", МинимальнаяВерсия) Тогда
МинимальнаяВерсия = "0.0.0.0";
КонецЕсли;
ДополнительныеПараметры.Вставить("ТекущаяВерсия");
Если СтруктураНастроекАутентификации = Неопределено Тогда
Если ОбменДаннымиПовтИсп.ЭтоУзелОбменаСообщениями(УзелИнформационнойБазы) Тогда
МодульНастройкиТранспортаОбменаСообщениями = ОбщегоНазначения.ОбщийМодуль("РегистрыСведений.НастройкиТранспортаОбменаСообщениями");
СтруктураНастроекАутентификации = МодульНастройкиТранспортаОбменаСообщениями.НастройкиТранспортаWS(УзелИнформационнойБазы, ПараметрыАутентификации);
Иначе
СтруктураНастроекАутентификации = РегистрыСведений.НастройкиТранспортаОбменаДанными.НастройкиТранспортаWS(УзелИнформационнойБазы, ПараметрыАутентификации);
КонецЕсли;
КонецЕсли;
Попытка
ВерсииКорреспондента = ОбменДаннымиПовтИсп.ВерсииКорреспондента(СтруктураНастроекАутентификации);
Исключение
СтрокаСообщенияОбОшибке = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииУстановкаПодключенияКWebСервису(),
УровеньЖурналаРегистрации.Ошибка,,, СтрокаСообщенияОбОшибке);
Возврат Неопределено;
КонецПопытки;
ДоступныеВерсии = Новый Соответствие;
Для Каждого Версия Из СтрРазделить("3.0.1.1;2.1.1.7;2.0.1.6", ";", Ложь) Цикл
ДоступныеВерсии.Вставить(Версия, ВерсииКорреспондента.Найти(Версия) <> Неопределено
И (ОбщегоНазначенияКлиентСервер.СравнитьВерсии(Версия, МинимальнаяВерсия) >= 0));
КонецЦикла;
ДоступныеВерсии.Вставить("0.0.0.0", ОбщегоНазначенияКлиентСервер.СравнитьВерсии("0.0.0.0", МинимальнаяВерсия) >= 0);
WSПрокси = Неопределено;
Если ДоступныеВерсии.Получить("3.0.1.1") = Истина Тогда
WSПрокси = ПолучитьWSПрокси_3_0_1_1(СтруктураНастроекАутентификации, СтрокаСообщенияОбОшибке);
ДополнительныеПараметры.ТекущаяВерсия = "3.0.1.1";
ИначеЕсли ДоступныеВерсии.Получить("2.1.1.7") = Истина Тогда
WSПрокси = ПолучитьWSПрокси_2_1_1_7(СтруктураНастроекАутентификации, СтрокаСообщенияОбОшибке);
ДополнительныеПараметры.ТекущаяВерсия = "2.1.1.7";
ИначеЕсли ДоступныеВерсии.Получить("2.0.1.6") = Истина Тогда
WSПрокси = ПолучитьWSПрокси_2_0_1_6(СтруктураНастроекАутентификации, СтрокаСообщенияОбОшибке);
ДополнительныеПараметры.ТекущаяВерсия = "2.0.1.6";
ИначеЕсли ДоступныеВерсии.Получить("0.0.0.0") = Истина Тогда
WSПрокси = ПолучитьWSПрокси(СтруктураНастроекАутентификации, СтрокаСообщенияОбОшибке);
ДополнительныеПараметры.ТекущаяВерсия = "0.0.0.0";
Иначе
СтрокаСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Корреспондент не поддерживает требуемую версию ""%1"" интерфейса ""ОбменДанными"".'"),
МинимальнаяВерсия);
КонецЕсли;
Возврат WSПрокси;
КонецФункции
Процедура УдалитьНезначащиеСимволыВНастройкахПодключения(Настройки)
Для Каждого Настройка Из Настройки Цикл
Если ТипЗнч(Настройка.Значение) = Тип("Строка") Тогда
Настройки.Вставить(Настройка.Ключ, СокрЛП(Настройка.Значение));
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ЕстьПодключениеККорреспонденту(Знач Корреспондент,
Знач СтруктураНастроек,
СообщениеПользователю = "",
НастройкаСинхронизацииДанныхЗавершена = Истина,
ПолученоСообщениеДляСопоставленияДанных = Ложь) Экспорт
СтруктураНастроекОбмена = Новый Структура;
СтруктураНастроекОбмена.Вставить("ИмяПланаОбмена", ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(Корреспондент));
СтруктураНастроекОбмена.Вставить("УзелИнформационнойБазы", Корреспондент);
СтруктураНастроекОбмена.Вставить("КлючСообщенияЖурналаРегистрации",
НСтр("ru = 'Обмен данными.Проверка подключения'", ОбщегоНазначения.КодОсновногоЯзыка()));
СтруктураНастроекОбмена.Вставить("ТекущийУзелПланаОбмена",
ОбменДаннымиПовтИсп.ПолучитьЭтотУзелПланаОбмена(СтруктураНастроекОбмена.ИмяПланаОбмена));
СтруктураНастроекОбмена.Вставить("ТекущийУзелПланаОбменаКод",
ИдентификаторЭтогоУзлаДляОбмена(Корреспондент));
СтруктураНастроекОбмена.Вставить("ДействиеПриОбмене", Перечисления.ДействияПриОбмене.ВыгрузкаДанных); // Для проверки возможности перехода.
ПараметрыПрокси = Новый Структура;
ПараметрыПрокси.Вставить("ПараметрыАутентификации", Неопределено);
ПараметрыПрокси.Вставить("СтруктураНастроекАутентификации", СтруктураНастроек);
Прокси = Неопределено;
СостояниеНастройки = Неопределено;
Отказ = Ложь;
ИнициализироватьWSПроксиДляУправленияОбменомДанными(Прокси, СтруктураНастроекОбмена, ПараметрыПрокси, Отказ, СостояниеНастройки, СообщениеПользователю);
Если Отказ Тогда
СброситьПарольСинхронизацииДанных(Корреспондент);
НастройкаСинхронизацииДанныхЗавершена = Ложь;
Возврат Ложь;
КонецЕсли;
УстановитьПарольСинхронизацииДанных(Корреспондент, СтруктураНастроек.WSПароль);
НастройкаСинхронизацииДанныхЗавершена = СостояниеНастройки.НастройкаСинхронизацииДанныхЗавершена;
ПолученоСообщениеДляСопоставленияДанных = СостояниеНастройки.ПолученоСообщениеДляСопоставленияДанных;
Возврат СостояниеНастройки.НастройкаСуществует;
КонецФункции
// Выводит сообщение об ошибке и выставляет параметр Отказ в "Истина".
//
// Параметры:
// ТекстСообщения - Строка - текст сообщения.
// Отказ - Булево - признак отказа
//
Процедура СообщитьОбОшибке(ТекстСообщения, Отказ = Ложь) Экспорт
Отказ = Истина;
ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
КонецПроцедуры
// Получает таблицу правил выборочной регистрации объектов из параметров сеанса.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// ТаблицаЗначений - таблица реквизитов регистрации для всех объектов метаданных.
//
Функция ПолучитьПравилаВыборочнойРегистрацииОбъектовПС() Экспорт
Возврат ОбменДаннымиПовтИсп.ПолучитьПравилаВыборочнойРегистрацииОбъектовПС();
КонецФункции
// Выполняет загрузку правил для обмена данными (ПРО или ПКО) в ИБ.
//
Процедура ЗагрузитьПравилаДляОбменаДанными(Отказ,
Знач ИмяПланаОбмена,
Знач ВидПравил,
Знач ИмяМакетаПравил,
Знач ИмяМакетаПравилКорреспондента = "")
СтруктураЗаписи = Новый Структура;
СтруктураЗаписи.Вставить("ИмяПланаОбмена", ИмяПланаОбмена);
СтруктураЗаписи.Вставить("ВидПравил", ВидПравил);
Если Не ПустаяСтрока(ИмяМакетаПравилКорреспондента) Тогда
СтруктураЗаписи.Вставить("ИмяМакетаПравилКорреспондента", ИмяМакетаПравилКорреспондента);
КонецЕсли;
СтруктураЗаписи.Вставить("ИмяМакетаПравил", ИмяМакетаПравил);
СтруктураЗаписи.Вставить("ИсточникПравил", Перечисления.ИсточникиПравилДляОбменаДанными.МакетКонфигурации);
СтруктураЗаписи.Вставить("ИспользоватьФильтрВыборочнойРегистрацииОбъектов", Истина);
// Получаем набор записей регистра.
НаборЗаписей = ОбменДаннымиСлужебный.СоздатьНаборЗаписейРегистраСведений(СтруктураЗаписи, "ПравилаДляОбменаДанными");
// Добавляем только одну запись в новый набор записей.
НоваяЗапись = НаборЗаписей.Добавить();
// Заполняем значения свойств записи из структуры.
ЗаполнитьЗначенияСвойств(НоваяЗапись, СтруктураЗаписи);
// Загружаем правила для обмена данными в ИБ.
РегистрыСведений.ПравилаДляОбменаДанными.ЗагрузитьПравила(Отказ, НаборЗаписей[0]);
Если Не Отказ Тогда
НаборЗаписей.Записать();
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьОбновлениеВерсииТиповыхПравилДляОбменаДанными(ПравилаОбменаЗагруженныеИзФайла, ПравилаРегистрацииЗагруженныеИзФайла)
Отказ = Ложь;
ШаблонТекстаЗапроса =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(ПсевдонимТаблицыМетаданных.Ссылка) КАК Количество,
| ""&ИмяПланаОбмена"" КАК ИмяПланаОбмена
|ИЗ
| &ИмяТаблицыМетаданных КАК ПсевдонимТаблицыМетаданных";
ТекстЗапроса = "";
Для Каждого ИмяПланаОбмена Из ОбменДаннымиПовтИсп.ПланыОбменаБСП() Цикл
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
ТекстЗапроса = ТекстЗапроса + Символы.ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС;
КонецЕсли;
ТекстПодзапроса = СтрЗаменить(ШаблонТекстаЗапроса, "&ИмяТаблицыМетаданных", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("ПланОбмена.%1", ИмяПланаОбмена));
ТекстПодзапроса = СтрЗаменить(ТекстПодзапроса, "&ИмяПланаОбмена", ИмяПланаОбмена);
ТекстЗапроса = ТекстЗапроса + ТекстПодзапроса;
КонецЦикла;
Если ПустаяСтрока(ТекстЗапроса) Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
Результат = Запрос.Выполнить().Выгрузить();
ВыполненоОбновлениеПравил = Ложь;
Для Каждого ЗаписьПланаОбмена Из Результат Цикл
Если ЗаписьПланаОбмена.Количество <= 1
И Не ОбщегоНазначения.РазделениеВключено() Тогда // только ЭтотУзел
Продолжить;
КонецЕсли;
ИмяПланаОбмена = ЗаписьПланаОбмена.ИмяПланаОбмена;
Если ОбменДаннымиПовтИсп.ЕстьМакетПланаОбмена(ИмяПланаОбмена, "ПравилаОбмена")
И ОбменДаннымиПовтИсп.ЕстьМакетПланаОбмена(ИмяПланаОбмена, "ПравилаОбменаКорреспондента") Тогда
Если ПравилаОбменаЗагруженныеИзФайла.Найти(ИмяПланаОбмена) = Неопределено Тогда
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Выполняется обновление правил конвертации данных для плана обмена %1'"), ИмяПланаОбмена);
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Информация,,, ТекстСообщения);
ЗагрузитьПравилаДляОбменаДанными(Отказ, ИмяПланаОбмена, Перечисления.ВидыПравилДляОбменаДанными.ПравилаКонвертацииОбъектов,
"ПравилаОбмена", "ПравилаОбменаКорреспондента");
Если Не Отказ Тогда
ВыполненоОбновлениеПравил = Истина;
СтандартныеПодсистемыСервер.ОбновитьПараметрРаботыПрограммы(
"СтандартныеПодсистемы.ОбменДанными.ПравилаКонвертации." + ИмяПланаОбмена, Истина);
КонецЕсли;
Иначе
СтандартныеПодсистемыСервер.ОбновитьПараметрРаботыПрограммы(
"СтандартныеПодсистемы.ОбменДанными.ПравилаКонвертации." + ИмяПланаОбмена, Ложь);
КонецЕсли;
КонецЕсли;
Если ОбменДаннымиПовтИсп.ЕстьМакетПланаОбмена(ИмяПланаОбмена, "ПравилаРегистрации") Тогда
Если ПравилаРегистрацииЗагруженныеИзФайла.Найти(ИмяПланаОбмена) = Неопределено Тогда
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Выполняется обновление правил регистрации данных для плана обмена %1'"), ИмяПланаОбмена);
ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрацииОбменДанными(),
УровеньЖурналаРегистрации.Информация,,, ТекстСообщения);
ЗагрузитьПравилаДляОбменаДанными(Отказ, ИмяПланаОбмена, Перечисления.ВидыПравилДляОбменаДанными.ПравилаРегистрацииОбъектов, "ПравилаРегистрации");
Если Не Отказ Тогда
ВыполненоОбновлениеПравил = Истина;
СтандартныеПодсистемыСервер.ОбновитьПараметрРаботыПрограммы(
"СтандартныеПодсистемы.ОбменДанными.ПравилаРегистрации." + ИмяПланаОбмена, Истина);
КонецЕсли;
Иначе
СтандартныеПодсистемыСервер.ОбновитьПараметрРаботыПрограммы(
"СтандартныеПодсистемы.ОбменДанными.ПравилаРегистрации." + ИмяПланаОбмена, Ложь);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Отказ Тогда
ВызватьИсключение НСтр("ru = 'При обновлении правил обмена данными возникли ошибки (см. Журнал регистрации).'");
КонецЕсли;
Если ВыполненоОбновлениеПравил Тогда
ОбменДаннымиСлужебный.СброситьКэшМеханизмаРегистрацииОбъектов();
КонецЕсли;
КонецПроцедуры
// Получает индекс картинки для вывода в таблице статистики сопоставления объектов.
//
Функция ИндексКартинкиТаблицыИнформацииСтатистики(Знач КоличествоОбъектовНесопоставленных, Знач ДанныеУспешноЗагружены) Экспорт
Возврат ?(КоличествоОбъектовНесопоставленных = 0, ?(ДанныеУспешноЗагружены = Истина, 2, 0), 1);
КонецФункции
// Выполняет проверку того, что размер файла сообщения обмена превышает допустимый размер.
//
// Возвращаемое значение:
// Истина - если размер файла больше допустимого, иначе Ложь.
//
Функция РазмерСообщенияОбменаПревышаетДопустимый(Знач ИмяФайла, Знач МаксимальныйДопустимыйРазмерСообщения) Экспорт
// Возвращаемое значение функции.
Результат = Ложь;
Файл = Новый Файл(ИмяФайла);
Если Файл.Существует() И Файл.ЭтоФайл() Тогда
Если МаксимальныйДопустимыйРазмерСообщения <> 0 Тогда
РазмерПакета = Окр(Файл.Размер() / 1024, 0, РежимОкругления.Окр15как20);
Если РазмерПакета > МаксимальныйДопустимыйРазмерСообщения Тогда
СтрокаСообщения = НСтр("ru = 'Размер исходящего пакета составил %1 Кбайт, что превышает допустимое ограничение %2 Кбайт.'");
СтрокаСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщения, Строка(РазмерПакета), Строка(МаксимальныйДопустимыйРазмерСообщения));
СообщитьОбОшибке(СтрокаСообщения, Результат);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция УстановленПризнакНачальнойВыгрузкиДанных(УзелИнформационнойБазы) Экспорт
УстановитьПривилегированныйРежим(Истина);
Возврат РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.УстановленПризнакНачальнойВыгрузкиДанных(УзелИнформационнойБазы);
КонецФункции
// Выполняет загрузку сообщения обмена, которое содержало
// изменения конфигурации, до обновления информационной базы.
//
Процедура ЗагрузитьСообщениеПередОбновлениемИнформационнойБазы()
Если ОбменДаннымиСлужебный.РежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском(
"ПропуститьЗагрузкуСообщенияОбменаДаннымиПередЗапуском") Тогда
Возврат;
КонецЕсли;
Если ПолучитьФункциональнуюОпцию("ИспользоватьСинхронизациюДанных") Тогда
УзелИнформационнойБазы = ГлавныйУзел();
Если УзелИнформационнойБазы <> Неопределено Тогда
УстановитьПривилегированныйРежим(Истина);
УстановитьРежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском("ЗагрузкаРазрешена", Истина);
УстановитьПривилегированныйРежим(Ложь);
Попытка
// Обновление правил регистрации объектов выполняем до загрузки данных.
ВыполнитьОбновлениеПравилДляОбменаДанными();
ВидТранспорта = РегистрыСведений.НастройкиТранспортаОбменаДанными.ВидТранспортаСообщенийОбменаПоУмолчанию(УзелИнформационнойБазы);
Отказ = Ложь;
ПараметрыОбмена = ПараметрыОбмена();
ПараметрыОбмена.ВидТранспортаСообщенийОбмена = ВидТранспорта;
ПараметрыОбмена.ВыполнятьЗагрузку = Истина;
ПараметрыОбмена.ВыполнятьВыгрузку = Ложь;
ВыполнитьОбменДаннымиДляУзлаИнформационнойБазы(УзелИнформационнойБазы, ПараметрыОбмена, Отказ);
// Режим повтора требует включения в следующих случаях.
// Случай 1. Получены метаданные с новой версией конфигурации, т.е. будет выполнено обновление ИБ.
// Е если Отказ = Истина, тогда недопустимо продолжение, т.к. могут быть созданы дубли генерируемых данных,
// - если Отказ = Ложь, тогда возможна ошибка при обновлении ИБ, возможно требующая повторной загрузки сообщения.
// Случай 2. Получены метаданные с той же версией конфигурации, т.е. не будет выполнено обновление ИБ.
// Е если Отказ = Истина, тогда возможна ошибка при продолжении запуска, например, из-за того, что
// не были загружены предопределенные элементы,
// - если Отказ = Ложь, тогда продолжение возможно, т.к. выгрузку можно сделать позднее (если же
// выгрузка не выполняется успешно, тогда позднее можно получить и новое сообщение для загрузки).
Если Отказ ИЛИ ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы() Тогда
ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
КонецЕсли;
Если Отказ Тогда
ВызватьИсключение НСтр("ru = 'Получение данных из главного узла завершилось с ошибками.'");
КонецЕсли;
Исключение
УстановитьПривилегированныйРежим(Истина);
УстановитьРежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском("ЗагрузкаРазрешена", Ложь);
УстановитьПривилегированныйРежим(Ложь);
ВызватьИсключение;
КонецПопытки;
УстановитьПривилегированныйРежим(Истина);
УстановитьРежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском("ЗагрузкаРазрешена", Ложь);
УстановитьПривилегированныйРежим(Ложь);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Сбрасывает признак повторения загрузки при ошибке загрузки или обновления.
Процедура ОтключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском() Экспорт
УстановитьПривилегированныйРежим(Истина);
Если Константы.ПовторитьЗагрузкуСообщенияОбменаДаннымиПередЗапуском.Получить() Тогда
Константы.ПовторитьЗагрузкуСообщенияОбменаДаннымиПередЗапуском.Установить(Ложь);
КонецЕсли;
КонецПроцедуры
// Выполняет загрузку и выгрузку сообщения обмена, которое
// содержало изменения конфигурации, которые не потребовали
// обновления информационной базы.
//
Процедура ВыполнитьСинхронизациюПриОтсутствииОбновленияИнформационнойБазы(
ПриЗапускеКлиентскогоПриложения, Перезапустить)
Если Не ЗагрузитьСообщениеОбменаДанными() Тогда
// Если загрузка сообщения обмена была отменена, а версия конфигурации
// в изменениях метаданных не была повышена, тогда повторение загрузки нужно отключить.
ОтключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
Возврат;
КонецЕсли;
Если КонфигурацияИзменена() Тогда
// Изменения конфигурации загружены, но не применены.
// Загружать сообщение еще рано.
Возврат;
КонецЕсли;
НачатьТранзакцию();
Попытка
ЗагрузитьСообщениеПередОбновлениемИнформационнойБазы();
ЗафиксироватьТранзакцию();
Исключение
Если КонфигурацияИзменена() Тогда
Если Не ОбменДаннымиСлужебный.РежимЗагрузкиСообщенияОбменаДаннымиПередЗапуском(
"СообщениеПолученоИзКэша") Тогда
// Переход с конфигурации, в которой не использовалось кэширование
// сообщения обмена. Возможно, новое загруженное сообщение содержит
// новые изменения конфигурации. Определить возврат к конфигурации
// базы данных невозможно. Следует зафиксировать транзакцию и продолжить
// запуск без выгрузки нового сообщения обмена.
ЗафиксироватьТранзакцию();
Возврат;
Иначе
// Вновь получены изменения конфигурации, значит
// был выполнен возврат к конфигурации базы данных.
// Следует отменить загрузку.
ОтменитьТранзакцию();
УстановитьПривилегированныйРежим(Истина);
Константы.ЗагрузитьСообщениеОбменаДанными.Установить(Ложь);
ОчиститьСообщениеОбменаДаннымиИзГлавногоУзла();
УстановитьПривилегированныйРежим(Ложь);
ЗаписатьСобытиеПолученияДанных(ГлавныйУзел(),
НСтр("ru = 'Обнаружен возврат к конфигурации базы данных.
|Синхронизация отменена.'"));
Возврат;
КонецЕсли;
КонецЕсли;
// Если был выполнен возврат к конфигурации базы данных,
// но конфигуратор не был закрыт. Тогда новое сообщение не загружено.
// Перейдя в режим повтора и в этом случае, можно будет нажать кнопку
// "Не синхронизировать и продолжить" после чего возврат к конфигурации
// базы данных будет закончен успешно.
ЗафиксироватьТранзакцию();
ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
Если ПриЗапускеКлиентскогоПриложения Тогда
Перезапустить = Истина;
Возврат;
КонецЕсли;
ВызватьИсключение;
КонецПопытки;
ВыгрузитьСообщениеПослеОбновленияИнформационнойБазы();
КонецПроцедуры
Функция УникальноеИмяФайлаСообщенияОбмена(Расширение = "xml") Экспорт
Результат = "Message{GUID}." + Расширение;
Результат = СтрЗаменить(Результат, "GUID", Строка(Новый УникальныйИдентификатор));
Возврат Результат;
КонецФункции
Функция ЭтоПодчиненныйУзелРИБ() Экспорт
Возврат ГлавныйУзел() <> Неопределено;
КонецФункции
// Возвращает массив номеров версий, поддерживаемых интерфейсом корреспондента для подсистемы ОбменДанными.
//
// Параметры:
// ВнешнееСоединение - объект COM-соединение, которое используется для работы с корреспондентом.
//
// Возвращаемое значение:
// Массив номеров версий, поддерживаемых интерфейсом корреспондента.
//
Функция ВерсииИнтерфейсаЧерезВнешнееСоединение(ВнешнееСоединение) Экспорт
Возврат ОбщегоНазначения.ПолучитьВерсииИнтерфейсаЧерезВнешнееСоединение(ВнешнееСоединение, "ОбменДанными");
КонецФункции
// Параметры:
// ИнформацияОбОшибке - ИнформацияОбОшибке - информация об ошибке.
//
Функция КраткоеПредставлениеПервойОшибки(ИнформацияОбОшибке)
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
Возврат КраткоеПредставлениеПервойОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
Возврат КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
КонецФункции
// Создает временный каталог сообщений обмена.
// Фиксирует имя каталога в регистре для последующего его удаления.
//
Функция СоздатьВременныйКаталогСообщенийОбмена(ИдентификаторКаталога = Неопределено) Экспорт
Результат = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(КаталогВременногоХранилищаФайлов(), ИмяВременногоКаталогаСообщенийОбмена());
СоздатьКаталог(Результат);
Если Не ОбщегоНазначения.ИнформационнаяБазаФайловая() Тогда
УстановитьПривилегированныйРежим(Истина);
ИдентификаторКаталога = ПоместитьФайлВХранилище(Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВариантОбменаДанными(Знач Корреспондент) Экспорт
Результат = "Синхронизация";
Если ОбменДаннымиПовтИсп.ЭтоУзелРаспределеннойИнформационнойБазы(Корреспондент) Тогда
Возврат Результат;
КонецЕсли;
ИменаРеквизитов = ОбщегоНазначения.ИменаРеквизитовПоТипу(Корреспондент, Тип("ПеречислениеСсылка.РежимыВыгрузкиОбъектовОбмена"));
ЗначенияРеквизитов = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Корреспондент, ИменаРеквизитов);
Для Каждого Реквизит Из ЗначенияРеквизитов Цикл
Если Реквизит.Значение = Перечисления.РежимыВыгрузкиОбъектовОбмена.ВыгружатьВручную
Или Реквизит.Значение = Перечисления.РежимыВыгрузкиОбъектовОбмена.НеВыгружать Тогда
Результат = "ПолучениеИОтправка";
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Параметры:
// Контекст - Структура - структура со значениями для переноса в объект.
// Объект - ОбработкаОбъект.СопоставлениеОбъектовИнформационныхБаз - объект-приемник данных.
//
Процедура ЗагрузитьКонтекстОбъекта(Знач Контекст, Знач Объект) Экспорт
Для Каждого Реквизит Из Объект.Метаданные().Реквизиты Цикл
Если Контекст.Свойство(Реквизит.Имя) Тогда
Объект[Реквизит.Имя] = Контекст[Реквизит.Имя];
КонецЕсли;
КонецЦикла;
Для Каждого ТабличнаяЧасть Из Объект.Метаданные().ТабличныеЧасти Цикл
Если Контекст.Свойство(ТабличнаяЧасть.Имя) Тогда
Объект[ТабличнаяЧасть.Имя].Загрузить(Контекст[ТабличнаяЧасть.Имя]);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Для внутреннего использования.
//
// Параметры:
// Объект - СправочникОбъект, ДокументОбъект и т.п. - объект данных.
//
// Возвращаемое значение:
// Структура - объект данных в виде структуры. Ключи соответствуют именам реквизитов и табличных частей,
// значения - соответствующим им значениям.
//
Функция ПолучитьКонтекстОбъекта(Знач Объект) Экспорт
Результат = Новый Структура;
МетаданныеОбъекта = Объект.Метаданные(); // ОбъектМетаданных
Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл
Результат.Вставить(Реквизит.Имя, Объект[Реквизит.Имя]);
КонецЦикла;
Для Каждого ТабличнаяЧасть Из МетаданныеОбъекта.ТабличныеЧасти Цикл
Результат.Вставить(ТабличнаяЧасть.Имя, Объект[ТабличнаяЧасть.Имя].Выгрузить());
КонецЦикла;
Возврат Результат;
КонецФункции
// Параметры:
// Таблица - ТаблицаЗначений - объект-приемник данных.
// Дерево - КоллекцияСтрокДереваЗначений - объект-источник данных.
//
Процедура РазвернутьДеревоЗначений(Таблица, Дерево)
Для Каждого СтрокаДерева Из Дерево Цикл
ЗаполнитьЗначенияСвойств(Таблица.Добавить(), СтрокаДерева);
Если СтрокаДерева.Строки.Количество() > 0 Тогда
РазвернутьДеревоЗначений(Таблица, СтрокаДерева.Строки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция КоличествоДнейРазницы(Знач Дата1, Знач Дата2)
Возврат Цел((НачалоДня(Дата2) - НачалоДня(Дата1)) / 86400);
КонецФункции
// Параметры:
// ТаблицаЗначений - ТаблицаЗначений - таблица значений для преобразования
//
Функция ТаблицаВМассивСтруктур(Знач ТаблицаЗначений)
Результат = Новый Массив;
ИменаКолонок = "";
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
ИменаКолонок = ИменаКолонок + "," + Колонка.Имя;
КонецЦикла;
ИменаКолонок = Сред(ИменаКолонок, 2);
Для Каждого Строка Из ТаблицаЗначений Цикл
СтруктураСтроки = Новый Структура(ИменаКолонок);
ЗаполнитьЗначенияСвойств(СтруктураСтроки, Строка);
Результат.Добавить(СтруктураСтроки);
КонецЦикла;
Возврат Результат;
КонецФункции
// Проверка на различие версии корреспондента в правилах текущей и другой программы.
//
Функция РазличаютсяВерсииКорреспондента(ИмяПланаОбмена, КлючСообщенияЖурналаРегистрации, ВерсияВЭтойПрограмме,
ВерсияВДругойПрограмме, ТекстСообщения, ПараметрыВнешнегоСоединения = Неопределено) Экспорт
ВерсияВЭтойПрограмме = ?(ЗначениеЗаполнено(ВерсияВЭтойПрограмме), ВерсияВЭтойПрограмме, ВерсияКорреспондентаВПравилах(ИмяПланаОбмена));
Если ЗначениеЗаполнено(ВерсияВЭтойПрограмме) И ЗначениеЗаполнено(ВерсияВДругойПрограмме)
И ЗначениеНастройкиПланаОбмена(ИмяПланаОбмена, "ПредупреждатьОНесоответствииВерсийПравилОбмена") Тогда
ВерсияВЭтойПрограммеБезНомераСборки = ОбщегоНазначенияКлиентСервер.ВерсияКонфигурацииБезНомераСборки(ВерсияВЭтойПрограмме);
ВерсияВДругойПрограммеБезНомераСборки = ОбщегоНазначенияКлиентСервер.ВерсияКонфигурацииБезНомераСборки(ВерсияВДругойПрограмме);
Если ВерсияВЭтойПрограммеБезНомераСборки <> ВерсияВДругойПрограммеБезНомераСборки Тогда
СинонимПланаОбмена = Метаданные.ПланыОбмена[ИмяПланаОбмена].Синоним;
ШаблонСообщения = НСтр("ru = 'Синхронизация данных может быть выполнена некорректно, т.к. версия программы ""%1"" (%2) в правилах конвертации этой программы отличается от версии %3 в правилах конвертации в другой программе. Убедитесь, что загружены актуальные правила, подходящие для используемых версий обеих программ.'");
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонСообщения, СинонимПланаОбмена, ВерсияВЭтойПрограммеБезНомераСборки, ВерсияВДругойПрограммеБезНомераСборки);
ЗаписьЖурналаРегистрации(КлючСообщенияЖурналаРегистрации, УровеньЖурналаРегистрации.Предупреждение,,, ТекстСообщения);
Если ПараметрыВнешнегоСоединения <> Неопределено
И ОбщегоНазначенияКлиентСервер.СравнитьВерсии("2.2.3.18", ПараметрыВнешнегоСоединения.ВерсияБСППоВнешнемуСоединению) <= 0
И ПараметрыВнешнегоСоединения.ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.ПредупреждатьОНесоответствииВерсийПравилОбмена(ИмяПланаОбмена) Тогда
СинонимПланаОбменаДругойПрограммы = ПараметрыВнешнегоСоединения.УзелИнформационнойБазы.Метаданные().Синоним;
ТекстСообщенияВнешнееСоединение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонСообщения,
СинонимПланаОбменаДругойПрограммы, ВерсияВДругойПрограммеБезНомераСборки, ВерсияВЭтойПрограммеБезНомераСборки);
ПараметрыВнешнегоСоединения.ВнешнееСоединение.ЗаписьЖурналаРегистрации(ПараметрыВнешнегоСоединения.КлючСообщенияЖурналаРегистрации,
ПараметрыВнешнегоСоединения.ВнешнееСоединение.УровеньЖурналаРегистрации.Предупреждение,,, ТекстСообщенияВнешнееСоединение);
КонецЕсли;
Если ПараметрыСеанса.ОшибкаРасхожденияВерсийПриПолученииДанных.ПроверятьРасхождениеВерсий Тогда
СтруктураПроверки = Новый Структура(ПараметрыСеанса.ОшибкаРасхожденияВерсийПриПолученииДанных);
СтруктураПроверки.ЕстьОшибка = Истина;
СтруктураПроверки.ТекстОшибки = ТекстСообщения;
СтруктураПроверки.ПроверятьРасхождениеВерсий = Ложь;
ПараметрыСеанса.ОшибкаРасхожденияВерсийПриПолученииДанных = Новый ФиксированнаяСтруктура(СтруктураПроверки);
Возврат Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ИнициализироватьПараметрыПроверкиРасхожденияВерсий(ПроверятьРасхождениеВерсий) Экспорт
УстановитьПривилегированныйРежим(Истина);
СтруктураПроверки = Новый Структура(ПараметрыСеанса.ОшибкаРасхожденияВерсийПриПолученииДанных);
СтруктураПроверки.ПроверятьРасхождениеВерсий = ПроверятьРасхождениеВерсий;
СтруктураПроверки.ЕстьОшибка = Ложь;
ПараметрыСеанса.ОшибкаРасхожденияВерсийПриПолученииДанных = Новый ФиксированнаяСтруктура(СтруктураПроверки);
Возврат ПараметрыСеанса.ОшибкаРасхожденияВерсийПриПолученииДанных;
КонецФункции
Функция ОшибкаРасхожденияВерсийПриПолученииДанных() Экспорт
УстановитьПривилегированныйРежим(Истина);
Возврат ПараметрыСеанса.ОшибкаРасхожденияВерсийПриПолученииДанных;
КонецФункции
Функция ВерсияКорреспондентаВПравилах(ИмяПланаОбмена)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ПравилаДляОбменаДанными.ПравилаЗачитанныеКорреспондента,
| ПравилаДляОбменаДанными.ВидПравил
|ИЗ
| РегистрСведений.ПравилаДляОбменаДанными КАК ПравилаДляОбменаДанными
|ГДЕ
| ПравилаДляОбменаДанными.ИмяПланаОбмена = &ИмяПланаОбмена
| И ПравилаДляОбменаДанными.ПравилаЗагружены = ИСТИНА
| И ПравилаДляОбменаДанными.ВидПравил = ЗНАЧЕНИЕ(Перечисление.ВидыПравилДляОбменаДанными.ПравилаКонвертацииОбъектов)";
Запрос.УстановитьПараметр("ИмяПланаОбмена", ИмяПланаОбмена);
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Выборка.Следующий();
СтруктураПравил = Выборка.ПравилаЗачитанныеКорреспондента.Получить().Конвертация;
ВерсияКорреспондента = Неопределено;
СтруктураПравил.Свойство("ВерсияКонфигурацииИсточника", ВерсияКорреспондента);
Возврат ВерсияКорреспондента;
КонецЕсли;
Возврат Неопределено;
КонецФункции
// Возвращает расширенное представление объекта.
//
Функция ПредставлениеОбъекта(ПараметрОбъект) Экспорт
Если ПараметрОбъект = Неопределено Тогда
Возврат "";
КонецЕсли;
МетаданныеОбъекта = ?(ТипЗнч(ПараметрОбъект) = Тип("Строка"), Метаданные.НайтиПоПолномуИмени(ПараметрОбъект), ПараметрОбъект);
// Реквизитов представления может не быть, обходим через структуру.
Представление = Новый Структура("РасширенноеПредставлениеОбъекта, ПредставлениеОбъекта");
ЗаполнитьЗначенияСвойств(Представление, МетаданныеОбъекта);
Если Не ПустаяСтрока(Представление.РасширенноеПредставлениеОбъекта) Тогда
Возврат Представление.РасширенноеПредставлениеОбъекта;
ИначеЕсли Не ПустаяСтрока(Представление.ПредставлениеОбъекта) Тогда
Возврат Представление.ПредставлениеОбъекта;
КонецЕсли;
Возврат МетаданныеОбъекта.Представление();
КонецФункции
// Возвращает расширенное представление списка объектов.
//
Функция ПредставлениеСпискаОбъектов(ПараметрОбъект) Экспорт
Если ПараметрОбъект = Неопределено Тогда
Возврат "";
КонецЕсли;
МетаданныеОбъекта = ?(ТипЗнч(ПараметрОбъект) = Тип("Строка"), Метаданные.НайтиПоПолномуИмени(ПараметрОбъект), ПараметрОбъект);
// Реквизитов представления может не быть, обходим через структуру.
Представление = Новый Структура("РасширенноеПредставлениеСписка, ПредставлениеСписка");
ЗаполнитьЗначенияСвойств(Представление, МетаданныеОбъекта);
Если Не ПустаяСтрока(Представление.РасширенноеПредставлениеСписка) Тогда
Возврат Представление.РасширенноеПредставлениеСписка;
ИначеЕсли Не ПустаяСтрока(Представление.ПредставлениеСписка) Тогда
Возврат Представление.ПредставлениеСписка;
КонецЕсли;
Возврат МетаданныеОбъекта.Представление();
КонецФункции
// Возвращает флаг доступности выгрузки для указанной ссылке на узле.
//
// Параметры:
// УзелОбмена - ПланОбменаСсылка - узел плана обмена, возможность выгрузки по которому проверяется.
// Ссылка - Произвольный - проверяемый объект.
// ДополнительныеСвойства - Структура - дополнительные свойства, передаваемыми через объект.
//
// Возвращаемое значение:
// Булево - флаг разрешения
//
Функция ВыгрузкаСсылкиРазрешена(УзелОбмена, Ссылка, ДополнительныеСвойства = Неопределено) Экспорт
Если Ссылка.Пустая() Тогда
Возврат Ложь;
КонецЕсли;
ОбъектРегистрации = Ссылка.ПолучитьОбъект();
Если ОбъектРегистрации = Неопределено Тогда
// Объект удален, можно всегда.
Возврат Истина;
КонецЕсли;
Если ДополнительныеСвойства <> Неопределено Тогда
СтруктураРеквизитов = Новый Структура("ДополнительныеСвойства");
ЗаполнитьЗначенияСвойств(СтруктураРеквизитов, ОбъектРегистрации);
ДополнительныеСвойстваОбъекта = СтруктураРеквизитов.ДополнительныеСвойства;
Если ТипЗнч(ДополнительныеСвойстваОбъекта) = Тип("Структура") Тогда
Для Каждого КлючЗначение Из ДополнительныеСвойства Цикл
ДополнительныеСвойстваОбъекта.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);
КонецЦикла;
КонецЕсли;
КонецЕсли;
// Проверка возможности выгрузки.
Отправка = ОтправкаЭлементаДанных.Авто;
ОбменДаннымиСобытия.ПриОтправкеДанныхКорреспонденту(ОбъектРегистрации, Отправка, , УзелОбмена);
Возврат Отправка = ОтправкаЭлементаДанных.Авто;
КонецФункции
// Возвращает флаг доступности выгрузки вручную для указанной ссылке на узле.
//
// Параметры:
// УзелОбмена - ПланОбменаСсылка - узел плана обмена, возможность выгрузки по которому проверяется.
// Ссылка - Произвольный - проверяемый объект.
//
// Возвращаемое значение:
// Булево - флаг разрешения
//
Функция ВыгрузкаСсылкиИзИнтерактивногоДополненияРазрешена(УзелОбмена, Ссылка) Экспорт
// В случае вызова из схемы компоновки данных при работе механизма дополнения к выгрузке
// включается безопасный режим, который нужно отключить на время выполнения этой функции.
УстановитьОтключениеБезопасногоРежима(Истина);
ДополнительныеСвойства = Новый Структура("ИнтерактивноеДополнениеВыгрузки", Истина);
Возврат ВыгрузкаСсылкиРазрешена(УзелОбмена, Ссылка, ДополнительныеСвойства);
КонецФункции
// Обертки фоновых процедур интерактивного изменения выгрузки.
//
Процедура ИнтерактивноеИзменениеВыгрузки_СформироватьТабличныйДокументПользователя(Параметры, АдресРезультата) Экспорт
ОбъектОтчета = ИнтерактивноеИзменениеВыгрузки_ОбъектПоНастройкам(Параметры.СтруктураОбработки);
РезультатВыполнения = ОбъектОтчета.СформироватьТабличныйДокументПользователя(Параметры.ПолноеИмяМетаданных, Параметры.Представление, Параметры.УпрощенныйРежим);
ПоместитьВоВременноеХранилище(РезультатВыполнения, АдресРезультата);
КонецПроцедуры
Процедура ИнтерактивноеИзменениеВыгрузки_СформироватьДеревоЗначений(Параметры, АдресРезультата) Экспорт
ОбъектОтчета = ИнтерактивноеИзменениеВыгрузки_ОбъектПоНастройкам(Параметры.СтруктураОбработки);
Результат = ОбъектОтчета.СформироватьДеревоЗначений();
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецПроцедуры
// Параметры:
// Настройки - Структура:
// * НастройкиКомпоновщикаОтбораВсехДокументов - НастройкиКомпоновкиДанных
//
Функция ИнтерактивноеИзменениеВыгрузки_ОбъектПоНастройкам(Знач Настройки)
ОбъектОтчета = Обработки.ИнтерактивноеИзменениеВыгрузки.Создать();
ЗаполнитьЗначенияСвойств(ОбъектОтчета, Настройки, , "КомпоновщикОтбораВсехДокументов");
// Компоновщик конструируем по частям.
Данные = ОбъектОтчета.КомпоновщикНастроекОбщегоОтбора();
Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Данные.СхемаКомпоновки));
Компоновщик.ЗагрузитьНастройки(Данные.Настройки);
ОбъектОтчета.КомпоновщикОтбораВсехДокументов = Компоновщик;
ЭлементыОтбора = ОбъектОтчета.КомпоновщикОтбораВсехДокументов.Настройки.Отбор.Элементы;
ЭлементыОтбора.Очистить();
ОбъектОтчета.ДобавитьЗначенияОтбораКомпоновки(
ЭлементыОтбора, Настройки.НастройкиКомпоновщикаОтбораВсехДокументов.Отбор.Элементы);
Возврат ОбъектОтчета;
КонецФункции
// Возвращает список ролей профиля групп доступа "Синхронизация данных с другими программами".
//
Функция РолиПрофиляДоступаСинхронизацияДанныхСДругимиПрограммами()
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ВерсионированиеОбъектов") Тогда
Возврат "ВыполнениеСинхронизацииДанных, УдаленныйДоступБазоваяФункциональность, ЧтениеИнформацииОВерсияхОбъектов";
Иначе
Возврат "ВыполнениеСинхронизацииДанных, УдаленныйДоступБазоваяФункциональность";
КонецЕсли;
КонецФункции
// См. ТекущиеДелаПереопределяемый.ПриОпределенииОбработчиковТекущихДел
Процедура ПриЗаполненииСпискаТекущихДелПредупрежденияСинхронизации(ТекущиеДела)
МодульТекущиеДелаСервер = ОбщегоНазначения.ОбщийМодуль("ТекущиеДелаСервер");
Если Не ПравоДоступа("Просмотр", Метаданные.РегистрыСведений.РезультатыОбменаДанными)
Или МодульТекущиеДелаСервер.ДелоОтключено("ПредупрежденияПриСинхронизации") Тогда
Возврат;
КонецЕсли;
ПланыОбменаБСП = ОбменДаннымиПовтИсп.ПланыОбменаБСП();
Если ПланыОбменаБСП.Количество() > 0 Тогда
ТаблицаМонитора = ТаблицаМонитораОбменаДанными(ПланыОбменаБСП);
КоличествоНерассмотренныхПроблем = КоличествоНерассмотренныхПроблем(
ТаблицаМонитора.ВыгрузитьКолонку("УзелИнформационнойБазы"));
Иначе
КоличествоНерассмотренныхПроблем = 0;
КонецЕсли;
// Процедура вызывается только при наличии подсистемы "Текущие дела", поэтому здесь
// не делается проверка существования подсистемы.
Разделы = МодульТекущиеДелаСервер.РазделыДляОбъекта(Метаданные.ОбщиеФормы.СинхронизацияДанных.ПолноеИмя());
Для Каждого Раздел Из Разделы Цикл
ИдентификаторПредупрежденияПриСинхронизации = "ПредупрежденияПриСинхронизации" + СтрЗаменить(Раздел.ПолноеИмя(), ".", "");
Дело = ТекущиеДела.Добавить();
Дело.Идентификатор = ИдентификаторПредупрежденияПриСинхронизации;
Дело.ЕстьДела = КоличествоНерассмотренныхПроблем > 0;
Дело.Представление = НСтр("ru = 'Предупреждения при синхронизации'");
Дело.Количество = КоличествоНерассмотренныхПроблем;
Дело.Форма = "РегистрСведений.РезультатыОбменаДанными.Форма.Форма";
Дело.Владелец = Раздел;
КонецЦикла;
КонецПроцедуры
// См. ТекущиеДелаПереопределяемый.ПриОпределенииОбработчиковТекущихДел
Процедура ПриЗаполненииСпискаТекущихДелНеобходимоОбновление(ТекущиеДела)
МодульТекущиеДелаСервер = ОбщегоНазначения.ОбщийМодуль("ТекущиеДелаСервер");
Если Не ПравоДоступа("Администрирование", Метаданные)
Или МодульТекущиеДелаСервер.ДелоОтключено("НеобходимоОбновлениеОбменДанными") Тогда
Возврат;
КонецЕсли;
ТребуетсяУстановкаОбновления = ТребуетсяУстановкаОбновления();
// Процедура вызывается только при наличии подсистемы "Текущие дела", поэтому здесь
// не делается проверка существования подсистемы.
Разделы = МодульТекущиеДелаСервер.РазделыДляОбъекта(Метаданные.ОбщиеФормы.СинхронизацияДанных.ПолноеИмя());
Для Каждого Раздел Из Разделы Цикл
ИдентификаторНеобходимоОбновление = "НеобходимоОбновлениеОбменДанными" + СтрЗаменить(Раздел.ПолноеИмя(), ".", "");
Дело = ТекущиеДела.Добавить();
Дело.Идентификатор = ИдентификаторНеобходимоОбновление;
Дело.ЕстьДела = ТребуетсяУстановкаОбновления;
Дело.Важное = Истина;
Дело.Представление = НСтр("ru = 'Обновить версию программы'");
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбновлениеКонфигурации") Тогда
МодульОбновлениеКонфигурации = ОбщегоНазначения.ОбщийМодуль("ОбновлениеКонфигурации");
ПараметрыФормы = Новый Структура("ЗавершениеРаботыСистемы, ПолученоОбновлениеКонфигурации", Ложь, Ложь);
Дело.Форма = МодульОбновлениеКонфигурации.ИмяФормыУстановкиОбновления();
Дело.ПараметрыФормы = ПараметрыФормы;
Иначе
Дело.Форма = "ОбщаяФорма.ДополнительноеОписание";
Дело.ПараметрыФормы = Новый Структура("Заголовок,ИмяМакета",
НСтр("ru = 'Установка обновления'"), "ИнструкцияКакВыполнитьУстановкуОбновленияВручную");
КонецЕсли;
Дело.Владелец = Раздел;
КонецЦикла;
КонецПроцедуры
// См. ТекущиеДелаПереопределяемый.ПриОпределенииОбработчиковТекущихДел.
Процедура ПриЗаполненииСпискаТекущихДелПроверитьСовместимостьСТекущейВерсией(ТекущиеДела)
МодульТекущиеДелаСервер = ОбщегоНазначения.ОбщийМодуль("ТекущиеДелаСервер");
Если Не ПравоДоступа("Редактирование", Метаданные.РегистрыСведений.ПравилаДляОбменаДанными)
Или МодульТекущиеДелаСервер.ДелоОтключено("ПравилаОбмена") Тогда
Возврат;
КонецЕсли;
// Если в командном интерфейсе нет раздела к которому относится регистр сведений, дело не добавляется.
Разделы = МодульТекущиеДелаСервер.РазделыДляОбъекта("РегистрСведений.ПравилаДляОбменаДанными");
Если Разделы.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ВывестиДело = Истина;
ПровереноНаВерсию = ХранилищеОбщихНастроек.Загрузить("ТекущиеДела", "ПланыОбмена");
Если ПровереноНаВерсию <> Неопределено Тогда
ВерсияМассив = СтрРазделить(Метаданные.Версия, ".");
ТекущаяВерсия = ВерсияМассив[0] + ВерсияМассив[1] + ВерсияМассив[2];
Если ПровереноНаВерсию = ТекущаяВерсия Тогда
ВывестиДело = Ложь; // Дополнительные отчеты и обработки проверены на текущей версии.
КонецЕсли;
КонецЕсли;
ПланыОбменаСПравиламиИзФайла = ПланыОбменаСПравиламиИзФайла();
Для Каждого Раздел Из Разделы Цикл
ИдентификаторРаздела = "ПроверитьСовместимостьСТекущейВерсией" + СтрЗаменить(Раздел.ПолноеИмя(), ".", "");
// Добавление дела.
Дело = ТекущиеДела.Добавить();
Дело.Идентификатор = "ПравилаОбмена";
Дело.ЕстьДела = ВывестиДело И ПланыОбменаСПравиламиИзФайла > 0;
Дело.Представление = НСтр("ru = 'Правила обмена'");
Дело.Количество = ПланыОбменаСПравиламиИзФайла;
Дело.Форма = "РегистрСведений.ПравилаДляОбменаДанными.Форма.ПроверкаСинхронизацииДанных";
Дело.Владелец = ИдентификаторРаздела;
// Проверка наличия группы дела. Если группа отсутствует - добавляем.
ГруппаДела = ТекущиеДела.Найти(ИдентификаторРаздела, "Идентификатор");
Если ГруппаДела = Неопределено Тогда
ГруппаДела = ТекущиеДела.Добавить();
ГруппаДела.Идентификатор = ИдентификаторРаздела;
ГруппаДела.ЕстьДела = Дело.ЕстьДела;
ГруппаДела.Представление = НСтр("ru = 'Проверить совместимость'");
Если Дело.ЕстьДела Тогда
ГруппаДела.Количество = Дело.Количество;
КонецЕсли;
ГруппаДела.Владелец = Раздел;
Иначе
Если Не ГруппаДела.ЕстьДела Тогда
ГруппаДела.ЕстьДела = Дело.ЕстьДела;
КонецЕсли;
Если Дело.ЕстьДела Тогда
ГруппаДела.Количество = ГруппаДела.Количество + Дело.Количество;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция СинонимДанныхСтрокиДереваСтатистики(СтрокаДерева, ТипИсточникаСтрокой)
Синоним = СтрокаДерева.Синоним;
Фильтр = Новый Структура("ПолноеИмя, Синоним", СтрокаДерева.ПолноеИмя, Синоним);
Существующие = СтрокаДерева.Владелец().Строки.НайтиСтроки(Фильтр, Истина);
Количество = Существующие.Количество();
Если Количество = 0 Или (Количество = 1 И Существующие[0] = СтрокаДерева) Тогда
// Не было еще такого описания в этом дереве.
Возврат Синоним;
КонецЕсли;
Синоним = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = '%1 (%2)'"),
СтрокаДерева.Синоним,
УдалитьИмяКлассаИзИмениОбъекта(ТипИсточникаСтрокой));
Возврат Синоним;
КонецФункции
// Возвращаемое значение:
// ТаблицаЗначений - коллекция регистров с движениями по заданному регистратору:
// * ИмяТаблицыРегистра - Строка - полное имя таблицы регистра.
// * НаборЗаписей - РегистрСведенийНаборЗаписей
// - РегистрНакопленияНаборЗаписей
// - и т.п. - набор записей.
// * БезусловноеУдаление - Булево - признак безусловного удаления записей.
//
Функция ОпределитьНаличиеДвиженийПоДокументу(ДокументСсылка)
МетаданныеДокумента = ДокументСсылка.Метаданные();
Если МетаданныеДокумента.Движения.Количество() = 0 Тогда
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("ИмяТаблицыРегистра", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("НаборЗаписей");
Результат.Колонки.Добавить("БезусловноеУдаление", Новый ОписаниеТипов("Булево"));
Возврат Результат;
КонецЕсли;
ТекстЗапроса = "";
// Для исключения падения для документов, проводящимся более чем по 256 таблицам.
СчетчикТаблиц = 0;
ШаблонТекстаЗапроса =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ВЫРАЗИТЬ(""&ИмяТаблицыМетаданных"" КАК СТРОКА(200)) КАК ИмяТаблицыРегистра
|ИЗ
| &ИмяТаблицыМетаданных КАК ПсевдонимТаблицыМетаданных
|ГДЕ
| ПсевдонимТаблицыМетаданных.Регистратор = &Регистратор";
Для Каждого Движение Из МетаданныеДокумента.Движения Цикл
// В запросе получаем имена регистров, по которым есть хотя бы одно движение.
// Например,
// ВЫБРАТЬ Первые 1 "РегистрНакопления.ТоварыНаСкладах"
// ИЗ РегистрНакопления.ТоварыНаСкладах
// ГДЕ Регистратор = &Регистратор.
// Имя регистра приводим к Строка(200)
Если НЕ ПустаяСтрока(ТекстЗапроса) Тогда
ТекстЗапроса = ТекстЗапроса + Символы.ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС;
КонецЕсли;
ТекстПодзапроса = СтрЗаменить(ШаблонТекстаЗапроса, "&ИмяТаблицыМетаданных", Движение.ПолноеИмя());
ТекстЗапроса = ТекстЗапроса + ТекстПодзапроса;
// Если в запрос попадает более 256 таблиц - разбиваем его на две части
// (вариант документа с проведением по 512 регистрам считаем нежизненным).
СчетчикТаблиц = СчетчикТаблиц + 1;
Если СчетчикТаблиц = 256 Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Регистратор", ДокументСсылка);
// При выгрузке для колонки "Имя" тип устанавливается по самой длинной строке из запроса
// при втором проходе по таблице новое имя может не «влезть», по этому сразу в запросе
// приводится к строка(200).
ТаблицаЗапроса = Запрос.Выполнить().Выгрузить();
ТаблицаЗапроса.Колонки.Добавить("НаборЗаписей");
ТаблицаЗапроса.Колонки.Добавить("БезусловноеУдаление", Новый ОписаниеТипов("Булево"));
// Если количество таблиц не превысило 256 - возвращаем таблицу.
Если СчетчикТаблиц = МетаданныеДокумента.Движения.Количество() Тогда
Возврат ТаблицаЗапроса;
КонецЕсли;
// Таблиц больше чем 256, делаем доп. запрос и дополняем строки таблицы.
ТекстЗапроса = "";
Для Каждого Движение Из МетаданныеДокумента.Движения Цикл
Если СчетчикТаблиц > 0 Тогда
СчетчикТаблиц = СчетчикТаблиц - 1;
Продолжить;
КонецЕсли;
Если НЕ ПустаяСтрока(ТекстЗапроса) Тогда
ТекстЗапроса = ТекстЗапроса + Символы.ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС;
КонецЕсли;
ТекстПодзапроса = СтрЗаменить(ШаблонТекстаЗапроса, "&ИмяТаблицыМетаданных", Движение.ПолноеИмя());
ТекстЗапроса = ТекстЗапроса + ТекстПодзапроса;
КонецЦикла;
Запрос.Текст = ТекстЗапроса;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СтрокаТаблицы = ТаблицаЗапроса.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаТаблицы, Выборка);
КонецЦикла;
Возврат ТаблицаЗапроса;
КонецФункции
// Получает дерево метаданных конфигурации с заданным отбором по объектам метаданных.
//
// Параметры:
// Отбор - Структура - содержит значения элементов отбора.
// Если параметр задан, то будет получено дерево метаданных в соответствии с заданным отбором:
// Ключ - Строка - имя свойства элемента метаданных;
// Значение - Массив - множество значений для отбора.
//
// Пример инициализации переменной "Отбор":
//
// Массив = Новый Массив;
// Массив.Добавить("Константа.ИспользоватьСинхронизациюДанных");
// Массив.Добавить("Справочник.Валюты");
// Массив.Добавить("Справочник._ДемоОрганизации");
// Отбор = Новый Структура;
// Отбор.Вставить("ПолноеИмя", Массив);
//
// Возвращаемое значение:
// ДеревоЗначений - дерево описания метаданных конфигурации.
//
Функция ДеревоМетаданныхКонфигурации(Отбор = Неопределено) Экспорт
ИспользоватьОтбор = (Отбор <> Неопределено);
КоллекцииОбъектовМетаданных = Новый ТаблицаЗначений;
КоллекцииОбъектовМетаданных.Колонки.Добавить("Имя");
КоллекцииОбъектовМетаданных.Колонки.Добавить("Синоним");
КоллекцииОбъектовМетаданных.Колонки.Добавить("Картинка");
КоллекцииОбъектовМетаданных.Колонки.Добавить("КартинкаОбъекта");
НоваяСтрокаКоллекцииОбъектовМетаданных("Константы", НСтр("ru = 'Константы'"), БиблиотекаКартинок.Константа, БиблиотекаКартинок.Константа, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("Справочники", НСтр("ru = 'Справочники'"), БиблиотекаКартинок.Справочник, БиблиотекаКартинок.Справочник, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("Документы", НСтр("ru = 'Документы'"), БиблиотекаКартинок.Документ, БиблиотекаКартинок.ДокументОбъект, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("ПланыВидовХарактеристик", НСтр("ru = 'Планы видов характеристик'"), БиблиотекаКартинок.ПланВидовХарактеристик, БиблиотекаКартинок.ПланВидовХарактеристикОбъект, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("ПланыСчетов", НСтр("ru = 'Планы счетов'"), БиблиотекаКартинок.ПланСчетов, БиблиотекаКартинок.ПланСчетовОбъект, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("ПланыВидовРасчета", НСтр("ru = 'Планы видов расчета'"), БиблиотекаКартинок.ПланВидовРасчета, БиблиотекаКартинок.ПланВидовРасчетаОбъект, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("РегистрыСведений", НСтр("ru = 'Регистры сведений'"), БиблиотекаКартинок.РегистрСведений, БиблиотекаКартинок.РегистрСведений, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("РегистрыНакопления", НСтр("ru = 'Регистры накопления'"), БиблиотекаКартинок.РегистрНакопления, БиблиотекаКартинок.РегистрНакопления, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("РегистрыБухгалтерии", НСтр("ru = 'Регистры бухгалтерии'"), БиблиотекаКартинок.РегистрБухгалтерии, БиблиотекаКартинок.РегистрБухгалтерии, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("РегистрыРасчета", НСтр("ru = 'Регистры расчета'"), БиблиотекаКартинок.РегистрРасчета, БиблиотекаКартинок.РегистрРасчета, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("БизнесПроцессы", НСтр("ru = 'Бизнес-процессы'"), БиблиотекаКартинок.БизнесПроцесс, БиблиотекаКартинок.БизнесПроцессОбъект, КоллекцииОбъектовМетаданных);
НоваяСтрокаКоллекцииОбъектовМетаданных("Задачи", НСтр("ru = 'Задачи'"), БиблиотекаКартинок.Задача, БиблиотекаКартинок.ЗадачаОбъект, КоллекцииОбъектовМетаданных);
// Возвращаемое значение функции.
ДеревоМетаданных = Новый ДеревоЗначений;
ДеревоМетаданных.Колонки.Добавить("Имя");
ДеревоМетаданных.Колонки.Добавить("ПолноеИмя");
ДеревоМетаданных.Колонки.Добавить("Синоним");
ДеревоМетаданных.Колонки.Добавить("Картинка");
Для Каждого СтрокаКоллекции Из КоллекцииОбъектовМетаданных Цикл
СтрокаДерева = ДеревоМетаданных.Строки.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаДерева, СтрокаКоллекции);
Для Каждого ОбъектМетаданных Из Метаданные[СтрокаКоллекции.Имя] Цикл
Если ИспользоватьОтбор Тогда
ОбъектПрошелФильтр = Истина;
Для Каждого ЭлементОтбора Из Отбор Цикл
Значение = ?(ВРег(ЭлементОтбора.Ключ) = ВРег("ПолноеИмя"), ОбъектМетаданных.ПолноеИмя(), ОбъектМетаданных[ЭлементОтбора.Ключ]);
Если ЭлементОтбора.Значение.Найти(Значение) = Неопределено Тогда
ОбъектПрошелФильтр = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ОбъектПрошелФильтр Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
СтрокаДереваОМ = СтрокаДерева.Строки.Добавить();
СтрокаДереваОМ.Имя = ОбъектМетаданных.Имя;
СтрокаДереваОМ.ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
СтрокаДереваОМ.Синоним = ОбъектМетаданных.Синоним;
СтрокаДереваОМ.Картинка = СтрокаКоллекции.КартинкаОбъекта;
КонецЦикла;
КонецЦикла;
// Удаляем строки без подчиненных элементов.
Если ИспользоватьОтбор Тогда
// Используем обратный порядок обхода дерева значений.
КоличествоЭлементовКоллекции = ДеревоМетаданных.Строки.Количество();
Для ОбратныйИндекс = 1 По КоличествоЭлементовКоллекции Цикл
ТекущийИндекс = КоличествоЭлементовКоллекции - ОбратныйИндекс;
СтрокаДерева = ДеревоМетаданных.Строки[ТекущийИндекс];
Если СтрокаДерева.Строки.Количество() = 0 Тогда
ДеревоМетаданных.Строки.Удалить(ТекущийИндекс);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ДеревоМетаданных;
КонецФункции
Процедура НоваяСтрокаКоллекцииОбъектовМетаданных(Имя, Синоним, Картинка, КартинкаОбъекта, Таб)
НоваяСтрока = Таб.Добавить();
НоваяСтрока.Имя = Имя;
НоваяСтрока.Синоним = Синоним;
НоваяСтрока.Картинка = Картинка;
НоваяСтрока.КартинкаОбъекта = КартинкаОбъекта;
КонецПроцедуры
Функция КодПредопределенногоУзлаПланаОбмена(ИмяПланаОбмена) Экспорт
УстановитьПривилегированныйРежим(Истина);
ЭтотУзел = ОбменДаннымиПовтИсп.ПолучитьЭтотУзелПланаОбмена(ИмяПланаОбмена);
Возврат СокрЛП(ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЭтотУзел, "Код"));
КонецФункции
// Возвращает массив всех узлов для заданного плана обмена кроме предопределенного узла.
//
// Параметры:
// ИмяПланаОбмена - Строка - имя плана обмена как оно задано в конфигураторе.
//
// Возвращаемое значение:
// МассивУзлов - Массив - массив всех узлов для заданного плана обмена кроме предопределенного узла.
//
Функция УзлыПланаОбмена(ИмяПланаОбмена) Экспорт
Запрос = Новый Запрос(
"ВЫБРАТЬ
| ПланОбмена.Ссылка КАК Ссылка
|ИЗ
| #ИмяТаблицыПланаОбмена КАК ПланОбмена
|ГДЕ
| НЕ ПланОбмена.ЭтотУзел");
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ИмяТаблицыПланаОбмена", "ПланОбмена." + ИмяПланаОбмена);
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
КонецФункции
#КонецОбласти
#Область РаботаСКонстантойСообщениеОбменаИзГлавногоУзла
// Зачитывает из информационной базы информацию о сообщении обмена данными.
//
// Возвращаемое значение:
// Структура - информация о расположении файла сообщения обмена (текущий формат).
// - ДвоичныеДанные - сообщение обмена в информационной базе (устаревший формат).
//
Функция СообщениеОбменаДаннымиИзГлавногоУзла()
Возврат Константы.СообщениеОбменаДаннымиИзГлавногоУзла.Получить().Получить();
КонецФункции
// Записывает на диск файл сообщения обмена, полученный из главного узла.
// Сохраняет путь к записанному сообщению в константу СообщениеОбменаДаннымиИзГлавногоУзла.
//
// Параметры:
// СообщениеОбмена - ДвоичныеДанные - зачитанное сообщение обмена.
// ГлавныйУзел - ПланОбменаСсылка - узел из которого получено сообщение.
//
Процедура УстановитьСообщениеОбменаДаннымиИзГлавногоУзла(СообщениеОбмена, ГлавныйУзел) Экспорт
ПутьКФайлу = "[Каталог][Путь].xml";
ПутьКФайлу = СтрЗаменить(ПутьКФайлу, "[Каталог]", КаталогВременногоХранилищаФайлов());
ПутьКФайлу = СтрЗаменить(ПутьКФайлу, "[Путь]", Новый УникальныйИдентификатор);
СообщениеОбмена.Записать(ПутьКФайлу);
СтруктураСообщения = Новый Структура;
СтруктураСообщения.Вставить("ПутьКФайлу", ПутьКФайлу);
Константы.СообщениеОбменаДаннымиИзГлавногоУзла.Установить(Новый ХранилищеЗначения(СтруктураСообщения));
ЗаписатьСобытиеПолученияДанных(ГлавныйУзел, НСтр("ru = 'Сообщение обмена записано в кэш.'"));
КонецПроцедуры
// Удаляет файл сообщения обмена с диска и очищает константу СообщениеОбменаДаннымиИзГлавногоУзла.
//
Процедура ОчиститьСообщениеОбменаДаннымиИзГлавногоУзла() Экспорт
СообщениеОбмена = СообщениеОбменаДаннымиИзГлавногоУзла();
Если ТипЗнч(СообщениеОбмена) = Тип("Структура") Тогда
УдалитьФайлы(СообщениеОбмена.ПутьКФайлу);
КонецЕсли;
Константы.СообщениеОбменаДаннымиИзГлавногоУзла.Установить(Новый ХранилищеЗначения(Неопределено));
ЗаписатьСобытиеПолученияДанных(ГлавныйУзел(), НСтр("ru = 'Сообщение обмена удалено из кэша.'"));
КонецПроцедуры
#КонецОбласти
#Область ПрофилиБезопасности
Процедура СформироватьЗапросыНаИспользованиеВнешнихРесурсов(ЗапросыРазрешений)
Если ОбщегоНазначения.РазделениеВключено()
И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
Возврат;
КонецЕсли;
Константы.КаталогСообщенийОбменаДаннымиДляLinux.СоздатьМенеджерЗначения().ПриЗаполненииРазрешенийНаДоступКВнешнимРесурсам(ЗапросыРазрешений);
Константы.КаталогСообщенийОбменаДаннымиДляWindows.СоздатьМенеджерЗначения().ПриЗаполненииРазрешенийНаДоступКВнешнимРесурсам(ЗапросыРазрешений);
Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
РегистрыСведений.НастройкиТранспортаОбменаДанными.ПриЗаполненииРазрешенийНаДоступКВнешнимРесурсам(ЗапросыРазрешений);
КонецЕсли;
РегистрыСведений.ПравилаДляОбменаДанными.ПриЗаполненииРазрешенийНаДоступКВнешнимРесурсам(ЗапросыРазрешений);
КонецПроцедуры
// Параметры:
// ЗапросыРазрешений - Массив из УникальныйИдентификатор - коллекция запросов разрешений.
// Объект - КонстантаМенеджерЗначения - менеджер значения объекта данных.
//
Процедура ЗапросВнешнихРесурсовДляКаталогаСообщенийОбменаДанными(ЗапросыРазрешений, Объект) Экспорт
ЗначениеКонстанты = Объект.Значение;
МодульРаботаВБезопасномРежиме = ОбщегоНазначения.ОбщийМодуль("РаботаВБезопасномРежиме");
Если Не ПустаяСтрока(ЗначениеКонстанты) Тогда
Разрешения = Новый Массив;
Разрешения.Добавить(МодульРаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаФайловойСистемы(
ЗначениеКонстанты, Истина, Истина));
ЗапросыРазрешений.Добавить(
МодульРаботаВБезопасномРежиме.ЗапросНаИспользованиеВнешнихРесурсов(Разрешения,
ОбщегоНазначения.ИдентификаторОбъектаМетаданных(Объект.Метаданные())));
КонецЕсли;
КонецПроцедуры
// Возвращает шаблон имени профиля безопасности для внешнего модуля.
// Функция должна возвращать одно и то же значение при многократном вызове.
//
// Параметры:
// ВнешнийМодуль - ЛюбаяСсылка - ссылка на внешний модуль.
//
// Возвращаемое значение:
// Строка - шаблон имя профиля безопасности, содержащий символы
// "%1", вместо которых в дальнейшем будет подставлен уникальный идентификатор.
//
Функция ШаблонИмениПрофиляБезопасности(Знач ВнешнийМодуль) Экспорт
Шаблон = "Exchange_[ИмяПланаОбмена]_%1"; // Не локализуется
Возврат СтрЗаменить(Шаблон, "[ИмяПланаОбмена]", ВнешнийМодуль.Имя);
КонецФункции
// Возвращает пиктограмму, отображающую внешний модуль.
//
// ВнешнийМодуль - ЛюбаяСсылка, ссылка на внешний модуль,
//
// Возвращаемое значение:
// Картинка.
//
Функция ПиктограммаВнешнегоМодуля(Знач ВнешнийМодуль) Экспорт
Возврат БиблиотекаКартинок.СинхронизацияДанных;
КонецФункции
Функция СловарьКонтейнераВнешнегоМодуля() Экспорт
Результат = Новый Структура();
Результат.Вставить("Именительный", НСтр("ru = 'Настройка синхронизации данных'"));
Результат.Вставить("Родительный", НСтр("ru = 'Настройки синхронизации данных'"));
Возврат Результат;
КонецФункции
Функция КонтейнерыВнешнихМодулей() Экспорт
Результат = Новый Массив();
ОбменДаннымиПереопределяемый.ПолучитьПланыОбмена(Результат);
Возврат Результат;
КонецФункции
#КонецОбласти
#Область ИнтерактивноеИзменениеВыгрузки
// Инициализирует дополнение выгрузки для мастера пошагового обмена.
//
// Параметры:
// УзелИнформационнойБазы - ПланОбменаСсылка - ссылка на узел, для которого производится настройка.
// АдресХранилищаФормы - Строка
// - УникальныйИдентификатор - адрес сохранения между серверными вызовами.
// ЕстьСценарийУзла - Булево - флаг необходимости дополнительной настройки.
//
// Возвращаемое значение:
// Структура - данные для дальнейшего оперирования дополнением выгрузки:
// * УзелИнформационнойБазы - ПланОбменаСсылка - ссылка на узел, для которого производится настройка.
// * ВариантВыгрузки - Число - текущий вариант выгрузки.
// * ПериодОтбораВсехДокументов - СтандартныйПериод - период отбора документов. По умолчанию - прошлый месяц.
// * АдресКомпоновщикаВсехДокументов - Строка - адрес компоновщика настроек для отбора документов.
// * ДополнительнаяРегистрация - см. ОписаниеДополнительнойРегистрацииВариантаВыгрузки
// * ПараметрыСценарияДополнения - см. ОписаниеСтандартныхВариантовДополненияВыгрузки
// * АдресХранилищаФормы - УникальныйИдентификатор - уникальный идентификатор формы для временного хранилища.
//
Функция ИнтерактивноеИзменениеВыгрузки(Знач УзелИнформационнойБазы, Знач АдресХранилищаФормы, Знач ЕстьСценарийУзла = Неопределено) Экспорт
УстановитьПривилегированныйРежим(Истина);
Результат = Новый Структура;
Результат.Вставить("УзелИнформационнойБазы", УзелИнформационнойБазы);
Результат.Вставить("ВариантВыгрузки", 0);
Результат.Вставить("ПериодОтбораВсехДокументов", Новый СтандартныйПериод);
Результат.ПериодОтбораВсехДокументов.Вариант = ВариантСтандартногоПериода.ПрошлыйМесяц;
ОбработкаДополнения = Обработки.ИнтерактивноеИзменениеВыгрузки.Создать();
ОбработкаДополнения.УзелИнформационнойБазы = УзелИнформационнойБазы;
ОбработкаДополнения.ВариантВыгрузки = 0;
// Компоновщик собираем по частям.
Данные = ОбработкаДополнения.КомпоновщикНастроекОбщегоОтбора(АдресХранилищаФормы);
Результат.Вставить("АдресКомпоновщикаВсехДокументов", ПоместитьВоВременноеХранилище(Данные, АдресХранилищаФормы));
Результат.Вставить("ДополнительнаяРегистрация", ОписаниеДополнительнойРегистрацииВариантаВыгрузки());
Результат.Вставить("ПараметрыСценарияДополнения", ОписаниеСтандартныхВариантовДополненияВыгрузки());
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(УзелИнформационнойБазы);
Если ЕстьСценарийУзла = Неопределено Тогда
// Можно определить по метаданным узла.
ЕстьСценарийУзла = Ложь;
КонецЕсли;
Если ЕстьСценарийУзла
И ЕстьАлгоритмМенеджераПланаОбмена("НастроитьИнтерактивнуюВыгрузку", ИмяПланаОбмена) Тогда
МодульМенеджераУзла = ПланыОбмена[ИмяПланаОбмена];
МодульМенеджераУзла.НастроитьИнтерактивнуюВыгрузку(УзелИнформационнойБазы, Результат.ПараметрыСценарияДополнения);
КонецЕсли;
Результат.Вставить("АдресХранилищаФормы", АдресХранилищаФормы);
Возврат Результат;
КонецФункции
// Возвращаемое значение:
// ТаблицаЗначений - содержит строки с описанием подробных отборов по сценарию узла:
// * ПолноеИмяМетаданных - Строка - полное имя метаданных регистрируемого объекта, отбор которого описывает строка.
// Например "Документ._ДемоПоступлениеТоваров". Можно
// использовать специальные значения "ВсеДокументы" и
// "ВсеСправочники" для отбора соответственно всех
// документов и всех справочников, регистрирующихся на узле "Получатель".
// * Отбор - ОтборКомпоновкиДанных - отбор по умолчанию. Поля отбора формируются в соответствии с общим
// правилами формирования полей компоновки. Например, для указания
// отбора по реквизиту документа "Организация", необходимо
// использовать поле "Ссылка.Организация".
// * Период - СтандартныйПериод - значение периода общего отбора для метаданных строки, предлагаемого по умолчанию.
// * ВыборПериода - Булево - признак того, что данная строка описывает отбор с общим периодом.
// * Представление - Строка - представление отбора.
// * ОтборСтрокой - Строка - значение отбора в виде строки.
// * Количество - Строка - количество элементов в отборе.
//
Функция ОписаниеДополнительнойРегистрацииВариантаВыгрузки()
ДополнительнаяРегистрация = Новый ТаблицаЗначений;
ДополнительнаяРегистрация.Колонки.Добавить("ПолноеИмяМетаданных", Новый ОписаниеТипов("Строка"));
ДополнительнаяРегистрация.Колонки.Добавить("Отбор", Новый ОписаниеТипов("ОтборКомпоновкиДанных"));
ДополнительнаяРегистрация.Колонки.Добавить("Период", Новый ОписаниеТипов("СтандартныйПериод"));
ДополнительнаяРегистрация.Колонки.Добавить("ВыборПериода", Новый ОписаниеТипов("Булево"));
ДополнительнаяРегистрация.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
ДополнительнаяРегистрация.Колонки.Добавить("ОтборСтрокой", Новый ОписаниеТипов("Строка"));
ДополнительнаяРегистрация.Колонки.Добавить("Количество", Новый ОписаниеТипов("Строка"));
Возврат ДополнительнаяРегистрация;
КонецФункции
// Возвращаемое значение:
// Структура - настройки типового варианта дополнения выгрузки "Не добавлять":
// * Использование - Булево - признак разрешения использования варианта. По умолчанию Истина.
// * Порядок - Число - порядок размещения варианта на форме помощника, сверху вниз. По умолчанию 1.
// * Заголовок - Строка - позволяет переопределить название типового варианта.
// * Пояснение - Строка - позволяет переопределить текст пояснения варианта для пользователя.
//
Функция ОписаниеСтандартногоВариантаБезДополнения()
Результат = Новый Структура;
Результат.Вставить("Использование", Истина);
Результат.Вставить("Порядок", 1);
Результат.Вставить("Заголовок", "");
Результат.Вставить("Пояснение", НСтр("ru = 'Будут отправлены только данные согласно общим настройкам.'"));
Возврат Результат;
КонецФункции
// Возвращаемое значение:
// Структура - настройки типового варианта дополнения выгрузки "Добавить все документы за период":
// * Использование - Булево - признак разрешения использования варианта. По умолчанию Истина.
// * Порядок - Число - порядок размещения варианта на форме помощника, сверху вниз. По умолчанию 2.
// * Заголовок - Строка - позволяет переопределить название типового варианта.
// * Пояснение - Строка - позволяет переопределить текст пояснения варианта для пользователя.
//
Функция ОписаниеСтандартногоВариантаВсеДокументы()
Результат = Новый Структура;
Результат.Вставить("Использование", Истина);
Результат.Вставить("Порядок", 2);
Результат.Вставить("Заголовок", "");
Результат.Вставить("Пояснение", НСтр("ru = 'Дополнительно будут отправлены все документы за период, удовлетворяющие условиям отбора.'"));
Возврат Результат;
КонецФункции
// Возвращаемое значение:
// Структура - настройки типового варианта дополнения выгрузки "Добавить данные с произвольным отбором":
// * Использование - Булево - признак разрешения использования варианта. По умолчанию Истина.
// * Порядок - Число - порядок размещения варианта на форме помощника, сверху вниз. По умолчанию 3.
// * Заголовок - Строка - позволяет переопределить название типового варианта.
// * Пояснение - Строка - позволяет переопределить текст пояснения варианта для пользователя.
//
Функция ОписаниеСтандартногоВариантаПроизвольныйОтбор()
Результат = Новый Структура;
Результат.Вставить("Использование", Истина);
Результат.Вставить("Порядок", 3);
Результат.Вставить("Заголовок", "");
Результат.Вставить("Пояснение", НСтр("ru = 'Дополнительно будут отправлены данные согласно отбору.'"));
Возврат Результат;
КонецФункции
// Структура описания стандартного варианта дополнения выгрузки "ВариантДополнительно".
//
// Возвращаемое значение:
// Структура - настройки типового варианта дополнения выгрузки по сценарию узла:
// * Использование - Булево - признак разрешения использования варианта. По умолчанию Ложь.
// * Порядок - Число - порядок размещения варианта на форме помощника, сверху вниз. По умолчанию 4.
// * Заголовок - Строка - позволяет переопределить название типового варианта.
// * Пояснение - Строка - позволяет переопределить текст пояснения варианта для пользователя.
// * ИспользоватьПериодОтбора - Булево - признак того, что необходим общий отбор по периоду. По умолчанию Ложь.
// * ПериодОтбора - СтандартныйПериод - значение периода общего отбора, предлагаемого по умолчанию.
// * ИмяФормыОтбора - Строка - имя формы, вызываемой для редактирования настроек.
// * ЗаголовокКомандыФормы - Строка - заголовок для отрисовки на форме команды открытия формы настроек.
// * Отбор - см. ОписаниеДополнительнойРегистрацииВариантаВыгрузки
//
Функция ОписаниеСтандартногоВариантаДополнительно()
Результат = Новый Структура;
Результат.Вставить("Использование", Ложь);
Результат.Вставить("Порядок", 4);
Результат.Вставить("Заголовок", "");
Результат.Вставить("Пояснение", НСтр("ru = 'Дополнительно будут отправлены данные согласно отбору.'"));
Результат.Вставить("ИспользоватьПериодОтбора", Ложь);
Результат.Вставить("ПериодОтбора", Новый СтандартныйПериод);
Результат.Вставить("ИмяФормыОтбора", "");
Результат.Вставить("ЗаголовокКомандыФормы", "");
Результат.Вставить("Отбор", ОписаниеДополнительнойРегистрацииВариантаВыгрузки());
Возврат Результат;
КонецФункции
// Очистка отбора всех документов.
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - ДанныеФормыСтруктура - описание параметров выгрузки:
// * КомпоновщикОтбораВсехДокументов - КомпоновщикНастроекКомпоновкиДанных
// * АдресКомпоновщикаВсехДокументов - Строка
// * АдресХранилищаФормы - Строка
//
Процедура ИнтерактивноеИзменениеВыгрузкиОчисткаОбщегоОтбора(ДополнениеВыгрузки) Экспорт
Если ПустаяСтрока(ДополнениеВыгрузки.АдресКомпоновщикаВсехДокументов) Тогда
ДополнениеВыгрузки.КомпоновщикОтбораВсехДокументов.Настройки.Отбор.Элементы.Очистить();
Иначе
Данные = ПолучитьИзВременногоХранилища(ДополнениеВыгрузки.АдресКомпоновщикаВсехДокументов); // КомпоновщикНастроекКомпоновкиДанных
Данные.Настройки.Отбор.Элементы.Очистить();
ДополнениеВыгрузки.АдресКомпоновщикаВсехДокументов = ПоместитьВоВременноеХранилище(Данные, ДополнениеВыгрузки.АдресХранилищаФормы);
Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Данные.СхемаКомпоновки));
Компоновщик.ЗагрузитьНастройки(Данные.Настройки);
ДополнениеВыгрузки.КомпоновщикОтбораВсехДокументов = Компоновщик;
КонецЕсли;
КонецПроцедуры
// Очистка детального отбора
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - РеквизитФормыКоллекция - описание параметров выгрузки.
//
Процедура ИнтерактивноеИзменениеВыгрузкиОчисткаДетально(ДополнениеВыгрузки) Экспорт
ДополнениеВыгрузки.ДополнительнаяРегистрация.Очистить();
КонецПроцедуры
// Определяет описание общего отбора. При пустом отборе возвращает пустую строку.
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - РеквизитФормыКоллекция - описание параметров выгрузки.
//
// Возвращаемое значение:
// Строка - описание отбора.
//
Функция ИнтерактивноеИзменениеВыгрузкиОписаниеДополненияОбщегоОтбора(Знач ДополнениеВыгрузки) Экспорт
ДанныеКомпоновщика = ПолучитьИзВременногоХранилища(ДополнениеВыгрузки.АдресКомпоновщикаВсехДокументов);
Источник = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ДанныеКомпоновщика.СхемаКомпоновки);
Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
Компоновщик.Инициализировать(Источник);
Компоновщик.ЗагрузитьНастройки(ДанныеКомпоновщика.Настройки);
Возврат ПредставлениеОтбораДополненияВыгрузки(Неопределено, Компоновщик, "");
КонецФункции
// Определяет описание детального отбора. При пустом отборе возвращает пустую строку.
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - РеквизитФормыКоллекция - описание параметров выгрузки.
//
// Возвращаемое значение:
// Строка - описание отбора.
//
Функция ИнтерактивноеИзменениеВыгрузкиОписаниеДетальногоОтбора(Знач ДополнениеВыгрузки) Экспорт
Возврат ПредставлениеДетальногоДополненияВыгрузки(ДополнениеВыгрузки.ДополнительнаяРегистрация, "");
КонецФункции
// Анализирует историю настроек-отборов, сохраненную пользователем для узла.
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - РеквизитФормыКоллекция - описание параметров выгрузки.
//
// Возвращаемое значение:
// Список значений, где представление - имя настройки, значение - данные настройки.
//
Функция ИнтерактивноеИзменениеВыгрузкиИсторияНастроек(Знач ДополнениеВыгрузки) Экспорт
ОбработкаДополнения = Обработки.ИнтерактивноеИзменениеВыгрузки.Создать();
ФильтрВарианта = ИнтерактивноеИзменениеВыгрузкиФильтрВарианта(ДополнениеВыгрузки);
Возврат ОбработкаДополнения.ПрочитатьПредставленияСпискаНастроек(ДополнениеВыгрузки.УзелИнформационнойБазы, ФильтрВарианта);
КонецФункции
// Восстанавливает настройки в реквизитах ДополнениеВыгрузки по названию сохраненной настройки.
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - РеквизитФормыКоллекция - описание параметров выгрузки.
// ПредставлениеНастройки - Строка - название восстанавливаемой настройки.
//
// Возвращаемое значение:
// Булево - Истина - успешно восстановлено, Ложь - настройка не найдена.
//
Функция ИнтерактивноеИзменениеВыгрузкиВосстановитьНастройки(ДополнениеВыгрузки, Знач ПредставлениеНастройки) Экспорт
ОбработкаДополнения = Обработки.ИнтерактивноеИзменениеВыгрузки.Создать();
ЗаполнитьЗначенияСвойств(ОбработкаДополнения, ДополнениеВыгрузки);
ФильтрВарианта = ИнтерактивноеИзменениеВыгрузкиФильтрВарианта(ДополнениеВыгрузки);
// Восстанавливаем состояние объекта.
Результат = ОбработкаДополнения.ВосстановитьТекущееИзНастроек(ПредставлениеНастройки, ФильтрВарианта, ДополнениеВыгрузки.АдресХранилищаФормы);
Если Результат Тогда
ЗаполнитьЗначенияСвойств(ДополнениеВыгрузки, ОбработкаДополнения, "ВариантВыгрузки, ПериодОтбораВсехДокументов, КомпоновщикОтбораВсехДокументов");
// Обновляем адрес компоновщика всегда.
Данные = ОбработкаДополнения.КомпоновщикНастроекОбщегоОтбора();
Данные.Настройки = ДополнениеВыгрузки.КомпоновщикОтбораВсехДокументов.Настройки;
ДополнениеВыгрузки.АдресКомпоновщикаВсехДокументов = ПоместитьВоВременноеХранилище(Данные, ДополнениеВыгрузки.АдресХранилищаФормы);
ЗаполнитьТаблицуЗначений(ДополнениеВыгрузки.ДополнительнаяРегистрация, ОбработкаДополнения.ДополнительнаяРегистрация);
// Настройки по сценарию узла обновляем только если они определены в прочитанном. Иначе оставляем текущее.
Если ОбработкаДополнения.ДополнительнаяРегистрацияСценарияУзла.Количество() > 0 Тогда
ЗаполнитьЗначенияСвойств(ДополнениеВыгрузки, ОбработкаДополнения, "ПериодОтбораСценарияУзла, ПредставлениеОтбораСценарияУзла");
ЗаполнитьТаблицуЗначений(ДополнениеВыгрузки.ДополнительнаяРегистрацияСценарияУзла, ОбработкаДополнения.ДополнительнаяРегистрацияСценарияУзла);
// Нормализуем установки периода.
ИнтерактивноеИзменениеВыгрузкиУстановитьПериодаСценарияУзла(ДополнениеВыгрузки);
КонецЕсли;
// Текущее представление ранее запомненных настроек.
ДополнениеВыгрузки.ПредставлениеТекущейНастройки = ПредставлениеНастройки;
КонецЕсли;
Возврат Результат;
КонецФункции
// Сохраняет настройки с указанным именем по данным ДополнениеВыгрузки.
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - РеквизитФормыКоллекция - описание параметров выгрузки.
// ПредставлениеНастройки - Строка - название сохраняемой настройки.
//
Процедура ИнтерактивноеИзменениеВыгрузкиСохранитьНастройки(ДополнениеВыгрузки, Знач ПредставлениеНастройки) Экспорт
ОбработкаДополнения = Обработки.ИнтерактивноеИзменениеВыгрузки.Создать();
ЗаполнитьЗначенияСвойств(ОбработкаДополнения, ДополнениеВыгрузки, ,
"ДополнительнаяРегистрация, ДополнительнаяРегистрацияСценарияУзла");
ЗаполнитьТаблицуЗначений(ОбработкаДополнения.ДополнительнаяРегистрация, ДополнениеВыгрузки.ДополнительнаяРегистрация);
ЗаполнитьТаблицуЗначений(ОбработкаДополнения.ДополнительнаяРегистрацияСценарияУзла, ДополнениеВыгрузки.ДополнительнаяРегистрацияСценарияУзла);
// Компоновщик настроек собираем заново.
Данные = ОбработкаДополнения.КомпоновщикНастроекОбщегоОтбора();
Если ПустаяСтрока(ДополнениеВыгрузки.АдресКомпоновщикаВсехДокументов) Тогда
ИсточникНастроек = ДополнениеВыгрузки.КомпоновщикОтбораВсехДокументов.Настройки;
Иначе
СтруктураКомпоновщика = ПолучитьИзВременногоХранилища(ДополнениеВыгрузки.АдресКомпоновщикаВсехДокументов);
ИсточникНастроек = СтруктураКомпоновщика.Настройки;
КонецЕсли;
ОбработкаДополнения.КомпоновщикОтбораВсехДокументов = Новый КомпоновщикНастроекКомпоновкиДанных;
ОбработкаДополнения.КомпоновщикОтбораВсехДокументов.Инициализировать( Новый ИсточникДоступныхНастроекКомпоновкиДанных(Данные.СхемаКомпоновки) );
ОбработкаДополнения.КомпоновщикОтбораВсехДокументов.ЗагрузитьНастройки(ИсточникНастроек);
// Собственно сохранение
ОбработкаДополнения.СохранитьТекущееВНастройки(ПредставлениеНастройки);
// Текущее представление запомненных настроек.
ДополнениеВыгрузки.ПредставлениеТекущейНастройки = ПредставлениеНастройки;
КонецПроцедуры
// Заполняет реквизит формы по данным структуры настроек.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - форма для установки реквизита.
// НастройкиДополненияВыгрузки - см. ИнтерактивноеИзменениеВыгрузки
// ИмяРеквизитаДополнения - Строка - имя реквизита формы для создания или заполнения.
//
Процедура ИнтерактивноеИзменениеВыгрузкиРеквизитПоНастройкам(Форма, Знач НастройкиДополненияВыгрузки, Знач ИмяРеквизитаДополнения="ДополнениеВыгрузки") Экспорт
УстановитьПривилегированныйРежим(Истина);
ПараметрыСценарияДополнения = НастройкиДополненияВыгрузки.ПараметрыСценарияДополнения;
// Разбираемся с реквизитами
РеквизитДополнения = Неопределено;
КоллекцияРеквизитов = Форма.ПолучитьРеквизиты(); // Массив из РеквизитФормы
Для Каждого Реквизит Из КоллекцияРеквизитов Цикл
Если Реквизит.Имя = ИмяРеквизитаДополнения Тогда
РеквизитДополнения = Реквизит;
Прервать;
КонецЕсли;
КонецЦикла;
// Проверяем и добавляем реквизит.
Добавляемые = Новый Массив;
Если РеквизитДополнения=Неопределено Тогда
РеквизитДополнения = Новый РеквизитФормы(ИмяРеквизитаДополнения,
Новый ОписаниеТипов("ОбработкаОбъект.ИнтерактивноеИзменениеВыгрузки"));
Добавляемые.Добавить(РеквизитДополнения);
Форма.ИзменитьРеквизиты(Добавляемые);
КонецЕсли;
// Проверяем и добавляем колонки общей дополнительной регистрации.
ПутьРеквизитаТаблицы = РеквизитДополнения.Имя + ".ДополнительнаяРегистрация";
Если Форма.ПолучитьРеквизиты(ПутьРеквизитаТаблицы).Количество()=0 Тогда
Добавляемые.Очистить();
Колонки = НастройкиДополненияВыгрузки.ДополнительнаяРегистрация.Колонки;
Для Каждого Колонка Из Колонки Цикл
Добавляемые.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ПутьРеквизитаТаблицы));
КонецЦикла;
Форма.ИзменитьРеквизиты(Добавляемые);
КонецЕсли;
// Проверяем и добавляем колонки дополнительной регистрации сценария узла.
ПутьРеквизитаТаблицы = РеквизитДополнения.Имя + ".ДополнительнаяРегистрацияСценарияУзла";
Если Форма.ПолучитьРеквизиты(ПутьРеквизитаТаблицы).Количество() = 0 Тогда
Добавляемые.Очистить();
Колонки = ПараметрыСценарияДополнения.ВариантДополнительно.Отбор.Колонки;
Для Каждого Колонка Из Колонки Цикл
Добавляемые.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ПутьРеквизитаТаблицы));
КонецЦикла;
Форма.ИзменитьРеквизиты(Добавляемые);
КонецЕсли;
// Добавляем данные
ЗначениеРеквизита = Форма[ИмяРеквизитаДополнения];
// Обрабатываем таблицы значений.
ЗначениеВДанныеФормы(ПараметрыСценарияДополнения.ВариантДополнительно.Отбор,
ЗначениеРеквизита.ДополнительнаяРегистрацияСценарияУзла);
ПараметрыСценарияДополнения.ВариантДополнительно.Отбор = ТаблицаВМассивСтруктур(
ПараметрыСценарияДополнения.ВариантДополнительно.Отбор);
ЗначениеРеквизита.ПараметрыСценарияДополнения = ПараметрыСценарияДополнения;
ЗначениеРеквизита.УзелИнформационнойБазы = НастройкиДополненияВыгрузки.УзелИнформационнойБазы;
ЗначениеРеквизита.ВариантВыгрузки = НастройкиДополненияВыгрузки.ВариантВыгрузки;
ЗначениеРеквизита.ПериодОтбораВсехДокументов = НастройкиДополненияВыгрузки.ПериодОтбораВсехДокументов;
Данные = ПолучитьИзВременногоХранилища(НастройкиДополненияВыгрузки.АдресКомпоновщикаВсехДокументов);
УдалитьИзВременногоХранилища(НастройкиДополненияВыгрузки.АдресКомпоновщикаВсехДокументов);
ЗначениеРеквизита.АдресКомпоновщикаВсехДокументов = ПоместитьВоВременноеХранилище(Данные, Форма.УникальныйИдентификатор);
ЗначениеРеквизита.ПериодОтбораСценарияУзла = ПараметрыСценарияДополнения.ВариантДополнительно.ПериодОтбора;
Если ПараметрыСценарияДополнения.ВариантДополнительно.Использование Тогда
ЗначениеРеквизита.ПредставлениеОтбораСценарияУзла = ПредставлениеДополненияВыгрузкиПоСценариюУзла(ЗначениеРеквизита);
КонецЕсли;
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
// Возвращает описание выгрузки по настройкам.
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - ДанныеФормыКоллекция - описание параметров выгрузки:
// * УзелИнформационнойБазы - ПланОбменаСсылка - узел плана обмена.
//
// Возвращаемое значение:
// Строка - представление.
//
Функция ПредставлениеДополненияВыгрузкиПоСценариюУзла(Знач ДополнениеВыгрузки)
ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(ДополнениеВыгрузки.УзелИнформационнойБазы);
Если Не ЕстьАлгоритмМенеджераПланаОбмена("ПредставлениеОтбораИнтерактивнойВыгрузки", ИмяПланаОбмена) Тогда
Возврат "";
КонецЕсли;
МодульМенеджера = ПланыОбмена[ИмяПланаОбмена];
Параметры = Новый Структура;
Параметры.Вставить("ИспользоватьПериодОтбора", ДополнениеВыгрузки.ПараметрыСценарияДополнения.ВариантДополнительно.ИспользоватьПериодОтбора);
Параметры.Вставить("ПериодОтбора", ДополнениеВыгрузки.ПериодОтбораСценарияУзла);
Параметры.Вставить("Отбор", ДополнениеВыгрузки.ДополнительнаяРегистрацияСценарияУзла);
Возврат МодульМенеджера.ПредставлениеОтбораИнтерактивнойВыгрузки(ДополнениеВыгрузки.УзелИнформационнойБазы, Параметры);
КонецФункции
// Возвращает описание периода и отбора строкой.
//
// Параметры:
// Период: период для описания отбора.
// Отбор: отбор компоновки данных для описания.
// ОписаниеПустогоОтбора: значение, возвращаемое в случае пустого отбора.
//
// Возвращаемое значение:
// Строка - описание периода и отбора.
//
Функция ПредставлениеОтбораДополненияВыгрузки(Знач Период, Знач Отбор, Знач ОписаниеПустогоОтбора=Неопределено) Экспорт
НашОтбор = ?(ТипЗнч(Отбор)=Тип("КомпоновщикНастроекКомпоновкиДанных"), Отбор.Настройки.Отбор, Отбор);
ПериодСтрокой = ?(ЗначениеЗаполнено(Период), Строка(Период), "");
ОтборСтрокой = Строка(НашОтбор);
Если ПустаяСтрока(ОтборСтрокой) Тогда
Если ОписаниеПустогоОтбора=Неопределено Тогда
ОтборСтрокой = НСтр("ru='Все объекты'");
Иначе
ОтборСтрокой = ОписаниеПустогоОтбора;
КонецЕсли;
КонецЕсли;
Если Не ПустаяСтрока(ПериодСтрокой) Тогда
ОтборСтрокой = ПериодСтрокой + ", " + ОтборСтрокой;
КонецЕсли;
Возврат ОтборСтрокой;
КонецФункции
// Возвращает описание детального отбора по реквизиту "ДополнительнаяРегистрация".
//
// Параметры:
// ДополнительнаяРегистрация - ТаблицаЗначений
// - Массив - строки или структуры, описывающие отбор.
// ОписаниеПустогоОтбора - Строка - значение, возвращаемое в случае пустого отбора.
//
Функция ПредставлениеДетальногоДополненияВыгрузки(Знач ДополнительнаяРегистрация, Знач ОписаниеПустогоОтбора=Неопределено) Экспорт
Текст = "";
Для Каждого Строка Из ДополнительнаяРегистрация Цикл
Текст = Текст + Символы.ПС + Строка.Представление + ": " + ПредставлениеОтбораДополненияВыгрузки(Строка.Период, Строка.Отбор);
КонецЦикла;
Если Не ПустаяСтрока(Текст) Тогда
Возврат СокрЛП(Текст);
ИначеЕсли ОписаниеПустогоОтбора=Неопределено Тогда
Возврат НСтр("ru='Дополнительные данные не выбраны'");
КонецЕсли;
Возврат ОписаниеПустогоОтбора;
КонецФункции
// Идентификатор служебной группы объектов метаданных "Все документы".
//
Функция ДополнениеВыгрузкиИдентификаторВсехДокументов() Экспорт
// Не должно пересекаться с полным именем метаданных.
Возврат "ВсеДокументы";
КонецФункции
// Идентификатор служебной группы объектов метаданных "Все справочники".
//
Функция ДополнениеВыгрузкиИдентификаторВсехСправочников() Экспорт
// Не должно пересекаться с полным именем метаданных.
Возврат "ВсеСправочники";
КонецФункции
// Имя для сохранения и восстановления настроек при интерактивном дополнении выгрузки.
//
Функция ДополнениеВыгрузкиИмяАвтоСохраненияНастроек() Экспорт
Возврат НСтр("ru = 'Последняя отправка (сохраняется автоматически)'");
КонецФункции
// Производит дополнительную регистрацию объектов по настройкам.
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - ДанныеФормыКоллекция - описание параметров выгрузки.
//
Процедура ИнтерактивноеИзменениеВыгрузкиЗарегистрироватьДополнительныеДанные(Знач ДополнениеВыгрузки) Экспорт
Если ДополнениеВыгрузки.ВариантВыгрузки <= 0 Тогда
Возврат;
КонецЕсли;
ОбъектОтчета = Обработки.ИнтерактивноеИзменениеВыгрузки.Создать();
ЗаполнитьЗначенияСвойств(ОбъектОтчета, ДополнениеВыгрузки,,"ДополнительнаяРегистрация, ДополнительнаяРегистрацияСценарияУзла");
Если ОбъектОтчета.ВариантВыгрузки=1 Тогда
// За период с отбором, дополнительная пустая.
ИначеЕсли ДополнениеВыгрузки.ВариантВыгрузки=2 Тогда
// Детально настроено
ОбъектОтчета.КомпоновщикОтбораВсехДокументов = Неопределено;
ОбъектОтчета.ПериодОтбораВсехДокументов = Неопределено;
ЗаполнитьТаблицуЗначений(ОбъектОтчета.ДополнительнаяРегистрация, ДополнениеВыгрузки.ДополнительнаяРегистрация);
ИначеЕсли ДополнениеВыгрузки.ВариантВыгрузки=3 Тогда
// По сценарию узла, имитируем детальное.
ОбъектОтчета.ВариантВыгрузки = 2;
ОбъектОтчета.КомпоновщикОтбораВсехДокументов = Неопределено;
ОбъектОтчета.ПериодОтбораВсехДокументов = Неопределено;
ЗаполнитьТаблицуЗначений(ОбъектОтчета.ДополнительнаяРегистрация, ДополнениеВыгрузки.ДополнительнаяРегистрацияСценарияУзла);
КонецЕсли;
ОбъектОтчета.ЗарегистрироватьДополнительныеИзменения();
КонецПроцедуры
// Производит установку общего периода во все разрезы отбора.
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - ДанныеФормыКоллекция - описание параметров выгрузки.
//
Процедура ИнтерактивноеИзменениеВыгрузкиУстановитьПериодаСценарияУзла(ДополнениеВыгрузки) Экспорт
Для Каждого Строка Из ДополнениеВыгрузки.ДополнительнаяРегистрацияСценарияУзла Цикл
Строка.Период = ДополнениеВыгрузки.ПериодОтбораСценарияУзла;
КонецЦикла;
// И обновляем представление
ДополнениеВыгрузки.ПредставлениеОтбораСценарияУзла = ПредставлениеДополненияВыгрузкиПоСценариюУзла(ДополнениеВыгрузки);
КонецПроцедуры
// Возвращает используемые варианты отбора по данным настроек.
//
// Параметры:
// ДополнениеВыгрузки - Структура
// - ДанныеФормыКоллекция - описание параметров выгрузки.
//
// Возвращаемое значение:
// Массив из Число - с номерами используемых вариантов:
// 0 - без отбора, 1 - отбор всех документов, 2 - подробный, 3 - сценарий узла.
//
Функция ИнтерактивноеИзменениеВыгрузкиФильтрВарианта(Знач ДополнениеВыгрузки) Экспорт
Результат = Новый Массив;
ТестДанных = Новый Структура("ПараметрыСценарияДополнения");
ЗаполнитьЗначенияСвойств(ТестДанных, ДополнениеВыгрузки);
ПараметрыСценарияДополнения = ТестДанных.ПараметрыСценарияДополнения;
Если ТипЗнч(ПараметрыСценарияДополнения)<>Тип("Структура") Тогда
// Нет настроек, значения по умолчанию - все.
Возврат Неопределено;
КонецЕсли;
Если ПараметрыСценарияДополнения.Свойство("ВариантБезДополнения")
И ПараметрыСценарияДополнения.ВариантБезДополнения.Использование Тогда
Результат.Добавить(0);
КонецЕсли;
Если ПараметрыСценарияДополнения.Свойство("ВариантВсеДокументы")
И ПараметрыСценарияДополнения.ВариантВсеДокументы.Использование Тогда
Результат.Добавить(1);
КонецЕсли;
Если ПараметрыСценарияДополнения.Свойство("ВариантПроизвольныйОтбор")
И ПараметрыСценарияДополнения.ВариантПроизвольныйОтбор.Использование Тогда
Результат.Добавить(2);
КонецЕсли;
Если ПараметрыСценарияДополнения.Свойство("ВариантДополнительно")
И ПараметрыСценарияДополнения.ВариантДополнительно.Использование Тогда
Результат.Добавить(3);
КонецЕсли;
Если Результат.Количество() = 4 Тогда
// Есть все варианты, убираем фильтр.
Возврат Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецОбласти
Функция НовыйУзелОбменаДаннымиXDTO(
ИмяПланаОбмена,
ИдентификаторНастройки,
ИдентификаторКорреспондента,
НаименованиеКорреспондента,
ВерсияФорматаОбмена)
МенеджерПланаОбмена = ПланыОбмена[ИмяПланаОбмена];
НовыйУзел = МенеджерПланаОбмена.СоздатьУзел();
НовыйУзел.Код = ИдентификаторКорреспондента;
НовыйУзел.Наименование = НаименованиеКорреспондента;
Если ОбщегоНазначения.ЕстьРеквизитОбъекта("ВариантНастройки", Метаданные.ПланыОбмена[ИмяПланаОбмена]) Тогда
НовыйУзел.ВариантНастройки = ИдентификаторНастройки;
КонецЕсли;
НовыйУзел.ВерсияФорматаОбмена = ВерсияФорматаОбмена;
НовыйУзел.Заполнить(Неопределено);
Если ОбщегоНазначения.РазделениеВключено()
И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных()
И ЭтоРазделенныйПланОбменаБСП(ИмяПланаОбмена) Тогда
НовыйУзел.РегистрироватьИзменения = Истина;
КонецЕсли;
НовыйУзел.ОбменДанными.Загрузка = Истина;
НовыйУзел.Записать();
Возврат НовыйУзел.Ссылка;
КонецФункции
Функция НедопустимыеСимволыВИмениПользователяWSПрокси()
Возврат ":";
КонецФункции
#КонецОбласти
#Область Дополнение
&AtServer
&Server
&AtClient
&Client
&ATSERVERNOCONTEXT
&ATCLIENTATSERVERNOCONTEXT
&ATCLIENTATSERVER
&После
&Вместо
&Перед
&ИзменениеИКонтроль
Функция ДополнениеФикстуры()
~Метка:
f = 1%2;
Goto ~Метка;
#delete
#enddelete
#insert
#endinsert
#if (client or server and MOBILEAPPCLIENT OR MOBILEAPPSERVER) or EXTERNALCONNECTION AND THINCLIENT AND WEBCLIENT then
#elsif not MOBILECLIENT OR THICKCLIENTORDINARYAPPLICATION AND THICKCLIENTMANAGEDAPPLICATION or AtServer or AtClient then //d
#else
#endif
d = null;
d = 1.2;
execute("d = 0");
addHandler f();
removeHandler f();
d = неопределено;
КонецФункции
#КонецОбласти
#Если МобильныйАвтономныйСервер Или MobileStandaloneServer Тогда
#КонецЕсли