Функция ТаблицаПриложенийСинхронизацииДанных(Параметры)

	НастройкиСинхронизацииИзМенеджераСервиса = Параметры.НастройкиСинхронизацииИзМенеджераСервиса.Получить();
	ОбластиДляОпределенияКодовУзлов          = Параметры.ОбластиДляОпределенияКодовУзлов.Получить();

	ДоступенExchangeAdministrationManage_3_0_1_1 = ОбменДаннымиВнутренняяПубликация.ВСервисеДоступенExchangeAdministrationManage_3_0_1_1();

	ТаблицаПриложений = Новый ТаблицаЗначений;
	ТаблицаПриложений.Колонки.Добавить("НаименованиеПриложения", Новый ОписаниеТипов("Строка"));
	ТаблицаПриложений.Колонки.Добавить("Префикс",                Новый ОписаниеТипов("Строка"));
	ТаблицаПриложений.Колонки.Добавить("ПрефиксКорреспондента",  Новый ОписаниеТипов("Строка"));
	ТаблицаПриложений.Колонки.Добавить("ВерсияКорреспондента",   Новый ОписаниеТипов("Строка"));
	ТаблицаПриложений.Колонки.Добавить("РольКорреспондента",     Новый ОписаниеТипов("Строка"));
	ТаблицаПриложений.Колонки.Добавить("ИмяПланаОбмена",         Новый ОписаниеТипов("Строка"));
	ТаблицаПриложений.Колонки.Добавить("ФорматОбмена",           Новый ОписаниеТипов("Строка"));
	ТаблицаПриложений.Колонки.Добавить("ОбластьДанных",          Новый ОписаниеТипов("Число"));

	ТаблицаПриложений.Колонки.Добавить("КонечнаяТочка", Новый ОписаниеТипов("ПланОбменаСсылка.ОбменСообщениями"));
	ТаблицаПриложений.Колонки.Добавить("КонечнаяТочкаКорреспондента", Новый ОписаниеТипов("ПланОбменаСсылка.ОбменСообщениями"));

	ТаблицаПриложений.Колонки.Добавить("Корреспондент");

	ТаблицаПриложений.Колонки.Добавить("НастройкаСинхронизацииНедоступна", Новый ОписаниеТипов("Булево"));
	ТаблицаПриложений.Колонки.Добавить("СообщениеОбОшибке",                Новый ОписаниеТипов("Строка"));

	ТаблицаПриложений.Колонки.Добавить("ДоступенExchangeAdministrationManage_3_0_1_1",	Новый ОписаниеТипов("Булево"));

	Если НастройкиСинхронизацииИзМенеджераСервиса.Количество() = 0 Тогда
		Возврат ТаблицаПриложений;
	КонецЕсли;

	СписокСвойств = "НаименованиеПриложения,
					|Префикс,
					|ПрефиксКорреспондента,
					|ВерсияКорреспондента,
					|РольКорреспондента,
					|ФорматОбмена,
					|ОбластьДанных";

	Если ДоступенExchangeAdministrationManage_3_0_1_1 Тогда
		СписокСвойств = СписокСвойств + ",ДоступенExchangeAdministrationManage_3_0_1_1";
	КонецЕсли;

	УстановитьПривилегированныйРежим(Истина);

	Для Каждого НастройкаИзМенеджераСервиса Из НастройкиСинхронизацииИзМенеджераСервиса Цикл

		СтрокаПриложение = ТаблицаПриложений.Добавить();
		ЗаполнитьЗначенияСвойств(СтрокаПриложение, НастройкаИзМенеджераСервиса, СписокСвойств);
		СтрокаПриложение.ИмяПланаОбмена = НастройкаИзМенеджераСервиса.ПланОбмена;
		СтрокаПриложение.КонечнаяТочкаКорреспондента = ПланыОбмена["ОбменСообщениями"].НайтиПоКоду(
			НастройкаИзМенеджераСервиса.КонечнаяТочкаКорреспондента);

		Если ДоступенExchangeAdministrationManage_3_0_1_1 Тогда
			СтрокаПриложение.КонечнаяТочка = ПланыОбмена["ОбменСообщениями"].НайтиПоКоду(
				НастройкаИзМенеджераСервиса.КонечнаяТочка);
		КонецЕсли;

		Если СтрокаПриложение.КонечнаяТочкаКорреспондента.Пустая() Тогда
			СтрокаПриложение.НастройкаСинхронизацииНедоступна = Истина;
			СтрокаПриложение.СообщениеОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Для приложения ""%1"" не найдена конечная точка с идентификатором ""%2"".'"),
				НастройкаИзМенеджераСервиса.НаименованиеПриложения,
				НастройкаИзМенеджераСервиса.КонечнаяТочкаКорреспондента);
		ИначеЕсли НастройкаИзМенеджераСервиса.НастройкаСинхронизацииВМенеджереСервиса Тогда
			СтрокаПриложение.НастройкаСинхронизацииНедоступна = Истина;
			СтрокаПриложение.СообщениеОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Конечная точка ""%1"" временно недоступна.
				|Повторите попытку позднее.'"),
				СтрокаПриложение.КонечнаяТочкаКорреспондента);
		Иначе
			Попытка
				НастройкиТранспорта = РегистрыСведений.НастройкиТранспортаОбменаОбластейДанных.НастройкиТранспорта(
					СтрокаПриложение.КонечнаяТочкаКорреспондента);
			Исключение
				Информация = ИнформацияОбОшибке();

				ЗаписьЖурналаРегистрации(ОбменДаннымиВМоделиСервиса.СобытиеЖурналаРегистрацииНастройкаСинхронизацииДанных(),
					УровеньЖурналаРегистрации.Ошибка, , , ОбработкаОшибок.ПодробноеПредставлениеОшибки(Информация));

				СтрокаПриложение.НастройкаСинхронизацииНедоступна = Истина;
				СтрокаПриложение.СообщениеОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Не удалось получить настройки подключения для приложения ""%1"" по причине:
					|%2
					|Повторите попытку позднее.'"),
					НастройкаИзМенеджераСервиса.НаименованиеПриложения,
					ОбработкаОшибок.КраткоеПредставлениеОшибки(Информация));
			КонецПопытки;
		КонецЕсли;

		Если Не ЗначениеЗаполнено(НастройкаИзМенеджераСервиса.КодПредопределенногоУзла)
			И НастройкаИзМенеджераСервиса.ЭтоПланОбменаXDTO
			И НастройкаИзМенеджераСервиса.СинхронизацияНастроена Тогда

			Отбор = Новый Структура("ОбластьДанных, ПланОбмена");
			ЗаполнитьЗначенияСвойств(Отбор, НастройкаИзМенеджераСервиса);

			Области = ОбластиДляОпределенияКодовУзлов.НайтиСтроки(Отбор);
			Если Области.Количество() > 0 Тогда
				Область = Области[0];

				Для Каждого СтрокаКодыУзлов Из Область.КодыУзлов Цикл
					Если Не ЗначениеЗаполнено(СтрокаКодыУзлов.КодПредопределенногоУзла) Тогда
						Продолжить;
					КонецЕсли;

					НастройкаИзМенеджераСервиса.КодПредопределенногоУзла = СтрокаКодыУзлов.КодПредопределенногоУзла;
					Прервать;
				КонецЦикла;
			КонецЕсли;
		КонецЕсли;

		Если ЗначениеЗаполнено(НастройкаИзМенеджераСервиса.КодПредопределенногоУзла) Тогда
			СтрокаПриложение.Корреспондент = ОбменДаннымиСервер.УзелПланаОбменаПоКоду(СтрокаПриложение.ИмяПланаОбмена,
				НастройкаИзМенеджераСервиса.КодПредопределенногоУзла);
		КонецЕсли;

		Если Не ЗначениеЗаполнено(СтрокаПриложение.Корреспондент) Тогда
			КодУзлаМС = ОбменДаннымиВМоделиСервиса.КодУзлаПланаОбменаВСервисе(СтрокаПриложение.ОбластьДанных);
			СтрокаПриложение.Корреспондент = ОбменДаннымиСервер.УзелПланаОбменаПоКоду(СтрокаПриложение.ИмяПланаОбмена, КодУзлаМС);
		Иначе

			ОбластьДанныхКорреспондента = РегистрыСведений.НастройкиОбменаДаннымиXDTO.ЗначениеНастройкиКорреспондента(СтрокаПриложение.Корреспондент,
				"ОбластьДанныхКорреспондента");

			Если ОбластьДанныхКорреспондента = Неопределено Тогда
				РегистрыСведений.НастройкиОбменаДаннымиXDTO.ОбновитьНастройкиКорреспондента(СтрокаПриложение.Корреспондент,
					"ОбластьДанныхКорреспондента", НастройкаИзМенеджераСервиса.ОбластьДанных);
			КонецЕсли;

			Если ДоступенExchangeAdministrationManage_3_0_1_1 Тогда
				РегистрыСведений.НастройкиОбменаДаннымиXDTO.ОбновитьНастройкиКорреспондента(СтрокаПриложение.Корреспондент,
					"ДоступенExchangeAdministrationManage_3_0_1_1", СтрокаПриложение.ДоступенExchangeAdministrationManage_3_0_1_1);
			КонецЕсли;

		КонецЕсли;

		Если Параметры.Режим = "НеНастроенныеОбмены"
			И ЗначениеЗаполнено(СтрокаПриложение.Корреспондент) Тогда
			ТаблицаПриложений.Удалить(СтрокаПриложение);
		ИначеЕсли Параметры.Режим = "НастроенныеОбмены"
			И Не ЗначениеЗаполнено(СтрокаПриложение.Корреспондент) Тогда
			ТаблицаПриложений.Удалить(СтрокаПриложение);
		КонецЕсли;

	КонецЦикла;

	Возврат ТаблицаПриложений;

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


Процедура СформироватьУровеньМетаданных(ТекущийНомерСтроки, Параметры, ИндексКартинки, ИндексКартинкиУзлов, ДобавлятьПодчиненные, ИмяМета, ПредставлениеМета)

	ПредставленияУровня = Новый Массив;
	Авторегистрации     = Новый Массив;
	ИменаУровня         = Новый Массив;

	ВсеСтроки = Параметры.Строки;
	МетаПлан  = Параметры.ПланОбмена;

	СоставПодписокМРО = Неопределено;
	ПроверятьСоставПодписокМРО = Параметры.Свойство("СоставПодписокМРО", СоставПодписокМРО);

	СтрокаГруппа = ВсеСтроки.Добавить();
	СтрокаГруппа.ИдентификаторСтроки = ТекущийНомерСтроки;

	СтрокаГруппа.МетаПолноеИмя  = ИмяМета;
	СтрокаГруппа.Наименование   = ПредставлениеМета;
	СтрокаГруппа.ИндексКартинки = ИндексКартинки;

	Строки = СтрокаГруппа.Строки;
	БылиПодчиненные = Ложь;

	Для Каждого Мета Из Метаданные[ИмяМета] Цикл

		Если МетаПлан = Неопределено Тогда
			// Без учета плана обмена

			Если Не ОбъектМетаданныхДоступенПоФункциональнымОпциям(Мета) Тогда
				Продолжить;
			КонецЕсли;

			БылиПодчиненные = Истина;
			МетаПолноеИмя   = Мета.ПолноеИмя();
			Наименование    = Мета.Представление();

			Если ДобавлятьПодчиненные Тогда

				НовСтрока = Строки.Добавить();
				НовСтрока.МетаПолноеИмя  = МетаПолноеИмя;
				НовСтрока.Наименование   = Наименование ;
				НовСтрока.ИндексКартинки = ИндексКартинкиУзлов;

				ТекущийНомерСтроки = ТекущийНомерСтроки + 1;
				НовСтрока.ИдентификаторСтроки = ТекущийНомерСтроки;

			КонецЕсли;

			ИменаУровня.Добавить(МетаПолноеИмя);
			ПредставленияУровня.Добавить(Наименование);

		Иначе

			Элемент = МетаПлан.Состав.Найти(Мета);

			Если Элемент <> Неопределено И ПравоДоступа("Чтение", Мета) Тогда

				Если ИменаСкрываемыхМетаданных.НайтиПоЗначению(Мета.ПолноеИмя()) <> Неопределено Тогда
					Продолжить;
				КонецЕсли;

				Если КонфигурацияПоддерживаетБСП
					И ПроверятьСоставПодписокМРО
					И СоставПодписокМРО.Найти(Мета) = Неопределено Тогда
					Продолжить;
				КонецЕсли;

				Если Не ОбъектМетаданныхДоступенПоФункциональнымОпциям(Мета) Тогда
					Продолжить;
				КонецЕсли;

				БылиПодчиненные = Истина;
				МетаПолноеИмя   = Мета.ПолноеИмя();
				Наименование    = Мета.Представление();
				Авторегистрация = ?(Элемент.Авторегистрация = АвтоРегистрацияИзменений.Запретить, 1, 2);

				Если ДобавлятьПодчиненные Тогда

					НовСтрока = Строки.Добавить();
					НовСтрока.МетаПолноеИмя   = МетаПолноеИмя;
					НовСтрока.Наименование    = Наименование ;
					НовСтрока.ИндексКартинки  = ИндексКартинкиУзлов;
					НовСтрока.Авторегистрация = Авторегистрация;

					ТекущийНомерСтроки = ТекущийНомерСтроки + 1;
					НовСтрока.ИдентификаторСтроки = ТекущийНомерСтроки;

				КонецЕсли;

				ИменаУровня.Добавить(МетаПолноеИмя);
				ПредставленияУровня.Добавить(Наименование);
				Авторегистрации.Добавить(Авторегистрация);

			КонецЕсли;
		КонецЕсли;

	КонецЦикла;

	Если БылиПодчиненные Тогда
		Строки.Сортировать("Наименование");
		Параметры.СтруктураИмен.Вставить(ИмяМета, ИменаУровня);
		Параметры.СтруктураПредставлений.Вставить(ИмяМета, ПредставленияУровня);
		Если Не ДобавлятьПодчиненные Тогда
			Параметры.СтруктураАвторегистрации.Вставить(ИмяМета, Авторегистрации);
		КонецЕсли;
	Иначе
		// Виды объектов без регистрации не вставляем.
		ВсеСтроки.Удалить(СтрокаГруппа);
	КонецЕсли;

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

// Определяет доступность объекта метаданных по функциональным опциям.
//
// Параметры:
//   ОбъектМетаданных - ОбъектМетаданных - проверяемый объект метаданных.
//
// Возвращаемое значение:
//  Булево - Истина, если объект доступен.
//

Функция ОбъектМетаданныхДоступенПоФункциональнымОпциям(ОбъектМетаданных)

	Если Не ЗначениеЗаполнено(ДоступностьОбъектовПоОпциям) Тогда
		ДоступностьОбъектовПоОпциям = ДоступностьОбъектовПоОпциям();
	КонецЕсли;

	Возврат ДоступностьОбъектовПоОпциям[ОбъектМетаданных] <> Ложь;

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

// Доступность объектов метаданных по функциональным опциям.

Функция ДоступностьОбъектовПоОпциям()

	Параметры = Новый Структура();

	ДоступностьОбъектов = Новый Соответствие;

	Для Каждого ФункциональнаяОпция Из Метаданные.ФункциональныеОпции Цикл

		Значение = -1;

		Для Каждого Элемент Из ФункциональнаяОпция.Состав Цикл

			Если Значение = -1 Тогда
				Значение = ПолучитьФункциональнуюОпцию(ФункциональнаяОпция.Имя, Параметры);
			КонецЕсли;

			Если Значение = Истина Тогда
				ДоступностьОбъектов.Вставить(Элемент.Объект, Истина);
			Иначе
				Если ДоступностьОбъектов[Элемент.Объект] = Неопределено Тогда
					ДоступностьОбъектов.Вставить(Элемент.Объект, Ложь);
				КонецЕсли;
			КонецЕсли;

		КонецЦикла;

	КонецЦикла;

	Возврат ДоступностьОбъектов;

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

// Накапливаем результаты регистраций.
//

Процедура ДобавитьРезультаты(Приемник, Источник)
	Приемник.Успешно = Приемник.Успешно + Источник.Успешно;
	Приемник.Всего   = Приемник.Всего   + Источник.Всего;
КонецПроцедуры

// Возвращает массив дополнительно регистрируемых объектов согласно флагам.
//


Процедура ЗаполнитьДеревоСвойств(ИмяКоманды = "")

	Свойства.ПолучитьЭлементы().Очистить();

	Если Не ПустаяСтрока(ИмяКоманды) Тогда

		НомерСвойстваВТаблице = Число(Прав(ИмяКоманды, 1));

		НайденныеСтроки = ТаблицаДопРеквизитовСвойств.НайтиСтроки(Новый Структура("ПорядковыйНомер", НомерСвойстваВТаблице));
		ТекущееСвойствоПанелиНавигации                   = НайденныеСтроки[0].ДопРеквизитСведение;
		ТекущееСвойствоПанелиНавигацииЯвляетсяРеквизитом = НайденныеСтроки[0].ЭтоРеквизит;
		ПредставлениеТекущегоСвойства                    = НайденныеСтроки[0].Представление;

	КонецЕсли;

	Элементы.СвойстваПредставление.Заголовок  = ПредставлениеТекущегоСвойства;

	Запрос = Новый Запрос;
	ТекстУсловия = "";

	ТекстУсловияПоОтборуСписка =  ПолучитьТекстЗапросаПоОтборуСписка(Запрос);
	Если Не ПустаяСтрока(ТекстУсловияПоОтборуСписка) Тогда
		Запрос.Текст = ТекстУсловияПоОтборуСписка;

		ТекстУсловия = " ГДЕ
			|(ДокументВзаимодействий.Ссылка В
			|	(ВЫБРАТЬ РАЗЛИЧНЫЕ
			|		ОтборСписка.Ссылка
			|	ИЗ
			|		ОтборСписка КАК ОтборСписка))";

	КонецЕсли;

	Если ТекущееСвойствоПанелиНавигацииЯвляетсяРеквизитом Тогда
		Запрос.Текст = Запрос.Текст + "
		|ВЫБРАТЬ РАЗРЕШЕННЫЕ
		|	ВложенныйЗапрос.Значение КАК Значение,
		|	СУММА(ВложенныйЗапрос.НеРассмотрено) КАК НеРассмотрено,
		|	1 КАК НомерКартинки,
		|	ВЫБОР
		|		КОГДА ВложенныйЗапрос.Значение = &НеУказан
		|			ТОГДА &НеУказанПредставление
		|		ИНАЧЕ ПРЕДСТАВЛЕНИЕ(ВложенныйЗапрос.Значение)
		|	КОНЕЦ КАК Представление
		|ИЗ
		|	(ВЫБРАТЬ
		|		ДокументВзаимодействий.Ссылка КАК Ссылка,
		|		ЕСТЬNULL(ДокументВзаимодействийДополнительныеРеквизиты.Значение, &НеУказан) КАК Значение,
		|		ВЫБОР
		|			КОГДА ПредметыПапкиВзаимодействий.Рассмотрено
		|				ТОГДА 0
		|			ИНАЧЕ 1
		|		КОНЕЦ КАК НеРассмотрено
		|	ИЗ
		|		Документ.ЭлектронноеПисьмоИсходящее КАК ДокументВзаимодействий
		|			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПредметыПапкиВзаимодействий КАК ПредметыПапкиВзаимодействий
		|			ПО ДокументВзаимодействий.Ссылка = ПредметыПапкиВзаимодействий.Взаимодействие
		|			ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЭлектронноеПисьмоИсходящее.ДополнительныеРеквизиты КАК ДокументВзаимодействийДополнительныеРеквизиты
		|			ПО (ДокументВзаимодействийДополнительныеРеквизиты.Ссылка = ДокументВзаимодействий.Ссылка)
		|				И (ДокументВзаимодействийДополнительныеРеквизиты.Свойство = &Свойство)
		|				И &ТекстУсловия
		|
		|	ОБЪЕДИНИТЬ ВСЕ
		|
		|	ВЫБРАТЬ
		|		ДокументВзаимодействий.Ссылка,
		|		ЕСТЬNULL(ДокументВзаимодействийДополнительныеРеквизиты.Значение, &НеУказан),
		|		ВЫБОР
		|			КОГДА ПредметыПапкиВзаимодействий.Рассмотрено
		|				ТОГДА 0
		|			ИНАЧЕ 1
		|		КОНЕЦ
		|	ИЗ
		|		Документ.ЭлектронноеПисьмоВходящее КАК ДокументВзаимодействий
		|			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПредметыПапкиВзаимодействий КАК ПредметыПапкиВзаимодействий
		|			ПО ДокументВзаимодействий.Ссылка = ПредметыПапкиВзаимодействий.Взаимодействие
		|			ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЭлектронноеПисьмоВходящее.ДополнительныеРеквизиты КАК ДокументВзаимодействийДополнительныеРеквизиты
		|			ПО (ДокументВзаимодействийДополнительныеРеквизиты.Ссылка = ДокументВзаимодействий.Ссылка)
		|				И (ДокументВзаимодействийДополнительныеРеквизиты.Свойство = &Свойство)
		|				И &ТекстУсловия
		|
		|	ОБЪЕДИНИТЬ ВСЕ
		|
		|	ВЫБРАТЬ
		|		ДокументВзаимодействий.Ссылка,
		|		ЕСТЬNULL(ДокументВзаимодействийДополнительныеРеквизиты.Значение, &НеУказан),
		|		ВЫБОР
		|			КОГДА ПредметыПапкиВзаимодействий.Рассмотрено
		|				ТОГДА 0
		|			ИНАЧЕ 1
		|		КОНЕЦ
		|	ИЗ
		|		Документ.Встреча КАК ДокументВзаимодействий
		|			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПредметыПапкиВзаимодействий КАК ПредметыПапкиВзаимодействий
		|			ПО ДокументВзаимодействий.Ссылка = ПредметыПапкиВзаимодействий.Взаимодействие
		|			ЛЕВОЕ СОЕДИНЕНИЕ Документ.Встреча.ДополнительныеРеквизиты КАК ДокументВзаимодействийДополнительныеРеквизиты
		|			ПО (ДокументВзаимодействийДополнительныеРеквизиты.Ссылка = ДокументВзаимодействий.Ссылка)
		|				И (ДокументВзаимодействийДополнительныеРеквизиты.Свойство = &Свойство)
		|				И &ТекстУсловия
		|
		|	ОБЪЕДИНИТЬ ВСЕ
		|
		|	ВЫБРАТЬ
		|		ДокументВзаимодействий.Ссылка,
		|		ЕСТЬNULL(ДокументВзаимодействийДополнительныеРеквизиты.Значение, &НеУказан),
		|		ВЫБОР
		|			КОГДА ПредметыПапкиВзаимодействий.Рассмотрено
		|				ТОГДА 0
		|			ИНАЧЕ 1
		|		КОНЕЦ
		|	ИЗ
		|		Документ.ТелефонныйЗвонок КАК ДокументВзаимодействий
		|			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПредметыПапкиВзаимодействий КАК ПредметыПапкиВзаимодействий
		|			ПО ДокументВзаимодействий.Ссылка = ПредметыПапкиВзаимодействий.Взаимодействие
		|			ЛЕВОЕ СОЕДИНЕНИЕ Документ.ТелефонныйЗвонок.ДополнительныеРеквизиты КАК ДокументВзаимодействийДополнительныеРеквизиты
		|			ПО (ДокументВзаимодействийДополнительныеРеквизиты.Ссылка = ДокументВзаимодействий.Ссылка)
		|				И (ДокументВзаимодействийДополнительныеРеквизиты.Свойство = &Свойство)
		|				И &ТекстУсловия
		|
		|	ОБЪЕДИНИТЬ ВСЕ
		|
		|	ВЫБРАТЬ
		|		ДокументВзаимодействий.Ссылка,
		|		ЕСТЬNULL(ДокументВзаимодействийДополнительныеРеквизиты.Значение, &НеУказан),
		|		ВЫБОР
		|			КОГДА ПредметыПапкиВзаимодействий.Рассмотрено
		|				ТОГДА 0
		|			ИНАЧЕ 1
		|		КОНЕЦ
		|	ИЗ
		|		Документ.СообщениеSMS КАК ДокументВзаимодействий
		|			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПредметыПапкиВзаимодействий КАК ПредметыПапкиВзаимодействий
		|			ПО ДокументВзаимодействий.Ссылка = ПредметыПапкиВзаимодействий.Взаимодействие
		|			ЛЕВОЕ СОЕДИНЕНИЕ Документ.СообщениеSMS.ДополнительныеРеквизиты КАК ДокументВзаимодействийДополнительныеРеквизиты
		|			ПО (ДокументВзаимодействийДополнительныеРеквизиты.Ссылка = ДокументВзаимодействий.Ссылка)
		|				И (ДокументВзаимодействийДополнительныеРеквизиты.Свойство = &Свойство)
		|				И &ТекстУсловия
		|
		|	ОБЪЕДИНИТЬ ВСЕ
		|
		|	ВЫБРАТЬ
		|		ДокументВзаимодействий.Ссылка,
		|		ЕСТЬNULL(ДокументВзаимодействийДополнительныеРеквизиты.Значение, &НеУказан),
		|		ВЫБОР
		|			КОГДА ПредметыПапкиВзаимодействий.Рассмотрено
		|				ТОГДА 0
		|			ИНАЧЕ 1
		|		КОНЕЦ
		|	ИЗ
		|		Документ.ЗапланированноеВзаимодействие КАК ДокументВзаимодействий
		|			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПредметыПапкиВзаимодействий КАК ПредметыПапкиВзаимодействий
		|			ПО ДокументВзаимодействий.Ссылка = ПредметыПапкиВзаимодействий.Взаимодействие
		|			ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗапланированноеВзаимодействие.ДополнительныеРеквизиты КАК ДокументВзаимодействийДополнительныеРеквизиты
		|			ПО (ДокументВзаимодействийДополнительныеРеквизиты.Ссылка = ДокументВзаимодействий.Ссылка)
		|				И (ДокументВзаимодействийДополнительныеРеквизиты.Свойство = &Свойство)
		|				И &ТекстУсловия) КАК ВложенныйЗапрос
		|
		|СГРУППИРОВАТЬ ПО
		|	ВложенныйЗапрос.Значение
		|
		|УПОРЯДОЧИТЬ ПО
		|	Значение
		|ИТОГИ ПО
		|	Значение ИЕРАРХИЯ";

	Иначе

		Запрос.Текст = Запрос.Текст + "
		|ВЫБРАТЬ РАЗРЕШЕННЫЕ
		|	ВложенныйЗапрос.Значение                        КАК Значение,
		|	СУММА(ВложенныйЗапрос.НеРассмотрено)            КАК НеРассмотрено,
		|	1                                               КАК НомерКартинки,
		|	ВЫБОР
		|		КОГДА ВложенныйЗапрос.Значение = &НеУказан
		|			ТОГДА &НеУказанПредставление
		|		ИНАЧЕ ПРЕДСТАВЛЕНИЕ(ВложенныйЗапрос.Значение)
		|		КОНЕЦ КАК Представление
		|	ИЗ
		|	(ВЫБРАТЬ
		|		ДокументВзаимодействий.Ссылка КАК Ссылка,
		|		ВЫБОР
		|			КОГДА ПредметыПапкиВзаимодействий.Рассмотрено
		|				ТОГДА 0
		|			ИНАЧЕ 1
		|		КОНЕЦ КАК НеРассмотрено,
		|		ЕСТЬNULL(ДополнительныеСведения.Значение, &НеУказан) КАК Значение
		|	ИЗ
		|		ЖурналДокументов.Взаимодействия КАК ДокументВзаимодействий
		|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПредметыПапкиВзаимодействий КАК ПредметыПапкиВзаимодействий
		|			ПО ДокументВзаимодействий.Ссылка = ПредметыПапкиВзаимодействий.Взаимодействие
		|			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
		|			ПО ДокументВзаимодействий.Ссылка = ДополнительныеСведения.Объект
		|				И (ДополнительныеСведения.Свойство = &Свойство)
		|			И &ТекстУсловия) КАК ВложенныйЗапрос
		|
		|СГРУППИРОВАТЬ ПО
		|	ВложенныйЗапрос.Значение
		|
		|УПОРЯДОЧИТЬ ПО
		|Значение
		|
		|ИТОГИ ПО
		|Значение ИЕРАРХИЯ";

	КонецЕсли;

	Запрос.Текст = СтрЗаменить(Запрос.Текст, "И &ТекстУсловия", ТекстУсловия);

	Запрос.УстановитьПараметр("Свойство",              ТекущееСвойствоПанелиНавигации);
	Запрос.УстановитьПараметр("НеУказан",              "НеУказан");
	Запрос.УстановитьПараметр("НеУказанПредставление", НСтр("ru = 'Не указан'"));

	Результат = Запрос.Выполнить();
	Дерево = Результат.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);

	СтрокиПервыйУровень = Свойства.ПолучитьЭлементы();

	Для Каждого Строка Из Дерево.Строки Цикл
		СтрокаСвойства =  СтрокиПервыйУровень.Добавить();
		ЗаполнитьЗначенияСвойств(СтрокаСвойства, Строка);
		СтрокаСвойства.НомерКартинки = ?(ТипЗнч(СтрокаСвойства.Значение) = Тип("Строка"), 0, 1);
		СтрокаСвойства.Представление = Строка(СтрокаСвойства.Значение)
		                               + ?(Строка.НеРассмотрено = 0 Или Не ИспользоватьПризнакРассмотрено,
		                               "", " (" + Строка(Строка.НеРассмотрено) + ")");
		ДобавитьСтрокиВДеревоНавигации(Строка, СтрокаСвойства, Истина, 1);
	КонецЦикла;

	ДобавитьСтрокуВсе(Свойства, 2);

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

&НаСервере


Процедура КомментарийНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)

	ОбщегоНазначенияКлиент.ПоказатьФормуРедактированияКомментария(Элемент.ТекстРедактирования, ЭтотОбъект);

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

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте

Процедура ФормаЗаполненияЗаписать(Команда)

	Отказ = ОкончаниеРедактированиеФормыЗаполнения(РежимЗаписиДокумента.Запись);
	Если Не Отказ Тогда

		ПоказатьОповещениеПользователя(НСтр("ru = 'Изменение'"),, Строка(Объект.Ссылка),
			БиблиотекаКартинок.Информация32);

		Оповестить("Запись_Анкета", Новый Структура, Объект.Ссылка);

	КонецЕсли;

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

&НаКлиенте

Процедура ФормаЗаполненияЗавершитьИЗакрыть(Команда)

	ОбработчикОповещенияОЗакрытии = Новый ОписаниеОповещения("ВопросОПринятииАнкетыПослеЗавершения", ЭтотОбъект);
	ПоказатьВопрос(ОбработчикОповещенияОЗакрытии,
		НСтр("ru = 'Ваша анкета будет принята.
			|Дальнейшее заполнение анкеты будет невозможно.
			|Продолжить?'"), РежимДиалогаВопрос.ДаНет);

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

&НаКлиенте

Процедура ПоказатьРазделы(Команда)

	ИзменитьВидимостьДеревоРазделов();

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

&НаКлиенте

Процедура СледующийРаздел(Команда)

	ИзменитьРаздел("Вперед");

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

&НаКлиенте

Процедура ПредыдущийРаздел(Команда)

	ИзменитьРаздел("Назад");

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

&НаКлиенте

Процедура ВыборРаздела(Команда)

	ВыполнитьПостроениеФормыЗаполнения();
	УстановитьДоступностьНавигацииРазделов();

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

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

////////////////////////////////////////////////////////////////////////////////
// Установка значений реквизитов формы.

&НаСервере

Процедура УстановитьЗначенияРеквизитовФормыЗаполненияРаздела()

	ТаблицаВопросовРаздела.Выгрузить().ВыгрузитьКолонку("ВопросШаблона");

	Запрос = Новый Запрос;
	Запрос.Текст =
		"ВЫБРАТЬ
		|	ВнешнийИсточник.Вопрос КАК Вопрос,
		|	ВЫРАЗИТЬ(ВнешнийИсточник.ЭлементарныйВопрос КАК ПланВидовХарактеристик.ВопросыДляАнкетирования) КАК ЭлементарныйВопрос,
		|	ВнешнийИсточник.НомерЯчейки КАК НомерЯчейки,
		|	ВнешнийИсточник.Ответ КАК Ответ,
		|	ВнешнийИсточник.ОткрытыйОтвет КАК ОткрытыйОтвет,
		|	ВнешнийИсточник.БезОтвета КАК БезОтвета
		|ПОМЕСТИТЬ ТаблицаОтветов
		|ИЗ
		|	&ВнешнийИсточник КАК ВнешнийИсточник
		|ГДЕ
		|	ВнешнийИсточник.Вопрос В(&ВопросыРаздела)
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ТаблицаОтветов.Вопрос КАК Вопрос,
		|	ТаблицаОтветов.ЭлементарныйВопрос КАК ЭлементарныйВопрос,
		|	ТаблицаОтветов.НомерЯчейки КАК НомерЯчейки,
		|	ТаблицаОтветов.Ответ КАК Ответ,
		|	ТаблицаОтветов.ОткрытыйОтвет КАК ОткрытыйОтвет,
		|	ТаблицаОтветов.ЭлементарныйВопрос.ТребуетсяКомментарий КАК ТребуетОткрытогоОтвета,
		|	ТаблицаОтветов.БезОтвета КАК БезОтвета
		|ИЗ
		|	ТаблицаОтветов КАК ТаблицаОтветов
		|ИТОГИ ПО
		|	Вопрос";

	Запрос.УстановитьПараметр("ВнешнийИсточник", Объект.Состав.Выгрузить());
	Запрос.УстановитьПараметр("ВопросыРаздела", ТаблицаВопросовРаздела.Выгрузить().ВыгрузитьКолонку("ВопросШаблона"));

	Результат = Запрос.Выполнить();
	Если Не Результат.Пустой() Тогда

		Выборка = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
		Пока Выборка.Следующий() Цикл

			ВыборкаВопрос = Выборка.Выбрать();
			УстановитьЗначениеРеквизита(Выборка.Вопрос, ВыборкаВопрос);

		КонецЦикла;

	КонецЕсли;

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

// Параметры:
//  ВопросШаблона  - СправочникСсылка.ВопросыШаблонаАнкеты - вопрос шаблона анкеты,
//                 для которого устанавливаются значения реквизитов.
//  ВыборкаВопрос  - ВыборкаИзРезультатаЗапроса - выборка, содержащая значения ответов
//                 на вопрос шаблона анкеты.
//  ДеревоАнкетыСервер  - ДеревоЗначений - дерево значений, содержащее шаблон анкеты.
//
&НаСервере

Процедура УстановитьЗначениеРеквизита(ВопросШаблона, ВыборкаВопрос)

	НайденныеСтроки = ТаблицаВопросовРаздела.НайтиСтроки(Новый Структура("ВопросШаблона", ВопросШаблона));

	Если НайденныеСтроки.Количество() > 0 Тогда
		НайденнаяСтрока = НайденныеСтроки[0];
		Если НайденнаяСтрока.ТипВопроса = Перечисления.ТипыВопросовШаблонаАнкеты.Табличный Тогда
			УстановитьЗначениеРеквизитаТабличныйВопрос(ВопросШаблона, ВыборкаВопрос, НайденнаяСтрока);
			УстановитьЗначенияРеквизитаКомплексныйВопрос(ВопросШаблона, ВыборкаВопрос, НайденнаяСтрока);
		ИначеЕсли НайденнаяСтрока.ТипВопроса = Перечисления.ТипыВопросовШаблонаАнкеты.Комплексный Тогда
			УстановитьЗначенияРеквизитаКомплексныйВопрос(ВопросШаблона, ВыборкаВопрос, НайденнаяСтрока);
		Иначе
			УстановитьЗначениеРеквизитаПростойВопрос(ВопросШаблона, ВыборкаВопрос, НайденнаяСтрока);
		КонецЕсли;
	КонецЕсли;

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

// Параметры:
//  Вопрос  - СправочникСсылка.ВопросыШаблонаАнкеты - вопрос шаблона анкеты,
//                 для которого устанавливаются значения реквизитов.
//  ВыборкаВопрос  - ВыборкаИзРезультатаЗапроса - выборка, содержащая значения ответов
//                 на вопрос шаблона анкеты.
//  СтрокаДерева  - СтрокаДереваЗначений - строка дерева значений, содержащая данные вопроса шаблона анкеты.
//
&НаСервере


Процедура СвойстваВыполнитьОтложеннуюИнициализацию()

	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Свойства") Тогда
		МодульУправлениеСвойствами = ОбщегоНазначения.ОбщийМодуль("УправлениеСвойствами");
		МодульУправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме(ЭтотОбъект);
	КонецЕсли;

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

&НаКлиенте

Процедура Подключаемый_ПриИзмененииДополнительногоРеквизита(Элемент)

	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.Свойства") Тогда
		МодульУправлениеСвойствамиКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("УправлениеСвойствамиКлиент");
		МодульУправлениеСвойствамиКлиент.ОбновитьЗависимостиДополнительныхРеквизитов(ЭтотОбъект);
	КонецЕсли;

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

&НаСервере

Процедура ОбновитьЭлементыДополнительныхРеквизитов()

	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Свойства") Тогда
		МодульУправлениеСвойствами = ОбщегоНазначения.ОбщийМодуль("УправлениеСвойствами");
		МодульУправлениеСвойствами.ОбновитьЭлементыДополнительныхРеквизитов(ЭтотОбъект);
	КонецЕсли;

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

&НаКлиенте

Процедура ОбновитьЗависимостиДополнительныхРеквизитов()

	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.Свойства") Тогда
		МодульУправлениеСвойствамиКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("УправлениеСвойствамиКлиент");
		МодульУправлениеСвойствамиКлиент.ОбновитьЗависимостиДополнительныхРеквизитов(ЭтотОбъект);
	КонецЕсли;

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

// Конец СтандартныеПодсистемы.Свойства

&НаКлиенте

Процедура ПроверитьДоступностьСозданияКонтакта()

	Элементы.СоздатьКонтакт.Доступность = (НЕ Объект.Ссылка.Пустая())
	                                      И (Не ЗначениеЗаполнено(Объект.АбонентКонтакт))
	                                      И (Не ПустаяСтрока(Объект.АбонентПредставление));

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

// СтандартныеПодсистемы.ПодключаемыеКоманды
&НаКлиенте

Процедура Подключаемый_ВыполнитьКоманду(Команда)
	МодульПодключаемыеКомандыКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ПодключаемыеКомандыКлиент");
	МодульПодключаемыеКомандыКлиент.НачатьВыполнениеКоманды(ЭтотОбъект, Команда, Объект);
КонецПроцедуры

&НаКлиенте

Процедура Подключаемый_ПродолжитьВыполнениеКомандыНаСервере(ПараметрыВыполнения, ДополнительныеПараметры) Экспорт
	ВыполнитьКомандуНаСервере(ПараметрыВыполнения);
КонецПроцедуры

&НаСервере

Процедура ВыполнитьКомандуНаСервере(ПараметрыВыполнения)
	МодульПодключаемыеКоманды = ОбщегоНазначения.ОбщийМодуль("ПодключаемыеКоманды");
	МодульПодключаемыеКоманды.ВыполнитьКоманду(ЭтотОбъект, ПараметрыВыполнения, Объект);
КонецПроцедуры

&НаКлиенте

Процедура Подключаемый_ОбновитьКоманды()
	МодульПодключаемыеКомандыКлиентСервер = ОбщегоНазначенияКлиент.ОбщийМодуль("ПодключаемыеКомандыКлиентСервер");
	МодульПодключаемыеКомандыКлиентСервер.ОбновитьКоманды(ЭтотОбъект, Объект);
КонецПроцедуры
// Конец СтандартныеПодсистемы.ПодключаемыеКоманды

#КонецОбласти


Процедура ЗаполнитьКонтакты(Контакты) Экспорт

	Если Не Взаимодействия.КонтактыЗаполнены(Контакты) Тогда
		Возврат;
	КонецЕсли;

	Для Каждого СтрокаТаблицы Из Контакты Цикл

		Адрес = Неопределено;

		Если ТипЗнч(СтрокаТаблицы) = Тип("Структура") Тогда
			// В документ попадут только те контакты, для которых заданы адреса электронной почты.
			МассивАдресов = СтрРазделить(СтрокаТаблицы.Адрес, ",");
			Для каждого ЭлементМассиваАдресов Из МассивАдресов Цикл
				Попытка
					Результат = ОбщегоНазначенияКлиентСервер.РазобратьСтрокуСПочтовымиАдресами(ЭлементМассиваАдресов);
				Исключение
					// Введенная строка с e-mail адресами введена неправильно.
					Продолжить;
				КонецПопытки;
				Если Результат.Количество() > 0 И НЕ ПустаяСтрока(Результат[0]) Тогда
					Адрес = Результат[0];
				КонецЕсли;
				Если Адрес <> Неопределено Тогда
					Прервать;
				КонецЕсли;
			КонецЦикла;

			Если Адрес = Неопределено И ЗначениеЗаполнено(СтрокаТаблицы.Контакт) Тогда
				МассивАдресовЭП = ВзаимодействияВызовСервера.ПолучитьАдресаЭлектроннойПочтыКонтакта(СтрокаТаблицы.Контакт);
				Если МассивАдресовЭП.Количество() > 0 Тогда
					Адрес = Новый Структура("Адрес",МассивАдресовЭП[0].АдресЭП);
				КонецЕсли;
			КонецЕсли;

			Если НЕ Адрес = Неопределено Тогда

				НоваяСтрока = ПолучателиПисьма.Добавить();

				НоваяСтрока.Контакт = СтрокаТаблицы.Контакт;
				НоваяСтрока.Представление = СтрокаТаблицы.Представление;
				НоваяСтрока.Адрес = Адрес.Адрес;
			Иначе
				Продолжить;
			КонецЕсли;

		Иначе
			НоваяСтрока = ПолучателиПисьма.Добавить();
			НоваяСтрока.Контакт = СтрокаТаблицы;
		КонецЕсли;

		Взаимодействия.ДозаполнитьПоляКонтактов(НоваяСтрока.Контакт, НоваяСтрока.Представление,
			НоваяСтрока.Адрес, Перечисления.ТипыКонтактнойИнформации.АдресЭлектроннойПочты);

	КонецЦикла;

	СформироватьПредставленияКонтактов();

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

// Конец СтандартныеПодсистемы.Взаимодействия

// СтандартныеПодсистемы.УправлениеДоступом

// Параметры:
//   Таблица - см. УправлениеДоступом.ТаблицаНаборыЗначенийДоступа
//

Процедура ЗаполнитьНаборыЗначенийДоступа(Таблица) Экспорт

	ВзаимодействияСобытия.ЗаполнитьНаборыЗначенийДоступа(ЭтотОбъект, Таблица);

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

// Конец СтандартныеПодсистемы.УправлениеДоступом

#КонецОбласти

#КонецОбласти

#Область ОбработчикиСобытий

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)

	Если ОбменДанными.Загрузка Тогда
		Возврат;
	КонецЕсли;

	ОбновлениеИнформационнойБазы.ПроверитьОбъектОбработан(ЭтотОбъект);

	ДанныеОбъектаДоЗаписи = ДанныеОбъектаДоЗаписи();

	ДополнительныеСвойства.Вставить("ПометкаУдаления", ДанныеОбъектаДоЗаписи.ПометкаУдаления);
	ДополнительныеСвойства.Вставить("СтатусПисьма",    ДанныеОбъектаДоЗаписи.СтатусПисьма);

	Если ПометкаУдаления <> ДанныеОбъектаДоЗаписи.ПометкаУдаления Тогда
		ЕстьВложения = ?(ПометкаУдаления, Ложь, РаботаСФайламиСлужебныйВызовСервера.КоличествоПрисоединенныхФайлов(Ссылка) > 0);
	КонецЕсли;

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

Процедура ПриЗаписи(Отказ)

	Если ОбменДанными.Загрузка Тогда
		Возврат;
	КонецЕсли;

	Взаимодействия.ПриЗаписиДокумента(ЭтотОбъект);
	Взаимодействия.ОтработатьПризнакИзмененияПометкиУдаленияПриЗаписиПисьма(ЭтотОбъект);

	ПредыдущийСтатус = ДополнительныеСвойства.СтатусПисьма;

	Если ЗначениеЗаполнено(УчетнаяЗапись)
		И (СтатусПисьма = Перечисления.СтатусыИсходящегоЭлектронногоПисьма.Исходящее
		  Или СтатусПисьма = Перечисления.СтатусыИсходящегоЭлектронногоПисьма.Отправлено)
		И (ПредыдущийСтатус <> Перечисления.СтатусыИсходящегоЭлектронногоПисьма.Исходящее
		  И ПредыдущийСтатус <> Перечисления.СтатусыИсходящегоЭлектронногоПисьма.Отправлено) Тогда

		РегистрыСведений.НастройкиУчетныхЗаписейЭлектроннойПочты.ОбновитьДатуИспользованияУчетнойЗаписи(УчетнаяЗапись);

	КонецЕсли;

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

Процедура ПередУдалением(Отказ)

	Если ОбменДанными.Загрузка Тогда
		Возврат;
	КонецЕсли;

	УправлениеЭлектроннойПочтой.УдалитьВложенияУПисьма(Ссылка);

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

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)

	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ШаблоныСообщений") Тогда
		МодульШаблоныСообщений = ОбщегоНазначения.ОбщийМодуль("ШаблоныСообщений");
		ЭтоШаблон = МодульШаблоныСообщений.ЭтоШаблон(ДанныеЗаполнения);
	Иначе
		ЭтоШаблон = Ложь;
	КонецЕсли;

	Если ЭтоШаблон Тогда

		ЗаполнитьНаОснованииШаблона(ДанныеЗаполнения);

	ИначеЕсли (ТипЗнч(ДанныеЗаполнения) = Тип("Структура")) И (ДанныеЗаполнения.Свойство("Основание"))
		 И (ТипЗнч(ДанныеЗаполнения.Основание) = Тип("ДокументСсылка.ЭлектронноеПисьмоВходящее")
		 ИЛИ ТипЗнч(ДанныеЗаполнения.Основание) = Тип("ДокументСсылка.ЭлектронноеПисьмоИсходящее")) Тогда

		Взаимодействия.ЗаполнитьРеквизитыПоУмолчанию(ЭтотОбъект, Неопределено);
		ЗаполнитьНаОснованииПисьма(ДанныеЗаполнения.Основание, ДанныеЗаполнения.Команда);

	Иначе
		Взаимодействия.ЗаполнитьРеквизитыПоУмолчанию(ЭтотОбъект, ДанныеЗаполнения);

	КонецЕсли;

	Важность = Перечисления.ВариантыВажностиВзаимодействия.Обычная;
	СтатусПисьма = Перечисления.СтатусыИсходящегоЭлектронногоПисьма.Черновик;
	Если ПустаяСтрока(Кодировка) Тогда
		Кодировка = "utf-8";
	КонецЕсли;

	// +++ 79Vlad  06.02.2019
	//Письма не должны отправляться через учетную запись, которая не используется для отправки
	Если ЗначениеЗаполнено(УчетнаяЗапись) И Не УчетнаяЗапись.ИспользоватьДляОтправки Тогда
		УчетнаяЗапись = Неопределено;
	КонецЕсли;
	// --- 79Vlad  06.02.2019

	Если Не ЗначениеЗаполнено(УчетнаяЗапись) Тогда
		УчетнаяЗапись = УправлениеЭлектроннойПочтой.ПолучитьУчетнуюЗаписьДляОтправкиПоУмолчанию();
	КонецЕсли;
	ОтправительПредставление = ПолучитьПредставлениеДляУчетнойЗаписи(УчетнаяЗапись);

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

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Процедура СформироватьПредставленияКонтактов()

	СписокПолучателейПисьма =
		ВзаимодействияКлиентСервер.ПолучитьПредставлениеСпискаАдресатов(ПолучателиПисьма, Ложь);
	СписокПолучателейКопий =
		ВзаимодействияКлиентСервер.ПолучитьПредставлениеСпискаАдресатов(ПолучателиКопий, Ложь);
	СписокПолучателейСкрытыхКопий =
		ВзаимодействияКлиентСервер.ПолучитьПредставлениеСпискаАдресатов(ПолучателиСкрытыхКопий, Ложь);

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

Процедура ЗаполнитьНаОснованииПисьма(Основание, ТипОтвета)

	ПереноситьОтправителя = Истина;
	ПереноситьВсехПолучателей = Ложь;
	ПереноситьВложения = Ложь;
	ДобавлятьКТеме = "RE: ";

	Если ТипОтвета = "ОтветитьВсем" Тогда
		ПереноситьВсехПолучателей = Истина;
	ИначеЕсли ТипОтвета = "Переслать" Тогда
		ДобавлятьКТеме = "FW: ";
		ПереноситьОтправителя = Ложь;
		ПереноситьВложения = Истина;
	ИначеЕсли ТипОтвета = "ПереслатьКакВложение" Тогда
		ДобавлятьКТеме = "";
		ПереноситьОтправителя = Ложь;
	КонецЕсли;

	ЗаполнитьПараметрыИзПисьма(Основание, ПереноситьОтправителя, ПереноситьВсехПолучателей,
		ДобавлятьКТеме, ПереноситьВложения,ТипОтвета);

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


Функция ПроверитьЗаполнениеСписковАдресатов()

	Отказ = Ложь;
	АдресаПоПредставлению = Новый Соответствие;
	АдресаПоЗначению = Новый Соответствие;
	ШаблонТекстаОшибки = НСтр("ru = 'Адрес %1 уже есть в списке.'");

	Для каждого СтрокаАдреса Из СписокПолучателей Цикл

		Результат = ОбщегоНазначенияКлиентСервер.АдресаЭлектроннойПочтыИзСтроки(СтрокаАдреса.Представление);
		Для Каждого СтруктураАдреса Из Результат Цикл

			Если Не ПустаяСтрока(СтруктураАдреса.ОписаниеОшибки) Тогда
				Отказ = Истина;
				ОбщегоНазначенияКлиент.СообщитьПользователю(СтруктураАдреса.ОписаниеОшибки,,
					"СписокПолучателей[" + Формат(СписокПолучателей.Индекс(СтрокаАдреса), "ЧГ=0") + "].Представление");
			КонецЕсли;

			Если АдресаПоПредставлению.Получить(СтруктураАдреса.Адрес) <> Неопределено Тогда
				Отказ = Истина;
				ОбщегоНазначенияКлиент.СообщитьПользователю(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонТекстаОшибки,
					СтруктураАдреса.Адрес),, "СписокПолучателей[" + Формат(СписокПолучателей.Индекс(СтрокаАдреса), "ЧГ=0") + "].Представление");
			Иначе
				АдресаПоПредставлению.Вставить(СтруктураАдреса.Адрес, СтрокаАдреса.ПолучитьИдентификатор());
			КонецЕсли;

		КонецЦикла;

		Если НЕ Отказ Тогда
			Результат = ОбщегоНазначенияКлиентСервер.АдресаЭлектроннойПочтыИзСтроки(СтрокаАдреса.Адрес);
			Для Каждого СтруктураАдреса Из Результат Цикл

				Если Не ПустаяСтрока(СтруктураАдреса.ОписаниеОшибки) Тогда
					Отказ = Истина;
					ОбщегоНазначенияКлиент.СообщитьПользователю(СтруктураАдреса.ОписаниеОшибки,,
						"СписокПолучателей[" + Формат(СписокПолучателей.Индекс(СтрокаАдреса), "ЧГ=0") + "].Представление");
				КонецЕсли;

				Если АдресаПоЗначению.Получить(СтруктураАдреса.Адрес) <> Неопределено Тогда
					Отказ = Истина;
					ОбщегоНазначенияКлиент.СообщитьПользователю(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонТекстаОшибки,
						СтруктураАдреса.Адрес),, "СписокПолучателей[" + Формат(СписокПолучателей.Индекс(СтрокаАдреса), "ЧГ=0") + "].Представление");
				Иначе
					АдресаПоЗначению.Вставить(СтруктураАдреса.Адрес, СтрокаАдреса.ПолучитьИдентификатор());
				КонецЕсли;

			КонецЦикла;
		КонецЕсли;

	КонецЦикла;

	Если НЕ Отказ Тогда

		Для каждого АдресПоЗначению Из АдресаПоЗначению Цикл
			Если АдресаПоПредставлению[АдресПоЗначению.Ключ] <> Неопределено
				И АдресаПоПредставлению[АдресПоЗначению.Ключ] <> АдресПоЗначению.Значение Тогда
					Отказ = Истина;
					Индекс = СписокПолучателей.Индекс(СписокПолучателей.НайтиПоИдентификатору(АдресПоЗначению.Значение));
					ОбщегоНазначенияКлиент.СообщитьПользователю(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонТекстаОшибки,
						АдресПоЗначению.Ключ),, "СписокПолучателей[" + Формат(Индекс, "ЧГ=0") + "].Представление");
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;

	Возврат Отказ;

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

&НаСервере

Функция НеобходимаОбработкаПисьмаОснования()

	Возврат ВыполняетсяОтправка И Объект.ВключатьТелоИсходногоПисьма И ПолучитьФункциональнуюОпцию("ОтправлятьПисьмаВФорматеHTML")
	        И (Не Объект.ВзаимодействиеОснование = Неопределено) И (Не Объект.ВзаимодействиеОснование.Пустая())
	        И Объект.СтатусПисьма = Перечисления.СтатусыИсходящегоЭлектронногоПисьма.Черновик;

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

&НаСервере

Процедура ОтобразитьВажность()

	Если Объект.Важность = Перечисления.ВариантыВажностиВзаимодействия.Высокая Тогда
		Элементы.ГруппаВажность.Картинка = БиблиотекаКартинок.ВажностьВысокая;
		Элементы.ГруппаВажность.Подсказка = НСтр("ru = 'Высокая важность'");
		Элементы.ВажностьДекорация.Картинка = БиблиотекаКартинок.ВажностьВысокая;
		Элементы.ВажностьДекорация.Подсказка = НСтр("ru = 'Высокая важность'");

	ИначеЕсли Объект.Важность = Перечисления.ВариантыВажностиВзаимодействия.Низкая Тогда
		Элементы.ГруппаВажность.Картинка = БиблиотекаКартинок.ВажностьНизкая;
		Элементы.ГруппаВажность.Подсказка = НСтр("ru = 'Низкая важность'");
		Элементы.ВажностьДекорация.Картинка = БиблиотекаКартинок.ВажностьНизкая;
		Элементы.ВажностьДекорация.Подсказка = НСтр("ru = 'Низкая важность'");

	Иначе
		Элементы.ГруппаВажность.Картинка = БиблиотекаКартинок.ВажностьНеЗадана;
		Элементы.ГруппаВажность.Подсказка = НСтр("ru = 'Обычная важность'");
		Элементы.ВажностьДекорация.Картинка = БиблиотекаКартинок.ВажностьНеЗадана;
		Элементы.ВажностьДекорация.Подсказка = НСтр("ru = 'Обычная важность'");
	КонецЕсли;

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

/////////////////////////////////////////////////////////////////////////////////
//  Управление доступностью элементов формы.

&НаКлиенте

Процедура УправлениеДоступностью()

	Элементы.РассмотретьПосле.Доступность = НаКонтроле;

	Если Объект.СтатусПисьма = ПредопределенноеЗначение("Перечисление.СтатусыИсходящегоЭлектронногоПисьма.Исходящее")
		И (НЕ ИнформационнаяБазаФайловая
		ИЛИ (Объект.ДатаКогдаОтправить <> Дата(1,1,1) И Объект.ДатаКогдаОтправить > ОбщегоНазначенияКлиент.ДатаСеанса())
		ИЛИ (Объект.ДатаАктуальностиОтправки <> Дата(1,1,1) И Объект.ДатаАктуальностиОтправки < ОбщегоНазначенияКлиент.ДатаСеанса())) Тогда
		Элементы.Отправить.Видимость = Ложь;
	Иначе
		Элементы.Отправить.Видимость = Истина;
	КонецЕсли;
	Элементы.ФормаЗаписатьИЗакрыть.Видимость = Не Элементы.Отправить.Видимость;

	Элементы.ГруппаДатаОтправкиАктуальность.Доступность = (Объект.СтатусПисьма <> ПредопределенноеЗначение("Перечисление.СтатусыИсходящегоЭлектронногоПисьма.Отправлено"));

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

&НаСервере

Процедура ОпределитьВидимостьДоступностьЭлементовВЗависимостиОтСтатусаПисьма()

	Если Объект.СтатусПисьма <> Перечисления.СтатусыИсходящегоЭлектронногоПисьма.Отправлено Тогда
		УправлениеЭлектроннойПочтой.ПолучитьДоступныеУчетныеЗаписиДляОтправки(
			Элементы.ОтправительПредставление.СписокВыбора,ДоступныеДляОтправкиУчетныеЗаписи);

		Если Объект.УчетнаяЗапись.Пустая()
			И ДоступныеДляОтправкиУчетныеЗаписи.Количество() > 0
			И Объект.Ссылка.Пустая() Тогда

			Объект.УчетнаяЗапись = ДоступныеДляОтправкиУчетныеЗаписи[0].УчетнаяЗапись;

		КонецЕсли;

		ЭлементСписка = Элементы.ОтправительПредставление.СписокВыбора.НайтиПоЗначению(Объект.УчетнаяЗапись);
		Если ЭлементСписка <> Неопределено Тогда
			Объект.ОтправительПредставление = ЭлементСписка.Представление;
		КонецЕсли;

	Иначе

		Элементы.ОтправительПредставление.ТолькоПросмотр             = Истина;
		Элементы.СписокПолучателейВариантОтправки.ТолькоПросмотр     = Истина;
		Элементы.СписокПолучателейПредставление.РедактированиеТекста = Ложь;
		Элементы.СписокПолучателей.ТолькоПросмотр                    = Истина;
		Элементы.ГруппаВажность.Видимость                            = Ложь;
		Элементы.ВажностьДекорация.Видимость = Объект.Важность <> Перечисления.ВариантыВажностиВзаимодействия.Обычная;

	КонецЕсли;

	Если Объект.СтатусПисьма <> Перечисления.СтатусыИсходящегоЭлектронногоПисьма.Черновик Тогда

		Если Вложения.Количество() > 0 Тогда
			Элементы.ДобавитьВложение.Доступность = Ложь;
			Элементы.УдалитьВложение.Доступность  = Ложь;
			Элементы.ДобавитьПисьмо.Доступность   = Ложь;
		Иначе
			Элементы.Вложения.Видимость = Ложь;
		КонецЕсли;

		Если Объект.ТипТекста = Перечисления.ТипыТекстовЭлектронныхПисем.HTML Тогда
			ТекстПисьма = Объект.ТекстHTML;
			ТекстПисьма = Взаимодействия.ОбработатьТекстHTML(Объект.Ссылка);
			Элементы.ТекстПисьма.Вид = ВидПоляФормы.ПолеHTMLДокумента;
			Элементы.ТекстПисьма.ТолькоПросмотр = Ложь;
		Иначе
			ТекстПисьма = Объект.Текст;
			Элементы.ТекстПисьма.Вид = ВидПоляФормы.ПолеТекстовогоДокумента;
			Элементы.ТекстПисьма.ТолькоПросмотр = Истина;
		КонецЕсли;

		Если Объект.СтатусПисьма = Перечисления.СтатусыИсходящегоЭлектронногоПисьма.Исходящее
			И (НЕ ИнформационнаяБазаФайловая
			ИЛИ (Объект.ДатаКогдаОтправить <> Дата(1,1,1) И Объект.ДатаКогдаОтправить > ТекущаяДатаСеанса())
			ИЛИ (Объект.ДатаАктуальностиОтправки <> Дата(1,1,1) И Объект.ДатаАктуальностиОтправки < ТекущаяДатаСеанса())) Тогда

			Элементы.Отправить.Доступность = Ложь;

		КонецЕсли;

	Иначе

		ОпределитьСпособРедактированияПисьма();

	КонецЕсли;

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

#Область РаботаСВложениями

&НаСервере


Процедура Подобрать(Команда)

	Если РольДоступнаДляВнешнихПользователей И РольДоступнаДляПользователей Тогда
		Выбор = Новый СписокЗначений;
		Выбор.Добавить("ВнешнийПользователь", НСтр("ru = 'Внешний пользователь'"));
		Выбор.Добавить("Пользователь", НСтр("ru = 'Пользователь'"));
		ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораТипаПользователя", ЭтотОбъект);
		Выбор.ПоказатьВыборЭлемента(ОписаниеОповещения, НСтр("ru = 'Выберите тип пользователя'"));
	ИначеЕсли РольДоступнаДляПользователей Тогда
		ОткрытьФормуПодбора("Пользователь");
	ИначеЕсли РольДоступнаДляВнешнихПользователей Тогда
		ОткрытьФормуПодбора("ВнешнийПользователь");
	КонецЕсли;

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

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаКлиенте

Процедура ПослеВыбораТипаПользователя(Результат, ДополнительныеПараметры) Экспорт
	Если Результат <> Неопределено Тогда
		ОткрытьФормуПодбора(Результат.Значение);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте

Процедура ОткрытьФормуПодбора(РежимОткрытия)

	ПараметрыФормыВыбора = Новый Структура;
	ПараметрыФормыВыбора.Вставить("ВыборГруппИЭлементов", ИспользованиеГруппИЭлементов.ГруппыИЭлементы);
	ПараметрыФормыВыбора.Вставить("ЗакрыватьПриВыборе", Ложь);
	ПараметрыФормыВыбора.Вставить("ЗакрыватьПриЗакрытииВладельца", Истина);
	ПараметрыФормыВыбора.Вставить("МножественныйВыбор", Истина);
	ПараметрыФормыВыбора.Вставить("РежимВыбора", Истина);
	ПараметрыФормыВыбора.Вставить("ВыборГрупп", Ложь);
	ПараметрыФормыВыбора.Вставить("ВыборГруппПользователей", Ложь);

	Если РежимОткрытия = "ВнешнийПользователь" Тогда
		ПараметрыФормыВыбора.Вставить("Назначение", Назначение.ВыгрузитьЗначения());
		ОткрытьФорму("Справочник.ВнешниеПользователи.ФормаВыбора", ПараметрыФормыВыбора, Элементы.Список);
	Иначе
		ОткрытьФорму("Справочник.Пользователи.ФормаВыбора", ПараметрыФормыВыбора, Элементы.Список);
	КонецЕсли;

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

&НаСервере

Процедура УстановитьУсловноеОформление()

	УсловноеОформление.Элементы.Очистить();

	Элемент = УсловноеОформление.Элементы.Добавить();
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных("Исполнитель");

	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("НаборЗаписей.Недействителен");
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;

	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", Метаданные.ЭлементыСтиля.ТекстЗапрещеннойЯчейкиЦвет.Значение);

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

#КонецОбласти


Процедура ОповеститьПользователейВариантаОтчета(Записи) Экспорт

	Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Обсуждения") Тогда
		Возврат;
	КонецЕсли;

	УведомитьПользователей = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
		Записи.ДополнительныеСвойства, "УведомитьПользователей", Ложь);

	Если Не УведомитьПользователей Тогда
		Возврат;
	КонецЕсли;

	МодульОбсуждения = ОбщегоНазначения.ОбщийМодуль("Обсуждения");

	УстановитьПривилегированныйРежим(Истина);
	Получатели = Новый Массив;

	ЭлементОтбора = Записи.Отбор.Найти("Вариант");
	ПользователиВарианта = ПользователиВариантаОтчета(ЭлементОтбора.Значение);

	Пока ПользователиВарианта.Следующий() Цикл
		Получатели.Добавить(ПользователиВарианта.Ссылка);
	КонецЦикла;

	Если Получатели.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	ВариантОтчета = Записи[0].Вариант;
	Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Настроен отчет %1'"),
		ПолучитьНавигационнуюСсылку(ВариантОтчета));

	Сообщение = МодульОбсуждения.ОписаниеСообщения(Текст);
	Попытка
		МодульОбсуждения.ОтправитьСообщение(Пользователи.ТекущийПользователь(), Получатели,
			Сообщение, ВариантОтчета);
	Исключение

		КодОсновногоЯзыка = ОбщегоНазначения.КодОсновногоЯзыка();
		ПредставлениеВариантаОтчета = Строка(ВариантОтчета);
		ЗаписьЖурналаРегистрации(
			НСтр("ru = 'Варианты отчетов'", КодОсновногоЯзыка),
			УровеньЖурналаРегистрации.Ошибка,,
			ПредставлениеВариантаОтчета,
			ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

	КонецПопытки;

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

Функция ПользователиВариантаОтчета(ВариантОтчета, ВыбранныеПользователи = Неопределено) Экспорт

	Запрос = Новый Запрос(
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
	|	Составы.Пользователь КАК Ссылка,
	|	Пользователи.ИдентификаторПользователяИБ КАК Идентификатор
	|ИЗ
	|	РегистрСведений.НастройкиВариантовОтчетов КАК Настройки
	|	ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СоставыГруппПользователей КАК Составы
	|		ПО Составы.ГруппаПользователей = Настройки.Пользователь
	|		ИЛИ Настройки.Пользователь = НЕОПРЕДЕЛЕНО
	|			И Составы.ГруппаПользователей = ЗНАЧЕНИЕ(Справочник.ГруппыПользователей.ВсеПользователи)
	|	ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Пользователи КАК Пользователи
	|		ПО Пользователи.Ссылка = Составы.Пользователь
	|ГДЕ
	|	Настройки.Вариант = &ВариантОтчета
	|	И Настройки.Подсистема = ЗНАЧЕНИЕ(Справочник.ИдентификаторыОбъектовМетаданных.ПустаяСсылка)
	|	И НЕ ТИПЗНАЧЕНИЯ(Настройки.Пользователь) В (
	|		ТИП(Справочник.ВнешниеПользователи),
	|		ТИП(Справочник.ГруппыВнешнихПользователей))
	|	И Настройки.Видимость
	|	И Составы.Используется
	|	И Пользователи.Ссылка <> &ТекущийПользователь
	|	И (НЕ &ПользователиВыбраны
	|		ИЛИ Пользователи.Ссылка В (&ВыбранныеПользователи))
	|	И НЕ Пользователи.Служебный");

	Запрос.УстановитьПараметр("ВариантОтчета", ВариантОтчета);
	Запрос.УстановитьПараметр("ТекущийПользователь", Пользователи.АвторизованныйПользователь());
	Запрос.УстановитьПараметр("ПользователиВыбраны", ВыбранныеПользователи <> Неопределено);
	Запрос.УстановитьПараметр("ВыбранныеПользователи", ВыбранныеПользователи);

	Возврат Запрос.Выполнить().Выбрать();

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

////////////////////////////////////////////////////////////////////////////////
// Обработчики обновления.

// Регистрирует данные к обновлению в плане обмена ОбновлениеИнформационнойБазы
//  см. Стандарты и методики разработки прикладных решений: Параллельный режим отложенного обновления.
//
// Параметры:
//  Параметры - см. ОбновлениеИнформационнойБазы.ОсновныеПараметрыОтметкиКОбработке
//

Процедура ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию(Параметры) Экспорт

	Запрос = Новый Запрос(
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
	|	Отчеты.Ссылка КАК Вариант,
	|	ЗНАЧЕНИЕ(Справочник.ИдентификаторыОбъектовМетаданных.ПустаяСсылка) КАК Подсистема,
	|	НЕОПРЕДЕЛЕНО КАК Пользователь,
	|	ВЫБОР
	|		КОГДА Отчеты.ВидимостьПоУмолчаниюПереопределена
	|			ИЛИ ЕСТЬNULL(ОтчетыКонфигурации.ВидимостьПоУмолчанию, ОтчетыРасширений.ВидимостьПоУмолчанию) ЕСТЬ NULL
	|		ТОГДА Отчеты.ВидимостьПоУмолчанию
	|		ИНАЧЕ ЕСТЬNULL(ОтчетыКонфигурации.ВидимостьПоУмолчанию, ОтчетыРасширений.ВидимостьПоУмолчанию)
	|	КОНЕЦ КАК Видимость,
	|	ЛОЖЬ КАК БыстрыйДоступ
	|ПОМЕСТИТЬ Настройки
	|ИЗ
	|	Справочник.ВариантыОтчетов КАК Отчеты
	|	ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ВариантыОтчетов.Размещение КАК РазмещениеОтчетов
	|		ПО РазмещениеОтчетов.Ссылка = Отчеты.Ссылка
	|	ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПредопределенныеВариантыОтчетов КАК ОтчетыКонфигурации
	|		ПО ОтчетыКонфигурации.Ссылка = Отчеты.ПредопределенныйВариант
	|	ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПредопределенныеВариантыОтчетов.Размещение КАК РазмещениеОтчетовКонфигурации
	|		ПО РазмещениеОтчетовКонфигурации.Ссылка = Отчеты.ПредопределенныйВариант
	|	ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПредопределенныеВариантыОтчетовРасширений КАК ОтчетыРасширений
	|		ПО ОтчетыРасширений.Ссылка = Отчеты.ПредопределенныйВариант
	|	ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПредопределенныеВариантыОтчетовРасширений.Размещение КАК РазмещениеОтчетовРасширений
	|		ПО РазмещениеОтчетовРасширений.Ссылка = Отчеты.ПредопределенныйВариант
	|ГДЕ
	|	ЕСТЬNULL(РазмещениеОтчетов.Использование, ИСТИНА)
	|	И НЕ ЕСТЬNULL(РазмещениеОтчетов.Подсистема,
	|		ЕСТЬNULL(РазмещениеОтчетовКонфигурации.Подсистема, РазмещениеОтчетовРасширений.Подсистема)) ЕСТЬ NULL
	|;
	|
	|ВЫБРАТЬ
	|	Настройки.Вариант,
	|	Настройки.Подсистема,
	|	Настройки.Пользователь,
	|	Настройки.Видимость,
	|	Настройки.БыстрыйДоступ
	|ИЗ
	|	Настройки КАК Настройки
	|	ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиВариантовОтчетов КАК НастройкиСуществующие
	|		ПО НастройкиСуществующие.Вариант = Настройки.Вариант
	|		И НастройкиСуществующие.Подсистема = Настройки.Подсистема
	|ГДЕ
	|	Настройки.Видимость
	|	И НастройкиСуществующие.Вариант ЕСТЬ NULL");

	Ссылки = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Вариант");

	ОбновлениеИнформационнойБазы.ОтметитьКОбработке(Параметры, Ссылки);

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

// Обрабатывает данные, зарегистрированные в плане обмена ОбновлениеИнформационнойБазы
//  см. Стандарты и методики разработки прикладных решений: Параллельный режим отложенного обновления.
//
// Параметры:
//  Параметры - см. ОбновлениеИнформационнойБазы.ОсновныеПараметрыОтметкиКОбработке
//


Функция НазваниеИУникальныйИдентификаторСеансаРегламентногоЗадания(СтрокаДанныхЖурналаРегистрации,
			СоответствиеНаименованиеИдентификатор, СоответствиеМетаданныеИдентификатор, СоответствиеМетаданныеНазвание)
	Если Не СтрокаДанныхЖурналаРегистрации.Данные = "" Тогда
		УникальныйИдентификаторРегламентногоЗадания = СоответствиеНаименованиеИдентификатор[
														СтрокаДанныхЖурналаРегистрации.Данные];
		НазваниеСеанса = СтрокаДанныхЖурналаРегистрации.Данные;
	Иначе
		УникальныйИдентификаторРегламентногоЗадания = СоответствиеМетаданныеИдентификатор[
			МетаданныеРегламентногоЗадания(СтрокаДанныхЖурналаРегистрации.Метаданные)];
		НазваниеСеанса = СоответствиеМетаданныеНазвание[МетаданныеРегламентногоЗадания(
														СтрокаДанныхЖурналаРегистрации.Метаданные)];
	КонецЕсли;

	Возврат Новый Структура("НазваниеСеанса, УникальныйИдентификаторРегламентногоЗадания",
								НазваниеСеанса, УникальныйИдентификаторРегламентногоЗадания)
КонецФункции

// Параметры:
//  Макет - ТабличныйДокумент
//  ИмяОбласти - Строка
//
// Возвращаемое значение:
//  ТабличныйДокумент:
//    * Параметры - ПараметрыМакетаТабличногоДокумента:
//        ** ДатаНачала - Дата
//        ** ДатаОкончания - Дата
//        ** РежимОтображенияИнтервалов - Строка
//        ** СписокРегламентныхЗаданий - Строка
//        ** РасшифровкаЗадания - Массив из Строка
//                              - Дата
//        ** РасшифровкаИнтервала - Массив из Строка
//

Функция ОписаниеОбластиМакета(Макет, ИмяОбласти)

	Возврат Макет.ПолучитьОбласть(ИмяОбласти);

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

////////////////////////////////////////////////////////////////////////////////
// Контроль журнала регистрации.

// Функция, формирующая отчет по зарегистрированным в журнале регистрации ошибкам.
//
// Параметры:
//   ДанныеЖурналаРегистрации - ТаблицаЗначений - выгруженная таблица из журнала регистраций.
//
// Должны присутствовать следующие колонки: Дата, ИмяПользователя, ПредставлениеПриложения,
//                                          ПредставлениеСобытия, Комментарий, Уровень.
//

Функция СформироватьОтчетКонтрольЖурналаРегистрации(ДатаНачала, ДатаОкончания, СмещениеВремениСервера) Экспорт

	Результат = Новый Структура;
	Отчет = Новый ТабличныйДокумент;
	Макет = ПолучитьМакет("МакетОтчетаПоОшибкамВЖурналеРегистрации");
	ДанныеЖурналаРегистрации = ИнформацияПоОшибкамЖурналаРегистрации(ДатаНачала, ДатаОкончания, СмещениеВремениСервера);
	КоличествоЗаписейЖурналаРегистрации = ДанныеЖурналаРегистрации.Количество();

	ОтчетПустой = (КоличествоЗаписейЖурналаРегистрации = 0); // Проверяем заполнение отчета.

	///////////////////////////////////////////////////////////////////////////////
	// Блок предварительной подготовки данных.
	//

	СверткаПоКомментариям = ДанныеЖурналаРегистрации.Скопировать();
	СверткаПоКомментариям.Колонки.Добавить("ИтогПоКомментарию");
	СверткаПоКомментариям.ЗаполнитьЗначения(1, "ИтогПоКомментарию");
	СверткаПоКомментариям.Свернуть("Уровень, Комментарий, Событие, ПредставлениеСобытия", "ИтогПоКомментарию");

	МассивСтрок_УровеньОшибка = СверткаПоКомментариям.НайтиСтроки(
									Новый Структура("Уровень", УровеньЖурналаРегистрации.Ошибка));

	МассивСтрок_УровеньПредупреждение = СверткаПоКомментариям.НайтиСтроки(
									Новый Структура("Уровень", УровеньЖурналаРегистрации.Предупреждение));

	Свертка_Ошибки         = СверткаПоКомментариям.Скопировать(МассивСтрок_УровеньОшибка);
	Свертка_Ошибки.Сортировать("ИтогПоКомментарию Убыв");
	Свертка_Предупреждения = СверткаПоКомментариям.Скопировать(МассивСтрок_УровеньПредупреждение);
	Свертка_Предупреждения.Сортировать("ИтогПоКомментарию Убыв");

	///////////////////////////////////////////////////////////////////////////////
	// Блок формирования самого отчета.
	//

	Область = Макет.ПолучитьОбласть("ШапкаОтчета");
	Область.Параметры.ПериодВыборкиНачало    = ДатаНачала;
	Область.Параметры.ПериодВыборкиОкончание = ДатаОкончания;
	Область.Параметры.ПредставлениеИнформационнойБазы = ПредставлениеИнформационнойБазы();
	Отчет.Вывести(Область);

	РезультатКомпоновкиТЧ = СформироватьТабличнуюЧасть(Макет, ДанныеЖурналаРегистрации, Свертка_Ошибки);

	Отчет.Вывести(Макет.ПолучитьОбласть("ПустаяСтрока"));
	Область = Макет.ПолучитьОбласть("ЗаголовокБлокаОшибки");
	Область.Параметры.ЧислоОшибок = Строка(РезультатКомпоновкиТЧ.Итог);
	Отчет.Вывести(Область);

	Если РезультатКомпоновкиТЧ.Итог > 0 Тогда
		Отчет.Вывести(РезультатКомпоновкиТЧ.ТабличнаяЧасть);
	КонецЕсли;

	Результат.Вставить("ИтогПоОшибкам", РезультатКомпоновкиТЧ.Итог);
	РезультатКомпоновкиТЧ = СформироватьТабличнуюЧасть(Макет, ДанныеЖурналаРегистрации, Свертка_Предупреждения);

	Отчет.Вывести(Макет.ПолучитьОбласть("ПустаяСтрока"));
	Область = Макет.ПолучитьОбласть("ЗаголовокБлокаПредупреждения");
	Область.Параметры.ЧислоПредупреждений = РезультатКомпоновкиТЧ.Итог;
	Отчет.Вывести(Область);

	Если РезультатКомпоновкиТЧ.Итог > 0 Тогда
		Отчет.Вывести(РезультатКомпоновкиТЧ.ТабличнаяЧасть);
	КонецЕсли;

	Результат.Вставить("ИтогПоПредупреждениям", РезультатКомпоновкиТЧ.Итог);
	Отчет.ОтображатьСетку = Ложь;
	Результат.Вставить("Отчет", Отчет);
	Результат.Вставить("ОтчетПустой", ОтчетПустой);
	Возврат Результат;

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

// Получить представление физического места размещения информационной базы для отображения администратору.
//
// Возвращаемое значение:
//   Строка - представление информационной базы.
//
// Пример:
// - для ИБ в файлом режиме: \\FileServer\1c_ib\
// - для ИБ в серверном режиме: ServerName:1111 / information_base_name.
//

Функция ПредставлениеИнформационнойБазы()

	СтрокаСоединенияСБД = СтрокаСоединенияИнформационнойБазы();

	Если ОбщегоНазначения.ИнформационнаяБазаФайловая(СтрокаСоединенияСБД) Тогда
		Возврат Сред(СтрокаСоединенияСБД, 6, СтрДлина(СтрокаСоединенияСБД) - 6);
	КонецЕсли;

	// Прибавить к имени сервера имя пути информационной базы.
	ПозицияПоиска = СтрНайти(ВРег(СтрокаСоединенияСБД), "SRVR=");
	Если ПозицияПоиска <> 1 Тогда
		Возврат Неопределено;
	КонецЕсли;

	ПозицияТочкиСЗапятой = СтрНайти(СтрокаСоединенияСБД, ";");
	НачальнаяПозицияКопирования = 6 + 1;
	КонечнаяПозицияКопирования = ПозицияТочкиСЗапятой - 2;

	ИмяСервера = Сред(СтрокаСоединенияСБД, НачальнаяПозицияКопирования, КонечнаяПозицияКопирования - НачальнаяПозицияКопирования + 1);

	СтрокаСоединенияСБД = Сред(СтрокаСоединенияСБД, ПозицияТочкиСЗапятой + 1);

	// Позиция имени сервера
	ПозицияПоиска = СтрНайти(ВРег(СтрокаСоединенияСБД), "REF=");
	Если ПозицияПоиска <> 1 Тогда
		Возврат Неопределено;
	КонецЕсли;

	НачальнаяПозицияКопирования = 6;
	ПозицияТочкиСЗапятой = СтрНайти(СтрокаСоединенияСБД, ";");
	КонечнаяПозицияКопирования = ПозицияТочкиСЗапятой - 2;

	ИмяИБНаСервере = Сред(СтрокаСоединенияСБД, НачальнаяПозицияКопирования, КонечнаяПозицияКопирования - НачальнаяПозицияКопирования + 1);
	ПутьКБД = ИмяСервера + "/ " + ИмяИБНаСервере;
	Возврат ПутьКБД;

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

// Функция получает информацию по ошибкам в журнале регистрации по переданному периоду.
//
// Параметры:
//   ДатаНачала    - Дата - начала периода, по которому будет собираться информация.
//   ДатаОкончания - Дата - окончание периода, по которому будет собираться информация.
//
// Возвращаемое значение
//   ТаблицаЗначений - записи из журнала регистрации в соответствии с фильтром:
//                    УровеньЖурналаРегистрации - УровеньЖурналаРегистрации.Ошибка
//                    Начало и Окончание периода - из параметров.
//


Процедура СформироватьОтчет(ТаблицаОтчета,Опрос,ВидОтчета) Экспорт

	ТаблицаОтчета.Очистить();

	Если ВидОтчета ="АнализОтветов" Тогда

		СформироватьОтчетАнализОтветов(ТаблицаОтчета,Опрос);

	ИначеЕсли ВидОтчета = "АнализОтветивших" Тогда

		СформироватьОтчетАнализОтветивших(ТаблицаОтчета,Опрос);

	Иначе

		Возврат;

	КонецЕсли;

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

#Область АнализОтветов

// Параметры:
//  ТаблицаОтчета - ТабличныйДокумент
//  Опрос - ДокументСсылка.НазначениеОпросов
//

Процедура СформироватьОтчетАнализОтветов(ТаблицаОтчета, Опрос)

	РеквизитыОпроса = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Опрос, "ШаблонАнкеты,ДатаНачала,ДатаОкончания,Представление");
	ШаблонАнкеты = РеквизитыОпроса.ШаблонАнкеты;
	ПредставленияВопросов = Анкетирование.ПредставленияЭлементарныхВопросовТабличногоВопроса(ШаблонАнкеты);

	РезультатЗапроса = ВыполнитьЗапросПоВопросамШаблонаАнкеты(Опрос,ШаблонАнкеты);
	Если РезультатЗапроса.Пустой() Тогда
		Возврат;
	КонецЕсли;

	Макет = ПолучитьМакет("МакетОтветы");

	Область = Макет.ПолучитьОбласть("Заголовок"); // ТабличныйДокумент
	Область.Параметры.Заголовок = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ШаблонАнкеты, "Заголовок");
	Область.Параметры.Опрос     = ПредставлениеОпросаДляЗаголовка(РеквизитыОпроса);
	ТаблицаОтчета.Вывести(Область, 1);

	Область = Макет.ПолучитьОбласть("ПустаяСтрока");
	ТаблицаОтчета.Вывести(Область, 1);
	ТаблицаОтчета.НачатьГруппуСтрок("Аннотация");

	Область = Макет.ПолучитьОбласть("Аннотация");
	ТаблицаОтчета.Вывести(Область, 2);
	ТаблицаОтчета.ЗакончитьГруппуСтрок();

	Область = Макет.ПолучитьОбласть("ПустаяСтрока");
	ТаблицаОтчета.Вывести(Область, 1);

	ДеревоАнкеты = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
	Если ДеревоАнкеты.Строки.Количество() > 0 Тогда
		ВывестиВТабличныйДокумент(ДеревоАнкеты.Строки,ТаблицаОтчета,Макет,1,Новый Массив, ПредставленияВопросов);
	КонецЕсли;

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

// Вызывается рекурсивно, формирует полный код, и вызывает процедуры вывода вопросов и разделов .
//
// Параметры:
//  СтрокиДерева    - КоллекцияСтрокДереваЗначений - строки дерева, для которых выполняется действие.
//  ТаблицаОтчета   - ТабличныйДокумент -  в него осуществляется вывод данных.
//  Макет           - ТабличныйДокумент - макет, используемый для вывода данных.
//  УровеньРекурсии - Число             - текущий уровень рекурсии.
//  МассивПолныйКод - Массив            - используется для формирования полного когда обрабатываемой строки.
//

Процедура ВывестиВТабличныйДокумент(СтрокиДерева,ТаблицаОтчета,Макет,УровеньРекурсии,МассивПолныйКод, ПредставленияВопросов)

	Если МассивПолныйКод.Количество() < УровеньРекурсии Тогда
		МассивПолныйКод.Добавить(0);
	КонецЕсли;

	Для каждого СтрокаДерева Из СтрокиДерева Цикл

		МассивПолныйКод[УровеньРекурсии-1] = МассивПолныйКод[УровеньРекурсии-1] + 1;
		Для инд = УровеньРекурсии По МассивПолныйКод.Количество()-1 Цикл
			МассивПолныйКод[инд] = 0;
		КонецЦикла;

		ПолныйКод = СтрСоединить(МассивПолныйКод,".");
		ПолныйКод = АнкетированиеКлиентСервер.УдалитьПоследниеСимволыИзСтроки(ПолныйКод,"0.",".");

		Если СтрокаДерева.ЭтоРаздел Тогда
			ВывестиРаздел(ТаблицаОтчета,СтрокаДерева,Макет,ПолныйКод);
			Если СтрокаДерева.Строки.Количество() > 0 Тогда
				ВывестиВТабличныйДокумент(СтрокаДерева.Строки,ТаблицаОтчета,Макет,УровеньРекурсии + 1,МассивПолныйКод,ПредставленияВопросов);
			КонецЕсли
		Иначе
			ВывестиВопрос(ТаблицаОтчета,СтрокаДерева,Макет,ПолныйКод, ПредставленияВопросов);
		КонецЕсли;
		ТаблицаОтчета.ЗакончитьГруппуСтрок();

	КонецЦикла;

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

// Параметры:
//  ТаблицаОтчета - ТабличныйДокумент - в него осуществляется вывод информации.
//  СтрокаДерева  - СтрокаДереваЗначений - текущая строка с данными:
//   * Наименование - Строка
//  Макет         - ТабличныйДокумент - макет, используемый для вывода информации.
//  ПолныйКод     - Строка - полный код строки, выводимой в отчет.
//

Процедура ВывестиРаздел(ТаблицаОтчета,СтрокаДерева,Макет,ПолныйКод)

	Область = Макет.ПолучитьОбласть("Раздел");
	Область.Параметры.ИмяРаздела = ПолныйКод + " " + СтрокаДерева.Наименование;
	ТаблицаОтчета.Вывести(Область);
	ТаблицаОтчета.НачатьГруппуСтрок("ПолныйКод_" + СтрокаДерева.Наименование);

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

// Параметры:
//  ТаблицаОтчета - ТабличныйДокумент - в него осуществляется вывод информации.
//  СтрокаДерева  - СтрокаДереваЗначений - текущая строка с данными:
//   * Наименование - Строка
//  Макет         - ТабличныйДокумент - макет, используемый для вывода информации.
//  Полный код    - Строка - полный код строки, выводимой в отчет.
//

Процедура ВывестиВопрос(ТаблицаОтчета,СтрокаДерева,Макет,ПолныйКод, ПредставленияВопросов)

	Область = Макет.ПолучитьОбласть("Вопрос");
	Область.Параметры.ФормулировкаВопроса = ПолныйКод + " " + СтрокаДерева.Наименование;
	ТаблицаОтчета.Вывести(Область);
	ТаблицаОтчета.НачатьГруппуСтрок("ПолныйКод_" + СтрокаДерева.Наименование);

	Если СтрокаДерева.Строки.Количество() > 0 Тогда

		Если СтрокаДерева.ТипВопроса = Перечисления.ТипыВопросовШаблонаАнкеты.Табличный Тогда

			ВывестиОтветТабличныйВопрос(ТаблицаОтчета,СтрокаДерева,Макет,ПолныйКод,ПредставленияВопросов);

		Иначе

			ВывестиОтветПростойВопрос(ТаблицаОтчета,СтрокаДерева,Макет,ПолныйКод);

		КонецЕсли;

	КонецЕсли;

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

// Параметры:
//  ТаблицаОтчета         - ТабличныйДокумент - в него осуществляется вывод информации.
//  СтрокаДерева          - СтрокаДереваЗначений - текущая строка с данными.
//  Макет                 - ТабличныйДокумент - макет, используемый для вывода информации.
//  ПолныйКод             - Строка - полный код строки, выводимой в отчет.
//  ПредставленияВопросов - Соответствие - содержит информацию о формулировке и признаке "Агрегировать в отчетах".
//

Процедура ВывестиОтветТабличныйВопрос(ТаблицаОтчета, СтрокаДерева, Макет, ПолныйКод, ПредставленияВопросов)

	Если СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.Составной Тогда

		ВывестиОтветСоставнойТабличныйВопрос(ТаблицаОтчета,СтрокаДерева.Строки[0],Макет,ПолныйКод, ПредставленияВопросов);

	ИначеЕсли СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.ПредопределенныеОтветыВКолонках Тогда

		ВывестиОтветПредопределенныеОтветыВКолонкахТабличныйВопрос(ТаблицаОтчета,СтрокаДерева,Макет,ПолныйКод,ПредставленияВопросов);

	ИначеЕсли СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.ПредопределенныеОтветыВСтроках Тогда

		ВывестиОтветПредопределенныеОтветыВСтрокахТабличныйВопрос(ТаблицаОтчета,СтрокаДерева,Макет,ПолныйКод,ПредставленияВопросов);

	ИначеЕсли СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.ПредопределенныеОтветыВСтрокахИКолонках Тогда

		ВывестиОтветПредопределенныеОтветыВСтрокахИКолонкахТабличныйВопрос(ТаблицаОтчета,СтрокаДерева,Макет,ПолныйКод, ПредставленияВопросов);

	КонецЕсли;

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

// Выводит в таблицу отчета ответы табличного вопроса с предопределенными ответами в колонках.
//
// Параметры:
//  ТаблицаОтчета         - ТабличныйДокумент - в него осуществляется вывод информации.
//  СтрокаДерева          - СтрокаДереваЗначений - текущая строка с данными.
//  Макет                 - ТабличныйДокумент - макет, используемый для вывода информации.
//  ПолныйКод             - Строка - полный код строки, выводимой в отчет.
//  ПредставленияВопросов - Соответствие - содержит информацию о формулировке и признаке "Агрегировать в отчетах".
//


Функция ВидыДоступаСПредставлением(ТипыЗначенийВидовДоступа, ТолькоИспользуемые)

	ВидыДоступа = ТипыЗначенийВидовДоступа.Скопировать(, "ВидДоступа");

	ВидыДоступа.Свернуть("ВидДоступа");
	ВидыДоступа.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(150)));
	ИспользуемыеВидыДоступа = УправлениеДоступомСлужебный.ИспользуемыеВидыДоступа();

	Индекс = ВидыДоступа.Количество()-1;
	Пока Индекс >= 0 Цикл
		Строка = ВидыДоступа[Индекс];
		СвойстваВидаДоступа = УправлениеДоступомСлужебный.СвойстваВидаДоступа(Строка.ВидДоступа);

		Если СвойстваВидаДоступа = Неопределено Тогда
			МетаданныеВладельцаНастроекПрав = Метаданные.НайтиПоТипу(ТипЗнч(Строка.ВидДоступа));
			Если МетаданныеВладельцаНастроекПрав = Неопределено Тогда
				Строка.Представление = ПредставлениеНеизвестногоВидаДоступа();
			Иначе
				Строка.Представление = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Настройки прав на %1'"),
					МетаданныеВладельцаНастроекПрав.Представление());
			КонецЕсли;

		ИначеЕсли Не ТолькоИспользуемые
		      Или ИспользуемыеВидыДоступа.Получить(СвойстваВидаДоступа.Ссылка) <> Неопределено Тогда

			Строка.Представление = УправлениеДоступомСлужебный.ПредставлениеВидаДоступа(СвойстваВидаДоступа);
		Иначе
			ВидыДоступа.Удалить(Строка);
		КонецЕсли;

		Индекс = Индекс - 1;
	КонецЦикла;

	Возврат ВидыДоступа;

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

// Для функций ВидыОграниченийПрав, ВидыДоступаСПредставлением.

Функция ПредставлениеНеизвестногоВидаДоступа()

	Возврат НСтр("ru = 'Неизвестный вид доступа'");

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

// Для функции ВидыОграниченийПрав.

Функция ТаблицыСОтключеннымОграничением(ДляВнешнихПользователей, Заполнять)

	ТипыИдентификаторов = Новый Массив;
	ТипыИдентификаторов.Добавить(Тип("СправочникСсылка.ИдентификаторыОбъектовМетаданных"));
	ТипыИдентификаторов.Добавить(Тип("СправочникСсылка.ИдентификаторыОбъектовРасширений"));

	Результат = Новый ТаблицаЗначений;
	Результат.Колонки.Добавить("ДляВнешнихПользователей", Новый ОписаниеТипов("Булево"));
	Результат.Колонки.Добавить("ПолноеИмя",
		Метаданные.Справочники.ИдентификаторыОбъектовМетаданных.Реквизиты.ПолноеИмя.Тип);
	Результат.Колонки.Добавить("Таблица",    Новый ОписаниеТипов(ТипыИдентификаторов));
	Результат.Колонки.Добавить("ВидДоступа", УправлениеДоступомСлужебныйПовтИсп.ОписаниеТиповЗначенийДоступаИВладельцевНастроекПрав());
	Результат.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(150)));

	Если Не Заполнять Тогда
		Возврат Результат;
	КонецЕсли;

	ДействующиеПараметры = УправлениеДоступомСлужебный.ДействующиеПараметрыОграниченияДоступа(
		Неопределено, Неопределено, Ложь);

	Если ДляВнешнихПользователей <> Истина Тогда
		ДобавитьТаблицыСОтключеннымОграничением(Результат, ДействующиеПараметры, Ложь);
	КонецЕсли;
	Если ДляВнешнихПользователей <> Ложь Тогда
		ДобавитьТаблицыСОтключеннымОграничением(Результат, ДействующиеПараметры, Истина);
	КонецЕсли;
	ПолныеИмена = Результат.ВыгрузитьКолонку("ПолноеИмя");
	ИдентификаторыИмен = ОбщегоНазначения.ИдентификаторыОбъектовМетаданных(ПолныеИмена, Ложь);
	Для Каждого Строка Из Результат Цикл
		Строка.Таблица = ИдентификаторыИмен.Получить(Строка.ПолноеИмя);
	КонецЦикла;

	Возврат Результат;

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

// Для функции ТаблицыСОтключеннымОграничением.

Процедура ДобавитьТаблицыСОтключеннымОграничением(ТаблицыСОтключеннымОграничением,
			ДействующиеПараметры, ДляВнешнихПользователей)

	Если ДляВнешнихПользователей Тогда
		ДополнительныйКонтекст = ДействующиеПараметры.ДополнительныйКонтекст.ДляВнешнихПользователей;
	Иначе
		ДополнительныйКонтекст = ДействующиеПараметры.ДополнительныйКонтекст.ДляПользователей;
	КонецЕсли;

	СпискиСОтключеннымОграничением = ДополнительныйКонтекст.СпискиСОтключеннымОграничением;
	СвойстваОграниченияСписков     = ДополнительныйКонтекст.СвойстваОграниченияСписков;

	Для Каждого КлючИЗначение Из СвойстваОграниченияСписков Цикл
		ПолноеИмя = КлючИЗначение.Ключ;
		Если Не КлючИЗначение.Значение.ДоступЗапрещен
		   И СпискиСОтключеннымОграничением.Получить(ПолноеИмя) = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		НоваяСтрока = ТаблицыСОтключеннымОграничением.Добавить();
		НоваяСтрока.ДляВнешнихПользователей = ДляВнешнихПользователей;
		НоваяСтрока.ПолноеИмя = ПолноеИмя;
		Если КлючИЗначение.Значение.ДоступЗапрещен Тогда
			НоваяСтрока.ВидДоступа    = Перечисления.ДополнительныеЗначенияДоступа.ДоступЗапрещен;
			НоваяСтрока.Представление = "<" + НСтр("ru = 'Доступ запрещен'") + ">";
		Иначе
			НоваяСтрока.ВидДоступа    = Перечисления.ДополнительныеЗначенияДоступа.ДоступРазрешен;
			НоваяСтрока.Представление = "<" + НСтр("ru = 'Ограничение отключено'") + ">";
		КонецЕсли;
	КонецЦикла;

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

#КонецОбласти

#КонецЕсли


Процедура УстановитьФиксированныеПараметры(Отчет, ФиксированныеПараметры, Настройки, ПользовательскиеНастройки) Экспорт
	ПараметрыДанных = Настройки.ПараметрыДанных;

	ДоступныеПараметры = ПараметрыДанных.ДоступныеПараметры;
	Если ДоступныеПараметры = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Для Каждого Параметр Из ФиксированныеПараметры Цикл
		Если ДоступныеПараметры.Элементы.Найти(Параметр.Ключ) = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		ЭлементНастройки = ПараметрыДанных.Элементы.Найти(Параметр.Ключ);
		Если ЭлементНастройки = Неопределено Тогда
			ЭлементНастройки = ПараметрыДанных.Элементы.Добавить();
			ЭлементНастройки.Параметр = Новый ПараметрКомпоновкиДанных(Параметр.Ключ);
			ЭлементНастройки.Значение = Параметр.Значение;
			ЭлементНастройки.Использование = Истина;
		Иначе
			ПараметрыДанных.УстановитьЗначениеПараметра(Параметр.Ключ, Параметр.Значение);
		КонецЕсли;

		ЭлементПользовательскойНастройки = Неопределено;
		Если ПользовательскиеНастройки <> Неопределено Тогда
			ЭлементПользовательскойНастройки = ПользовательскиеНастройки.Элементы.Найти(
				ЭлементНастройки.ИдентификаторПользовательскойНастройки);
		КонецЕсли;

		Если ЭлементПользовательскойНастройки <> Неопределено Тогда
			ЗаполнитьЗначенияСвойств(ЭлементПользовательскойНастройки, ЭлементНастройки, "Использование, Значение");
		КонецЕсли;
	КонецЦикла;

	Если ПользовательскиеНастройки <> Неопределено Тогда
		ПользовательскиеНастройки.ДополнительныеСвойства.Вставить("ОтчетИнициализирован", Истина);
	КонецЕсли;
КонецПроцедуры

Функция ТекстЗапросаПоМетаданным(ПараметрыОтчета)
	МетаданныеИсточника = Метаданные[ПараметрыОтчета.ТипОбъектаМетаданных][ПараметрыОтчета.ИмяОбъектаМетаданных];

	ИмяИсточника = МетаданныеИсточника.ПолноеИмя();
	Если ЗначениеЗаполнено(ПараметрыОтчета.ИмяТаблицы) Тогда
		ИмяИсточника = ИмяИсточника + "." + ПараметрыОтчета.ИмяТаблицы;
	КонецЕсли;

	ОтборИсточника = "";
	Если ПараметрыОтчета.ИмяТаблицы = "ОстаткиИОбороты" Тогда
		ОтборИсточника = "({&НачалоПериода}, {&КонецПериода}, Авто, Движения)";
	ИначеЕсли ПараметрыОтчета.ИмяТаблицы = "Обороты" Тогда
		ОтборИсточника = "({&НачалоПериода}, {&КонецПериода}, Авто)";
	ИначеЕсли ПараметрыОтчета.ИмяТаблицы = "Остатки"
		Или ПараметрыОтчета.ИмяТаблицы = "СрезПоследних" Тогда
		ОтборИсточника = "({&КонецПериода},)";
	ИначеЕсли ПараметрыОтчета.ИмяТаблицы = "СрезПервых" Тогда
		ОтборИсточника = "({&НачалоПериода},)";
	ИначеЕсли ПараметрыОтчета.ТипОбъектаМетаданных = "Документы"
		Или ПараметрыОтчета.ТипОбъектаМетаданных = "Задачи"
		Или ПараметрыОтчета.ТипОбъектаМетаданных = "БизнесПроцессы" Тогда

		Если ЗначениеЗаполнено(ПараметрыОтчета.ИмяТаблицы)
			И ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(МетаданныеИсточника, "ТабличныеЧасти")
			И ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(МетаданныеИсточника.ТабличныеЧасти, ПараметрыОтчета.ИмяТаблицы) Тогда
			ОтборИсточника = "
				|{ГДЕ
				|	(Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода)}";
		Иначе
			ОтборИсточника = "
				|{ГДЕ
				|	(Дата МЕЖДУ &НачалоПериода И &КонецПериода)}";
		КонецЕсли;
	ИначеЕсли ПараметрыОтчета.ТипОбъектаМетаданных = "РегистрыСведений"
		И МетаданныеИсточника.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
		ОтборИсточника = "
			|{ГДЕ
			|	(Период МЕЖДУ &НачалоПериода И &КонецПериода)}";
	ИначеЕсли ПараметрыОтчета.ТипОбъектаМетаданных = "РегистрыНакопления"
		Или ПараметрыОтчета.ТипОбъектаМетаданных = "РегистрыБухгалтерии" Тогда
		ОтборИсточника = "
			|{ГДЕ
			|	(Период МЕЖДУ &НачалоПериода И &КонецПериода)}";
	ИначеЕсли ПараметрыОтчета.ТипОбъектаМетаданных = "РегистрыРасчета" Тогда
		ОтборИсточника = "
			|{ГДЕ
			|	ПериодРегистрации МЕЖДУ &НачалоПериода И &КонецПериода}";
	КонецЕсли;

	ТекстЗапроса =
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ
	|	*
	|ИЗ
	|	&ИмяИсточника КАК Таблица";

	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "КАК Таблица", "");
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ИмяИсточника", ИмяИсточника);

	Если ЗначениеЗаполнено(ОтборИсточника) Тогда
		ТекстЗапроса = ТекстЗапроса + ОтборИсточника;
	КонецЕсли;

	Возврат ТекстЗапроса;
КонецФункции

Функция ДоступныеТипыОбъектовМетаданных()
	ДоступныеЗначения = Новый СписокЗначений;

	Если ЕстьОбъектыТипаМетаданных(Метаданные.Справочники) Тогда
		ДоступныеЗначения.Добавить("Справочники", НСтр("ru = 'Справочник'"), , БиблиотекаКартинок.Справочник);
	КонецЕсли;

	Если ЕстьОбъектыТипаМетаданных(Метаданные.Документы) Тогда
		ДоступныеЗначения.Добавить("Документы", НСтр("ru = 'Документ'"), , БиблиотекаКартинок.Документ);
	КонецЕсли;

	Если ЕстьОбъектыТипаМетаданных(Метаданные.РегистрыСведений) Тогда
		ДоступныеЗначения.Добавить("РегистрыСведений", НСтр("ru = 'Регистр сведений'"), , БиблиотекаКартинок.РегистрСведений);
	КонецЕсли;

	Если ЕстьОбъектыТипаМетаданных(Метаданные.РегистрыНакопления) Тогда
		ДоступныеЗначения.Добавить("РегистрыНакопления", НСтр("ru = 'Регистр накопления'"), , БиблиотекаКартинок.РегистрНакопления);
	КонецЕсли;

	Если ЕстьОбъектыТипаМетаданных(Метаданные.РегистрыБухгалтерии) Тогда
		ДоступныеЗначения.Добавить("РегистрыБухгалтерии", НСтр("ru = 'Регистр бухгалтерии'"), , БиблиотекаКартинок.РегистрБухгалтерии);
	КонецЕсли;

	Если ЕстьОбъектыТипаМетаданных(Метаданные.РегистрыРасчета) Тогда
		ДоступныеЗначения.Добавить("РегистрыРасчета", НСтр("ru = 'Регистр расчета'"), , БиблиотекаКартинок.РегистрРасчета);
	КонецЕсли;

	Если ЕстьОбъектыТипаМетаданных(Метаданные.ПланыВидовРасчета) Тогда
		ДоступныеЗначения.Добавить("ПланыВидовРасчета", НСтр("ru = 'Планы видов расчета'"), , БиблиотекаКартинок.ПланВидовРасчета);
	КонецЕсли;

	Если ЕстьОбъектыТипаМетаданных(Метаданные.Задачи) Тогда
		ДоступныеЗначения.Добавить("Задачи", НСтр("ru = 'Задачи'"), , БиблиотекаКартинок.Задача);
	КонецЕсли;

	Если ЕстьОбъектыТипаМетаданных(Метаданные.БизнесПроцессы) Тогда
		ДоступныеЗначения.Добавить("БизнесПроцессы", НСтр("ru = 'Бизнес-процессы'"), , БиблиотекаКартинок.БизнесПроцесс);
	КонецЕсли;

	Возврат ДоступныеЗначения;
КонецФункции

Функция ДоступныеОбъектыМетаданных(ТипОбъектаМетаданных)
	ДоступныеЗначения = Новый СписокЗначений;

	Если Не ЗначениеЗаполнено(ТипОбъектаМетаданных) Тогда
		Возврат ДоступныеЗначения;
	КонецЕсли;

	УдаляемыеЗначения = Новый СписокЗначений;
	Для Каждого Объект Из Метаданные[ТипОбъектаМетаданных] Цикл
		Если Не ОбщегоНазначения.ОбъектМетаданныхДоступенПоФункциональнымОпциям(Объект)
			Или Не ПравоДоступа("Чтение", Объект) Тогда
			Продолжить;
		КонецЕсли;

		Если СтрНачинаетсяС(ВРег(Объект.Имя), "УДАЛИТЬ") Тогда
			УдаляемыеЗначения.Добавить(Объект.Имя, Объект.Синоним);
		Иначе
			ДоступныеЗначения.Добавить(Объект.Имя, Объект.Синоним);
		КонецЕсли;
	КонецЦикла;
	ДоступныеЗначения.СортироватьПоПредставлению(НаправлениеСортировки.Возр);
	УдаляемыеЗначения.СортироватьПоПредставлению(НаправлениеСортировки.Возр);

	Для Каждого УдаляемыйОбъект Из УдаляемыеЗначения Цикл
		ДоступныеЗначения.Добавить(УдаляемыйОбъект.Значение, УдаляемыйОбъект.Представление);
	КонецЦикла;

	Возврат ДоступныеЗначения;
КонецФункции


Процедура ПрименитьФильтр(Отказ)

	Фильтр = Фильтр(КомпоновщикНастроек, СвойстваЗаголовка);

	Если ТипЗнч(Фильтр) <> Тип("ЭлементОтбораКомпоновкиДанных") Тогда

		Фильтры = ВариантыОтчетовСлужебныйКлиентСервер.ФильтрыРазделаОтчета(
			КомпоновщикНастроек.Настройки, СвойстваЗаголовка);

		Фильтр = Фильтры.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
		Фильтр.ЛевоеЗначение = СвойстваЗаголовка.Поле;

	КонецЕсли;

	Фильтр.Использование = Истина;

	Если Использование Тогда

		Фильтр.ВидСравнения = ВидСравнения;

		Если ЗначениеЗаполнено(ПравоеЗначение) Тогда
			Фильтр.ПравоеЗначение = ПравоеЗначение;
		Иначе
			Фильтр.ПравоеЗначение = Значения.ТипЗначения.ПривестиЗначение(ПравоеЗначение);
		КонецЕсли;

		ОтчетыКлиент.КэшироватьЗначениеОтбора(КомпоновщикНастроек, Фильтр, Значения);
		Возврат;

	КонецЕсли;

	СписокПомеченных = Новый СписокЗначений;
	СписокНепомеченных = Новый СписокЗначений;

	Для Каждого Элемент Из Значения Цикл

		Если Элемент.Пометка Тогда
			ЗаполнитьЗначенияСвойств(СписокПомеченных.Добавить(), Элемент);
		Иначе
			ЗаполнитьЗначенияСвойств(СписокНепомеченных.Добавить(), Элемент);
		КонецЕсли;

	КонецЦикла;

	Если СписокПомеченных.Количество() = 1 Тогда

		Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
		Фильтр.ПравоеЗначение = СписокПомеченных[0].Значение;

	Иначе

		Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
		Фильтр.ПравоеЗначение = СписокПомеченных;

	КонецЕсли;

	Если ТипЗнч(Фильтр) <> Тип("ЭлементОтбораКомпоновкиДанных") Тогда
		Возврат;
	КонецЕсли;

	УточнитьУсловиеФильтра(Фильтр, Отказ);
	ОтчетыКлиент.КэшироватьЗначениеОтбора(КомпоновщикНастроек, Фильтр, Значения);

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

&НаКлиенте

Процедура УточнитьУсловиеФильтра(Фильтр, Отказ)

	ИспользуютсяГруппы = Ложь;
	ИспользуютсяЭлементы = Ложь;

	ЗначенияФильтра = ОтчетыКлиентСервер.ЗначенияСписком(Фильтр.ПравоеЗначение, Истина);

	Если ЗначенияФильтра.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	ПроверитьИспользованиеГруппИЭлементов(ЗначенияФильтра, ИспользуютсяГруппы, ИспользуютсяЭлементы);

	Если Не ИспользуютсяГруппы
		И Не ИспользуютсяЭлементы Тогда

		Возврат;
	КонецЕсли;

	Если Не ИспользуютсяГруппы
		И ИспользуютсяЭлементы Тогда

		Возврат;
	КонецЕсли;

	Если ИспользуютсяГруппы
		И ИспользуютсяЭлементы Тогда

		Отказ = Истина;

		ТекстПредупреждения = НСтр("ru = 'В списке выбраны группы и элементы.
			|Необходимо выбрать только группы или только элементы.'");

		ПоказатьПредупреждение(, ТекстПредупреждения);
		Возврат;

	КонецЕсли;

	Если Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно Тогда

		Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВИерархии;

	ИначеЕсли Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке Тогда

		Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСпискеПоИерархии;

	Иначе
		Фильтр.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСпискеПоИерархии;
	КонецЕсли;

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

&НаКлиенте

Процедура  ПроверитьИспользованиеГруппИЭлементов(ЗначенияФильтра, ИспользуютсяГруппы, ИспользуютсяЭлементы)

	Если ИндексыГруппИЭлементов.Группы.Количество() = 0
		И ИндексыГруппИЭлементов.Элементы.Количество() = 0 Тогда

		Возврат;
	КонецЕсли;

	ТипГруппировкиПоля = ТипГруппировкиПоля();
	ВидыИерархииЗначений = НастройкиОтчета.ВидыИерархииЗначений;

	Для Каждого Элемент Из ЗначенияФильтра Цикл

		Если ИндексыГруппИЭлементов.Группы[Элемент.Значение] = Истина
			Или (ИндексыГруппИЭлементов.Элементы[Элемент.Значение] = Истина
				И ТипГруппировкиПоля <> ТипГруппировкиКомпоновкиДанных.Элементы
				И ВидыИерархииЗначений[ТипЗнч(Элемент.Значение)] = ВидИерархииИерархияЭлементов()) Тогда

			ИспользуютсяГруппы = Истина;

		ИначеЕсли ИндексыГруппИЭлементов.Элементы[Элемент.Значение] = Истина Тогда

			ИспользуютсяЭлементы = Истина;

		КонецЕсли;

	КонецЦикла;

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

&НаКлиенте

Функция ТипГруппировкиПоля()

	ТипГруппировкиПоля = ТипГруппировкиКомпоновкиДанных.Элементы;
	ТекущаяГруппировка = КомпоновщикНастроек.Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);

	Если ТипЗнч(ТекущаяГруппировка) <> Тип("ГруппировкаКомпоновкиДанных")
		И ТипЗнч(ТекущаяГруппировка) <> Тип("ГруппировкаТаблицыКомпоновкиДанных") Тогда

		Возврат ТипГруппировкиПоля;
	КонецЕсли;

	ПолеГруппировки = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(ТекущаяГруппировка.ПоляГруппировки, СвойстваЗаголовка.Поле);

	Если ПолеГруппировки = Неопределено Тогда
		Возврат ТипГруппировкиПоля;
	КонецЕсли;

	Возврат ПолеГруппировки.ТипГруппировки;

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

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

Функция Фильтр(КомпоновщикНастроек, СвойстваЗаголовка, Фильтры = Неопределено)

	Если Фильтры = Неопределено Тогда
		Фильтры = ВариантыОтчетовСлужебныйКлиентСервер.ФильтрыРазделаОтчета(КомпоновщикНастроек.Настройки, СвойстваЗаголовка);
	КонецЕсли;

	Возврат ВариантыОтчетовСлужебныйКлиентСервер.ФильтрРазделаОтчета(Фильтры, СвойстваЗаголовка.Поле);

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

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

Функция ОписаниеФильтра(КомпоновщикНастроек, СвойстваЗаголовка)

	ОписаниеФильтра = Неопределено;

	Если СвойстваЗаголовка.Поле <> Неопределено Тогда
		ОписаниеФильтра = КомпоновщикНастроек.Настройки.ДоступныеПоляОтбора.НайтиПоле(СвойстваЗаголовка.Поле);
	КонецЕсли;

	Возврат ОписаниеФильтра;

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

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

Процедура УточнитьПравоеЗначение(ПравоеЗначение, ДоступныеЗначения)

	Если ТипЗнч(ПравоеЗначение) <> Тип("СписокЗначений") Тогда
		Возврат;
	КонецЕсли;

	Для Каждого Элемент Из ПравоеЗначение Цикл

		ДоступноеЗначение = ДоступныеЗначения.НайтиПоЗначению(Элемент.Значение);

		Если ДоступноеЗначение <> Неопределено Тогда
			ЗаполнитьЗначенияСвойств(Элемент, ДоступноеЗначение);
		КонецЕсли;

	КонецЦикла;

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

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

Процедура ОпределитьДоступностьПоляПравогоЗначения(Поле, ВидСравнения)

	Поле.Доступность = ВидСравнения <> ВидСравненияКомпоновкиДанных.Заполнено
		И ВидСравнения <> ВидСравненияКомпоновкиДанных.НеЗаполнено;

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

&НаСервере

Процедура ПоказатьСтатистикуЗаполненияЗначений()

	Если ВыведеныВсеЗначенияРазделаОтчета Тогда

		Элементы.ОпцииЗаполненияФильтраПоЗначению.Видимость = Не ВыведеныВсеЗначенияРазделаОтчета;
		Возврат;

	КонецЕсли;

	Элементы.СтатистикаФильтраПоЗначению.Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Выведено %1 первых значений.'"), Значения.Количество());

	Элементы.ВывестиВсеЗначенияРазделаОтчета.РасширеннаяПодсказка.Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Выведено %1 уникальных значений из первых %2 строк отчета. Всего строк в разделе отчета - %3.'"),
		Значения.Количество(),
		КоличествоПервыхЧитаемыхСтрок,
		КоличествоСтрокВРазделеОтчета);

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

#КонецОбласти


Функция ПолучитьПланыОбменаКонфигурации()

	Результат = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.1c.ru/SaaS/ExchangeAdministration/Common", "ExchangeFeatures"));
	ТипExchangeFeature = ФабрикаXDTO.Тип("http://www.1c.ru/SaaS/ExchangeAdministration/Common", "ExchangeFeature");

	Для Каждого ИмяПланаОбмена Из ОбменДаннымиВМоделиСервисаПовтИсп.ПланыОбменаСинхронизацииДанных() Цикл

		ExchangeFeature = ФабрикаXDTO.Создать(ТипExchangeFeature);
		ExchangeFeature.ExchangePlan = ИмяПланаОбмена;

		ExchangeFeature.ExchangeRole = СокрЛП(ОбменДаннымиСервер.ЗначениеНастройкиПланаОбмена(ИмяПланаОбмена, "ИмяКонфигурацииИсточника"));

		Если ПустаяСтрока(ExchangeFeature.ExchangeRole) Тогда
			ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Не задано значение свойства ИмяКонфигурацииИсточника в процедуре ПриПолученииНастроек()
				|модуля менеджера плана обмена %1.'"),
				ИмяПланаОбмена);
		КонецЕсли;

		Результат.Feature.Добавить(ExchangeFeature);

	КонецЦикла;

	Возврат Результат;

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

// Соответствует операции PrepareExchangeExecution

Функция ЗапланироватьВыполнениеОбменаДанными(ОбластиДляОбменаДаннымиXDTO)

	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса") Тогда
		Возврат "";
	КонецЕсли;

	МодульОчередьЗаданий = ОбщегоНазначения.ОбщийМодуль("ОчередьЗаданий");

	ОбластиДляОбменаДанными = СериализаторXDTO.ПрочитатьXDTO(ОбластиДляОбменаДаннымиXDTO);

	УстановитьПривилегированныйРежим(Истина);

	Для Каждого Элемент Из ОбластиДляОбменаДанными Цикл

		ЗначениеРазделителя = Элемент.Ключ;
		СценарийОбменаДанными = Элемент.Значение;

		Параметры = Новый Массив;
		Параметры.Добавить(СценарийОбменаДанными);

		ПараметрыЗадания = Новый Структура;
		ПараметрыЗадания.Вставить("ИмяМетода"    , "ОбменДаннымиВМоделиСервиса.ВыполнитьОбменДанными");
		ПараметрыЗадания.Вставить("Параметры"    , Параметры);
		ПараметрыЗадания.Вставить("Ключ"         , "1");
		ПараметрыЗадания.Вставить("ОбластьДанных", ЗначениеРазделителя);

		Попытка
			МодульОчередьЗаданий.ДобавитьЗадание(ПараметрыЗадания);
		Исключение
			Если ИнформацияОбОшибке().Описание <> МодульОчередьЗаданий.ПолучитьТекстИсключенияДублированиеЗаданийСОдинаковымКлючом() Тогда
				ВызватьИсключение;
			КонецЕсли;
		КонецПопытки;

	КонецЦикла;

	Возврат "";
КонецФункции

// Соответствует операции StartExchangeExecutionInFirstDataBase

Функция ВыполнитьДействиеСценарияОбменаДаннымиВПервойИнформационнойБазе(ИндексСтрокиСценария, СценарийОбменаДаннымиXDTO)

	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса") Тогда
		Возврат "";
	КонецЕсли;

	МодульОчередьЗаданий = ОбщегоНазначения.ОбщийМодуль("ОчередьЗаданий");

	СценарийОбменаДанными = СериализаторXDTO.ПрочитатьXDTO(СценарийОбменаДаннымиXDTO);

	СтрокаСценария = СценарийОбменаДанными[ИндексСтрокиСценария];

	Ключ = СтрокаСценария.ИмяПланаОбмена + СтрокаСценария.КодУзлаИнформационнойБазы + СтрокаСценария.КодЭтогоУзла;

	РежимОбмена = РежимОбменаДанными(СценарийОбменаДанными);

	Если РежимОбмена = "Ручной" Тогда

		Параметры = Новый Массив;
		Параметры.Добавить(ИндексСтрокиСценария);
		Параметры.Добавить(СценарийОбменаДанными);

		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");

		УстановитьПривилегированныйРежим(Истина);
		МодульРаботаВМоделиСервиса.УстановитьРазделениеСеанса(Истина, СтрокаСценария.ЗначениеРазделителяПервойИнформационнойБазы);
		УстановитьПривилегированныйРежим(Ложь);

		РасширенияКонфигурации.ВыполнитьФоновоеЗаданиеСРасширениямиБазыДанных(
			"ОбменДаннымиВМоделиСервиса.ВыполнитьДействиеСценарияОбменаДаннымиВПервойИнформационнойБазе",
			Параметры,
			Ключ);

		УстановитьПривилегированныйРежим(Истина);
		МодульРаботаВМоделиСервиса.УстановитьРазделениеСеанса(Ложь);
		УстановитьПривилегированныйРежим(Ложь);

	ИначеЕсли РежимОбмена = "Автоматический" Тогда

		Попытка
			Параметры = Новый Массив;
			Параметры.Добавить(ИндексСтрокиСценария);
			Параметры.Добавить(СценарийОбменаДанными);

			ПараметрыЗадания = Новый Структура;
			ПараметрыЗадания.Вставить("ОбластьДанных", СтрокаСценария.ЗначениеРазделителяПервойИнформационнойБазы);
			ПараметрыЗадания.Вставить("ИмяМетода", "ОбменДаннымиВМоделиСервиса.ВыполнитьДействиеСценарияОбменаДаннымиВПервойИнформационнойБазе");
			ПараметрыЗадания.Вставить("Параметры", Параметры);
			ПараметрыЗадания.Вставить("Ключ", Ключ);
			ПараметрыЗадания.Вставить("Использование", Истина);

			УстановитьПривилегированныйРежим(Истина);
			МодульОчередьЗаданий.ДобавитьЗадание(ПараметрыЗадания);
		Исключение
			Если ИнформацияОбОшибке().Описание <> МодульОчередьЗаданий.ПолучитьТекстИсключенияДублированиеЗаданийСОдинаковымКлючом() Тогда
				ВызватьИсключение;
			КонецЕсли;
		КонецПопытки;

	Иначе
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Неизвестный режим обмена данными %1'"), Строка(РежимОбмена));
	КонецЕсли;

	Возврат "";
КонецФункции

// Соответствует операции StartExchangeExecutionInSecondDataBase

Функция ВыполнитьДействиеСценарияОбменаДаннымиВоВторойИнформационнойБазе(ИндексСтрокиСценария, СценарийОбменаДаннымиXDTO)

	Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса") Тогда
		Возврат "";
	КонецЕсли;

	МодульОчередьЗаданий = ОбщегоНазначения.ОбщийМодуль("ОчередьЗаданий");

	СценарийОбменаДанными = СериализаторXDTO.ПрочитатьXDTO(СценарийОбменаДаннымиXDTO);

	СтрокаСценария = СценарийОбменаДанными[ИндексСтрокиСценария];

	Ключ = СтрокаСценария.ИмяПланаОбмена + СтрокаСценария.КодУзлаИнформационнойБазы + СтрокаСценария.КодЭтогоУзла;

	РежимОбмена = РежимОбменаДанными(СценарийОбменаДанными);

	Если РежимОбмена = "Ручной" Тогда

		Параметры = Новый Массив;
		Параметры.Добавить(ИндексСтрокиСценария);
		Параметры.Добавить(СценарийОбменаДанными);

		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");

		УстановитьПривилегированныйРежим(Истина);
		МодульРаботаВМоделиСервиса.УстановитьРазделениеСеанса(Истина, СтрокаСценария.ЗначениеРазделителяВторойИнформационнойБазы);
		УстановитьПривилегированныйРежим(Ложь);

		РасширенияКонфигурации.ВыполнитьФоновоеЗаданиеСРасширениямиБазыДанных(
			"ОбменДаннымиВМоделиСервиса.ВыполнитьДействиеСценарияОбменаДаннымиВоВторойИнформационнойБазе",
			Параметры,
			Ключ);

		УстановитьПривилегированныйРежим(Истина);
		МодульРаботаВМоделиСервиса.УстановитьРазделениеСеанса(Ложь);
		УстановитьПривилегированныйРежим(Ложь);

	ИначеЕсли РежимОбмена = "Автоматический" Тогда

		Попытка
			Параметры = Новый Массив;
			Параметры.Добавить(ИндексСтрокиСценария);
			Параметры.Добавить(СценарийОбменаДанными);

			ПараметрыЗадания = Новый Структура;
			ПараметрыЗадания.Вставить("ОбластьДанных", СтрокаСценария.ЗначениеРазделителяВторойИнформационнойБазы);
			ПараметрыЗадания.Вставить("ИмяМетода", "ОбменДаннымиВМоделиСервиса.ВыполнитьДействиеСценарияОбменаДаннымиВоВторойИнформационнойБазе");
			ПараметрыЗадания.Вставить("Параметры", Параметры);
			ПараметрыЗадания.Вставить("Ключ", Ключ);
			ПараметрыЗадания.Вставить("Использование", Истина);

			УстановитьПривилегированныйРежим(Истина);
			МодульОчередьЗаданий.ДобавитьЗадание(ПараметрыЗадания);
		Исключение
			Если ИнформацияОбОшибке().Описание <> МодульОчередьЗаданий.ПолучитьТекстИсключенияДублированиеЗаданийСОдинаковымКлючом() Тогда
				ВызватьИсключение;
			КонецЕсли;
		КонецПопытки;

	Иначе
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Неизвестный режим обмена данными %1'"), Строка(РежимОбмена));
	КонецЕсли;

	Возврат "";
КонецФункции

// Соответствует операции TestConnection