[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `Завершить`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура Завершить(КомпонентыОбмена)
Экспорт

	Если НЕ КомпонентыОбмена.ВыполнятьЗамеры Тогда
		Возврат;
	КонецЕсли;

	СеансОбмена = КомпонентыОбмена.СеансОбмена;
	ИмяВременногоФайлаЗамеров = КомпонентыОбмена.ИмяВременногоФайлаЗамеров;

	КомпонентыОбмена.ВыполнятьЗамеры = Ложь;
	КомпонентыОбмена.ЗаписьЗамеров.Закрыть();

	ВремяНачала = СеансОбмена.Начало;
	ВремяОкончания = ТекущаяДатаСеанса();

	Каталог = ОбменДаннымиПовтИсп.КаталогВременногоХранилищаФайлов();
	ИмяАрхива = Формат(СеансОбмена.Начало, "ДФ=yyyy-MM-dd-HH-mm-ss") + "_"
		+ Строка(СеансОбмена.Ссылка.УникальныйИдентификатор()) + ".zip";

	ИмяВременногоФайлаИтогов = Каталог + "total.txt";
	ИмяВременногоФайлаАрхива = Каталог +  ИмяАрхива;

	ЗаписьИтогов = Новый ЗаписьТекста(ИмяВременногоФайлаИтогов);

	КодОсновногоЯзыка = ОбщегоНазначения.КодОсновногоЯзыка();

	// Шапка
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = '--- Сеанс обмена ---'", КодОсновногоЯзыка));
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = 'Направление обмена:'", КодОсновногоЯзыка) + КомпонентыОбмена.НаправлениеОбмена);

	Шаблон = НСтр("ru = 'Узел: %1 (%2)'", КодОсновногоЯзыка);
	ЗаписьИтогов.ЗаписатьСтроку(СтрШаблон(Шаблон,
		КомпонентыОбмена.УзелКорреспондента,
		КомпонентыОбмена.УзелКорреспондента.Код));

	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = 'Начало:'", КодОсновногоЯзыка) + ВремяНачала);
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = 'Окончание:'", КодОсновногоЯзыка) + ВремяОкончания);
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = 'Время выполнения (сек):'", КодОсновногоЯзыка) + (ВремяОкончания - ВремяНачала));
	ЗаписьИтогов.ЗаписатьСтроку("");

	// Итоги по типу событий
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = '--- Итоговые значения по типам ---'", КодОсновногоЯзыка));
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = 'Тип события; Время выполнения'", КодОсновногоЯзыка));

	ТаблицаЗамеровПоТипамСобытий = КомпонентыОбмена.ТаблицаЗамеровПоСобытиям.Скопировать(, "ТипСобытия, ВремяВыполнения");
	ТаблицаЗамеровПоТипамСобытий.Свернуть("ТипСобытия", "ВремяВыполнения");

	Шаблон = "%1; %2";
	Для Каждого СтрокаТаблицы Из ТаблицаЗамеровПоТипамСобытий Цикл

		Строка = СтрШаблон(Шаблон,
			СтрокаТаблицы.ТипСобытия,
			СтрокаТаблицы.ВремяВыполнения);

		ЗаписьИтогов.ЗаписатьСтроку(Строка);

	КонецЦикла;

	ЗаписьИтогов.ЗаписатьСтроку("");

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

	ТаблицаЗамеров = КомпонентыОбмена.ТаблицаЗамеровПоСобытиям;
	ТаблицаЗамеров.Сортировать("ВремяВыполнения Убыв");

	ВремяВыполненияИтог = ТаблицаЗамеров.Итог("ВремяВыполнения");

	Шаблон = "%1; %2; %3; %4; %5; %6";

	Для Каждого СтрокаТаблицы Из ТаблицаЗамеров Цикл
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура Завершить(КомпонентыОбмена) Экспорт

	Если НЕ КомпонентыОбмена.ВыполнятьЗамеры Тогда
		Возврат;
	КонецЕсли;

	СеансОбмена = КомпонентыОбмена.СеансОбмена;
	ИмяВременногоФайлаЗамеров = КомпонентыОбмена.ИмяВременногоФайлаЗамеров;

	КомпонентыОбмена.ВыполнятьЗамеры = Ложь;
	КомпонентыОбмена.ЗаписьЗамеров.Закрыть();

	ВремяНачала = СеансОбмена.Начало;
	ВремяОкончания = ТекущаяДатаСеанса();

	Каталог = ОбменДаннымиПовтИсп.КаталогВременногоХранилищаФайлов();
	ИмяАрхива = Формат(СеансОбмена.Начало, "ДФ=yyyy-MM-dd-HH-mm-ss") + "_"
		+ Строка(СеансОбмена.Ссылка.УникальныйИдентификатор()) + ".zip";

	ИмяВременногоФайлаИтогов = Каталог + "total.txt";
	ИмяВременногоФайлаАрхива = Каталог +  ИмяАрхива;

	ЗаписьИтогов = Новый ЗаписьТекста(ИмяВременногоФайлаИтогов);

	КодОсновногоЯзыка = ОбщегоНазначения.КодОсновногоЯзыка();

	// Шапка
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = '--- Сеанс обмена ---'", КодОсновногоЯзыка));
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = 'Направление обмена:'", КодОсновногоЯзыка) + КомпонентыОбмена.НаправлениеОбмена);

	Шаблон = НСтр("ru = 'Узел: %1 (%2)'", КодОсновногоЯзыка);
	ЗаписьИтогов.ЗаписатьСтроку(СтрШаблон(Шаблон,
		КомпонентыОбмена.УзелКорреспондента,
		КомпонентыОбмена.УзелКорреспондента.Код));

	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = 'Начало:'", КодОсновногоЯзыка) + ВремяНачала);
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = 'Окончание:'", КодОсновногоЯзыка) + ВремяОкончания);
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = 'Время выполнения (сек):'", КодОсновногоЯзыка) + (ВремяОкончания - ВремяНачала));
	ЗаписьИтогов.ЗаписатьСтроку("");

	// Итоги по типу событий
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = '--- Итоговые значения по типам ---'", КодОсновногоЯзыка));
	ЗаписьИтогов.ЗаписатьСтроку(НСтр("ru = 'Тип события; Время выполнения'", КодОсновногоЯзыка));

	ТаблицаЗамеровПоТипамСобытий = КомпонентыОбмена.ТаблицаЗамеровПоСобытиям.Скопировать(, "ТипСобытия, ВремяВыполнения");
	ТаблицаЗамеровПоТипамСобытий.Свернуть("ТипСобытия", "ВремяВыполнения");

	Шаблон = "%1; %2";
	Для Каждого СтрокаТаблицы Из ТаблицаЗамеровПоТипамСобытий Цикл

		Строка = СтрШаблон(Шаблон,
			СтрокаТаблицы.ТипСобытия,
			СтрокаТаблицы.ВремяВыполнения);

		ЗаписьИтогов.ЗаписатьСтроку(Строка);

	КонецЦикла;

	ЗаписьИтогов.ЗаписатьСтроку("");

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

	ТаблицаЗамеров = КомпонентыОбмена.ТаблицаЗамеровПоСобытиям;
	ТаблицаЗамеров.Сортировать("ВремяВыполнения Убыв");

	ВремяВыполненияИтог = ТаблицаЗамеров.Итог("ВремяВыполнения");

	Шаблон = "%1; %2; %3; %4; %5; %6";

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

		Если ВремяВыполненияИтог > 0 Тогда
			Процент = Окр(СтрокаТаблицы.ВремяВыполнения / ВремяВыполненияИтог * 100, 3);
		Иначе
			Процент = 0;
		КонецЕсли;
		Процент = СтроковыеФункцииКлиентСервер.ДополнитьСтроку(Процент, 7, " ", "Слева");

		СреднееВремяВыполнения = Окр(СтрокаТаблицы.ВремяВыполнения / СтрокаТаблицы.Количество, 3);
		СреднееВремяВыполнения = СтроковыеФункцииКлиентСервер.ДополнитьСтроку(СреднееВремяВыполнения, 7, " ", "Слева");

		ВремяВыполнения = Окр(СтрокаТаблицы.ВремяВыполнения, 3);
		ВремяВыполнения = Формат(ВремяВыполнения,"ЧГ=;");
		ВремяВыполнения = СтроковыеФункцииКлиентСервер.ДополнитьСтроку(ВремяВыполнения, 7, " ", "Слева");

		Количество = Формат(СтрокаТаблицы.Количество,"ЧГ=;");
		Количество = СтроковыеФункцииКлиентСервер.ДополнитьСтроку(СтрокаТаблицы.Количество, 7, " ", "Слева");
		ТипСобытия = СтроковыеФункцииКлиентСервер.ДополнитьСтроку(СтрокаТаблицы.ТипСобытия, 11, " ", "Справа");

		Строка = СтрШаблон(Шаблон,
			Процент,
			СреднееВремяВыполнения,
			ВремяВыполнения,
			Количество,
			ТипСобытия,
			СтрокаТаблицы.Событие);

		ЗаписьИтогов.ЗаписатьСтроку(Строка);

	КонецЦикла;

	ЗаписьИтогов.Закрыть();

	//
	СеансОбмена.Окончание = ВремяОкончания;
	СеансОбмена.ВремяВыполнения = ВремяОкончания - ВремяНачала;

	Архив = Новый ЗаписьZipФайла(ИмяВременногоФайлаАрхива);
	Архив.Добавить(ИмяВременногоФайлаЗамеров);
	Архив.Добавить(ИмяВременногоФайлаИтогов);
	Архив.Записать();

	СеансОбмена.ЗамерыПроизводительности = Новый ХранилищеЗначения(Новый ДвоичныеДанные(ИмяВременногоФайлаАрхива));
	СеансОбмена.Записать();

	// Удаление временных файлов
	УдалитьФайлы(ИмяВременногоФайлаИтогов);
	УдалитьФайлы(ИмяВременногоФайлаАрхива);
	УдалитьФайлы(ИмяВременногоФайлаЗамеров);

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

Функция НачатьЗамер() Экспорт

	Возврат ТекущаяУниверсальнаяДатаВМиллисекундах();

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

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

	Если Событие = "" Или НЕ КомпонентыОбмена.ВыполнятьЗамеры Тогда
		Возврат;
	КонецЕсли;

	Начало = Дата(1,1,1) + ВремяНачала / 1000;

	ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
	ВремяВыполнения = Окр((ВремяОкончания - ВремяНачала) / 1000, 3);

	ПредставлениеОбъекта = ПредставлениеОбъекта(Объект);

	// Лог
	ШаблонСтроки = "%1; %2; %3; %4; %5";

	Строка = СтрШаблон(ШаблонСтроки,
		Начало,
		Формат(ВремяВыполнения,"ЧГ=;"),
		ТипСобытия,
		Событие,
		ПредставлениеОбъекта);

	ЗаписьЗамеров = КомпонентыОбмена.ЗаписьЗамеров;
	ЗаписьЗамеров.ЗаписатьСтроку(Строка);

	// Итоговые данные по событиям
	ТаблицаЗамеров = КомпонентыОбмена.ТаблицаЗамеровПоСобытиям;
	Замер = ТаблицаЗамеров.Найти(Событие, "Событие");

	Если Замер = Неопределено Тогда
		НовыйЗамер = ТаблицаЗамеров.Добавить();
		НовыйЗамер.Событие = Событие;
		НовыйЗамер.ТипСобытия = ТипСобытия;
		НовыйЗамер.Количество = 1;
		НовыйЗамер.ВремяВыполнения = ВремяВыполнения;
	Иначе
		Замер.Количество = Замер.Количество + 1;
		Замер.ВремяВыполнения = Замер.ВремяВыполнения + ВремяВыполнения;
	КонецЕсли;

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

Функция ТаблицаЗамеровПоСобытиям() Экспорт

	Таблица = Новый ТаблицаЗначений;
	Таблица.Колонки.Добавить("Событие");
	Таблица.Колонки.Добавить("ТипСобытия");
	Таблица.Колонки.Добавить("Количество");
	Таблица.Колонки.Добавить("ВремяВыполнения");

	Таблица.Индексы.Добавить("Событие");

	Возврат Таблица;

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

Функция ТипСобытияПравило() Экспорт

	Возврат НСтр("ru = 'Правила обменов'", ОбщегоНазначения.КодОсновногоЯзыка());

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

Функция ТипСобытияБиблиотека() Экспорт

	Возврат НСтр("ru = 'Подсистема обменов'", ОбщегоНазначения.КодОсновногоЯзыка());

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

Функция ТипСобытияПрикладное() Экспорт

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

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

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

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

Функция ПредставлениеОбъекта(Объект)

	Если ТипЗнч(Объект) = Тип("Структура") Тогда

		МассивКлючейИЗначений = Новый Массив;
		Шаблон = "%1 = ""%2""";

		Если Объект.Свойство("КлючевыеСвойства") Тогда

			Для Каждого КлючИЗначение Из Объект.КлючевыеСвойства Цикл

				Если Не ЗначениеЗаполнено(КлючИЗначение.Значение)
					Или ТипЗнч(КлючИЗначение.Значение) = Тип("Структура") Тогда
					Продолжить;
				КонецЕсли;

				Строка = СтрШаблон(Шаблон, КлючИЗначение.Ключ, КлючИЗначение.Значение);
				МассивКлючейИЗначений.Добавить(Строка);

			КонецЦикла;

		КонецЕсли;

		Возврат СтрСоединить(МассивКлючейИЗначений, ", ");

	Иначе

		Возврат Строка(Объект);

	КонецЕсли;

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

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


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `ПолучитьВнешнееСоединениеДляУзлаИнформационнойБазы`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Функция ПолучитьВнешнееСоединениеДляУзлаИнформационнойБазы(УзелИнформационнойБазы, СтрокаСообщенияОбОшибке = "")
Экспорт

	Результат = ВнешнееСоединениеДляУзлаИнформационнойБазы(УзелИнформационнойБазы);
    // TODO: допиши оставшуюся часть

[Assistant]
Функция ПолучитьВнешнееСоединениеДляУзлаИнформационнойБазы(УзелИнформационнойБазы, СтрокаСообщенияОбОшибке = "") Экспорт

	Результат = ВнешнееСоединениеДляУзлаИнформационнойБазы(УзелИнформационнойБазы);

	СтрокаСообщенияОбОшибке = Результат.ПодробноеОписаниеОшибки;
	Возврат Результат.Соединение;

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

// Устанавливает внешнее соединение с информационной базой и возвращает указатель на это соединение.
//
// Параметры:
//  УзелИнформационнойБазы - ПланОбменаСсылка - узел плана обмена, для которого необходимо получить
//  внешнее соединение.
//  СтрокаСообщенияОбОшибке (необязательный) - Строка - если в процессе установки внешнего соединения возникает ошибка,
//   то подробное описание ошибки помещается в этот параметр.
//
// Возвращаемое значение:
//  COM-объект - в случае успешной установки внешнего соединения, в случае ошибки возвращается Неопределено.
//

Функция ВнешнееСоединениеДляУзлаИнформационнойБазы(УзелИнформационнойБазы) Экспорт

	Возврат ОбменДаннымиСервер.УстановитьВнешнееСоединениеСБазой(
        РегистрыСведений.НастройкиТранспортаОбменаДанными.НастройкиТранспорта(
            УзелИнформационнойБазы, Перечисления.ВидыТранспортаСообщенийОбмена.COM));

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

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

Функция ДоступноИспользованиеПланаОбмена(Знач ИмяПланаОбмена) Экспорт

	ОбъектВходитВСоставФункциональныхОпций = Ложь;

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

		Если ФункциональнаяОпция.Состав.Содержит(Метаданные.ПланыОбмена[ИмяПланаОбмена]) Тогда

			ОбъектВходитВСоставФункциональныхОпций = Истина;

			Если ПолучитьФункциональнуюОпцию(ФункциональнаяОпция.Имя) = Истина Тогда

				Возврат Истина;

			КонецЕсли;

		КонецЕсли;

	КонецЦикла;

	Если Не ОбъектВходитВСоставФункциональныхОпций Тогда

		Возврат Истина;

	КонецЕсли;

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

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

Функция ВерсииКорреспондента(Знач Корреспондент) Экспорт

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

	ПараметрыПодключения = Новый Структура;
	ПараметрыПодключения.Вставить("URL",      СтруктураНастроек.WSURLВебСервиса);
	ПараметрыПодключения.Вставить("UserName", СтруктураНастроек.WSИмяПользователя);
	ПараметрыПодключения.Вставить("Password", СтруктураНастроек.WSПароль);

	Возврат ОбщегоНазначения.ПолучитьВерсииИнтерфейса(ПараметрыПодключения, "ОбменДанными");

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

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

Функция ВсеСсылочныеТипыКонфигурации() Экспорт

	Результат = Новый Массив;

	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, Справочники.ТипВсеСсылки().Типы());
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, Документы.ТипВсеСсылки().Типы());
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, БизнесПроцессы.ТипВсеСсылки().Типы());
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, ПланыВидовХарактеристик.ТипВсеСсылки().Типы());
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, ПланыСчетов.ТипВсеСсылки().Типы());
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, ПланыВидовРасчета.ТипВсеСсылки().Типы());
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, Задачи.ТипВсеСсылки().Типы());
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, ПланыОбмена.ТипВсеСсылки().Типы());
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, Перечисления.ТипВсеСсылки().Типы());

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

Функция ПланыОбменаАвтономнойРаботы()

	// План обмена для организации автономной работы в модели сервиса должен:
	// - быть разделенным
	// - быть планом обмена распределенной ИБ
	// - использоваться для обмена в модели сервиса (ПланОбменаИспользуетсяВМоделиСервиса = Истина).

	Результат = Новый Массив;

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

		Если ОбменДаннымиСервер.ЭтоРазделенныйПланОбменаБСП(ПланОбмена.Имя)
			И ПланОбмена.РаспределеннаяИнформационнаяБаза
			И ОбменДаннымиПовтИсп.ПланОбменаИспользуетсяВМоделиСервиса(ПланОбмена.Имя) Тогда

			Результат.Добавить(ПланОбмена.Имя);

		КонецЕсли;

	КонецЦикла;

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

Функция ИмяПрофиляБезопасности(Знач ИмяПланаОбмена) Экспорт

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

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

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

	Возврат ИмяПрофиляБезопасности;

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

Функция РегистрацияПриЗацикливании(УзелИнформационнойБазы) Экспорт

	Возврат РегистрыСведений.ОбщиеНастройкиУзловИнформационныхБаз.РегистрацияПриЗацикливании(УзелИнформационнойБазы);

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

////////////////////////////////////////////////////////////////////////////////
// Инициализация структуры настроек обмена данными.

// Получает структуру настроек транспорта для выполнения обмена данными.
//

Функция НастройкиТранспортаУзлаПланаОбмена(УзелИнформационнойБазы, ВидТранспортаСообщенийОбмена) Экспорт

	Возврат ОбменДаннымиСервер.НастройкиТранспортаОбмена(УзелИнформационнойБазы, ВидТранспортаСообщенийОбмена);

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

// Получает список макетов типовых правил для обмена данными из конфигурации для заданного плана обмена;
// список заполняется именами и синонимами макетов правил.
//
// Параметры:
//  ИмяПланаОбмена - Строка - имя плана обмена как оно задано в конфигураторе.
//
// Возвращаемое значение:
//  СписокПравил - СписокЗначений - список макетов типовых правил для обмена данными.
//


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `ВыполнитьИнициализациюОбработкиТранспортаСообщенийОбменаСВнешнейСистемой`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура ВыполнитьИнициализациюОбработкиТранспортаСообщенийОбменаСВнешнейСистемой(СтруктураНастроекОбмена)
Если ОбщегоНазначения.ПодсистемаСуществует("ИнтернетПоддержкаПользователей.ОбменДаннымиСВнешнимиСистемами") Тогда

		ОбработкаТранспортаСообщенийОбмена = Обработки[СтруктураНастроекОбмена.ИмяОбработкиТранспортаСообщенийОбмена].Создать();

		ПараметрыПодключения = РегистрыСведений.НастройкиТранспортаОбменаДанными.НастройкиТранспортаВнешнейСистемы(
			СтруктураНастроекОбмена.УзелИнформационнойБазы);
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура ВыполнитьИнициализациюОбработкиТранспортаСообщенийОбменаСВнешнейСистемой(СтруктураНастроекОбмена)

	Если ОбщегоНазначения.ПодсистемаСуществует("ИнтернетПоддержкаПользователей.ОбменДаннымиСВнешнимиСистемами") Тогда

		ОбработкаТранспортаСообщенийОбмена = Обработки[СтруктураНастроекОбмена.ИмяОбработкиТранспортаСообщенийОбмена].Создать();

		ПараметрыПодключения = РегистрыСведений.НастройкиТранспортаОбменаДанными.НастройкиТранспортаВнешнейСистемы(
			СтруктураНастроекОбмена.УзелИнформационнойБазы);

		// Инициализируем транспорт.
		ОбработкаТранспортаСообщенийОбмена.Инициализация(ПараметрыПодключения);

		СтруктураНастроекОбмена.Вставить("ОбработкаТранспортаСообщенийОбмена", ОбработкаТранспортаСообщенийОбмена);

	КонецЕсли;

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

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

#Область ОбщегоНазначения_СлужебныеПроцедурыИФункции

Процедура ПолучитьОбщиеНастройкиУзловИнформационныхБаз(МенеджерВременныхТаблиц)

	Запрос = Новый Запрос;

	Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда

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

	Иначе

		ТекстЗапросаРезультат =
		"ВЫБРАТЬ
		|	NULL КАК УзелИнформационнойБазы,
		|	"""" КАК ВерсияКорреспондента,
		|	"""" КАК ПрефиксКорреспондента,
		|	ЛОЖЬ КАК НастройкаЗавершена,
		|	0 КАК ПереходНаWS_Этап,
		|	"""" КАК ВидТранспорта,
		|	ЛОЖЬ КАК СинхронизацияНедоступна
		|ПОМЕСТИТЬ ОбщиеНастройкиУзловИнформационныхБаз";

	КонецЕсли;

	Запрос.Текст = ТекстЗапросаРезультат;
	Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
	Запрос.Выполнить();

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

Функция СправочникиПланаОбмена(Знач ИмяПланаОбмена)

	Если ТипЗнч(ИмяПланаОбмена) <> Тип("Строка") Тогда

		ИмяПланаОбмена = ОбменДаннымиПовтИсп.ПолучитьИмяПланаОбмена(ИмяПланаОбмена);

	КонецЕсли;

	Результат = Новый Массив;

	СоставПланаОбмена = Метаданные.ПланыОбмена[ИмяПланаОбмена].Состав;

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

		Если ОбщегоНазначения.ЭтоСправочник(Элемент.Метаданные)
			ИЛИ ОбщегоНазначения.ЭтоПланВидовХарактеристик(Элемент.Метаданные) Тогда

			Результат.Добавить(Элемент.Метаданные);

		КонецЕсли;

	КонецЦикла;

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

// См. ТекущиеДелаПереопределяемый.ПриОпределенииОбработчиковТекущихДел

Процедура ПриЗаполненииСпискаТекущихДелПредупрежденияСинхронизации(ТекущиеДела)

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

	ПланыОбменаБСП = ОбменДаннымиПовтИсп.ПланыОбменаБСП();
	Если ПланыОбменаБСП.Количество() > 0 Тогда

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

	Иначе

		СтруктураРезультат = Новый Структура("Количество, Заголовок", 0, "");

	КонецЕсли;

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

	Для Каждого Раздел Из Разделы Цикл

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

	КонецЦикла;

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

// См. ТекущиеДелаПереопределяемый.ПриОпределенииОбработчиковТекущихДел

Процедура ПриЗаполненииСпискаТекущихДелПроверитьЗацикливание(ТекущиеДела)

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

	ПланыОбменаБСП = ОбменДаннымиПовтИсп.ПланыОбменаБСП();
	ЕстьЗацикливание = ПланыОбменаБСП.Количество() > 0 И ОбменДаннымиКонтрольЗацикливания.ЕстьЗацикливание();

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

	Для Каждого Раздел Из Разделы Цикл

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

	КонецЦикла;

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

// См. ТекущиеДелаПереопределяемый.ПриОпределенииОбработчиковТекущихДел.


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `ВыполнитьПроверкуНаличияПравилОбменаЗагруженныхИзФайла`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

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

	Запрос = Новый Запрос;
	Запрос.Текст = ТекстЗапроса;

	Результат = Запрос.Выполнить();

	Если Не Результат.Пустой() Тогда

		ПланыОбменаМассив = Новый Массив;

		Выборка = Результат.Выбрать();

		Пока Выборка.Следующий() Цикл

			Если Выборка.ВидПравил = Перечисления.ВидыПравилДляОбменаДанными.ПравилаКонвертацииОбъектов Тогда

				ПравилаОбменаЗагруженныеИзФайла.Добавить(Выборка.ИмяПланаОбмена);

			ИначеЕсли Выборка.ВидПравил = Перечисления.ВидыПравилДляОбменаДанными.ПравилаРегистрацииОбъектов Тогда
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура ВыполнитьПроверкуНаличияПравилОбменаЗагруженныхИзФайла(ПравилаОбменаЗагруженныеИзФайла, ПравилаРегистрацииЗагруженныеИзФайла)

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

	Запрос = Новый Запрос;
	Запрос.Текст = ТекстЗапроса;

	Результат = Запрос.Выполнить();

	Если Не Результат.Пустой() Тогда

		ПланыОбменаМассив = Новый Массив;

		Выборка = Результат.Выбрать();

		Пока Выборка.Следующий() Цикл

			Если Выборка.ВидПравил = Перечисления.ВидыПравилДляОбменаДанными.ПравилаКонвертацииОбъектов Тогда

				ПравилаОбменаЗагруженныеИзФайла.Добавить(Выборка.ИмяПланаОбмена);

			ИначеЕсли Выборка.ВидПравил = Перечисления.ВидыПравилДляОбменаДанными.ПравилаРегистрацииОбъектов Тогда

				ПравилаРегистрацииЗагруженныеИзФайла.Добавить(Выборка.ИмяПланаОбмена);

			КонецЕсли;

			Если ПланыОбменаМассив.Найти(Выборка.ИмяПланаОбмена) = Неопределено Тогда

				ПланыОбменаМассив.Добавить(Выборка.ИмяПланаОбмена);

			КонецЕсли;

		КонецЦикла;

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

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

	КонецЕсли;

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

// Основная функция для использования внешнего соединения при обмене.
//
// Параметры:
//  СтруктураНастроек - структура настроек транспорта COM обмена.
//
// Возвращаемое значение:
//  Структура:
//    * Соединение                  - COMОбъект
//                                  - Неопределено - указатель на COM-объект соединения или Неопределено в
//                                    случае ошибки;
//    * КраткоеОписаниеОшибки       - Строка - краткое описание ошибки;
//    * ПодробноеОписаниеОшибки     - Строка - подробное описание ошибки;
//    * ОшибкаПодключенияКомпоненты - Булево - флаг ошибки подключения COM.
//

Функция УстановитьВнешнееСоединениеСБазой(СтруктураНастроек) Экспорт

	Результат = ОбщегоНазначения.УстановитьВнешнееСоединениеСБазой(
		ЗаполнитьПараметрыПодключенияВнешнегоСоединения(СтруктураНастроек));

	ВнешнееСоединение = Результат.Соединение;
	Если ВнешнееСоединение = Неопределено Тогда
		// Ошибка установки соединения.
		Возврат Результат;
	КонецЕсли;

	// Для конфигураций с разными вариантами встроенного языка COM соединение не работает

	ВариантВстроенногоЯзыкаКорреспондента = "";
	ВариантыВстроенногоЯзыкаОтличаются = Ложь;
	Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский
		И ВнешнееСоединение.Метаданные.ВариантВстроенногоЯзыка <> ВнешнееСоединение.Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда
		ВариантВстроенногоЯзыкаКорреспондента = НСтр("ru = 'Английский'");
		ВариантыВстроенногоЯзыкаОтличаются = Истина;
	КонецЕсли;

	Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский
		И ВнешнееСоединение.Метаданные.ВариантВстроенногоЯзыка <> ВнешнееСоединение.Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский Тогда
		ВариантВстроенногоЯзыкаКорреспондента = НСтр("ru = 'Русский'");
		ВариантыВстроенногоЯзыкаОтличаются = Истина;
	КонецЕсли;

	Если ВариантыВстроенногоЯзыкаОтличаются Тогда

		ПодробноеОписаниеОшибки = НСтр("ru = 'В подключаемой программе отличается вариант встроенного языка (%1). Подключение невозможно.'");
		ПодробноеОписаниеОшибки = СтрШаблон(ПодробноеОписаниеОшибки, ВариантВстроенногоЯзыкаКорреспондента);

		Результат.ПодробноеОписаниеОшибки = ПодробноеОписаниеОшибки;
		Результат.КраткоеОписаниеОшибки   = ПодробноеОписаниеОшибки;
		Результат.Соединение = Неопределено;

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

	КонецЕсли;

	// Дополнительно проверяем возможность работы с внешней базой.

	Попытка
		НетПолныхПрав = Не ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.РольДоступнаПолныеПрава();
	Исключение
		НетПолныхПрав = Истина;
	КонецПопытки;

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

		Если СостояниеНеДопустимо Тогда
			Результат.ПодробноеОписаниеОшибки = НСтр("ru = 'Другая программа находится в состоянии обновления.'");
			Результат.КраткоеОписаниеОшибки   = Результат.ПодробноеОписаниеОшибки;
			Результат.Соединение = Неопределено;
		КонецЕсли;

	КонецЕсли;

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

Функция НастройкиТранспортаПоПараметрамВнешнегоСоединения(Параметры)

	// Преобразуем настройки - параметры внешнего соединения в параметры транспорта.
	НастройкиТранспорта = Новый Структура;

	НастройкиТранспорта.Вставить("COMПарольПользователя",
		ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ПарольПользователя"));
	НастройкиТранспорта.Вставить("COMИмяПользователя",
		ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ИмяПользователя"));
	НастройкиТранспорта.Вставить("COMАутентификацияОперационнойСистемы",
		ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "АутентификацияОперационнойСистемы"));
	НастройкиТранспорта.Вставить("COMИмяИнформационнойБазыНаСервере1СПредприятия",
		ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ИмяИнформационнойБазыНаСервере1СПредприятия"));
	НастройкиТранспорта.Вставить("COMИмяСервера1СПредприятия",
		ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ИмяСервера1СПредприятия"));
	НастройкиТранспорта.Вставить("COMКаталогИнформационнойБазы",
		ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "КаталогИнформационнойБазы"));
	НастройкиТранспорта.Вставить("COMВариантРаботыИнформационнойБазы",
		ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметры, "ВариантРаботыИнформационнойБазы"));

	Возврат НастройкиТранспорта;

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

Процедура УдалитьНезначащиеСимволыВНастройкахПодключения(Настройки) Экспорт

	Для Каждого Настройка Из Настройки Цикл

		Если ТипЗнч(Настройка.Значение) = Тип("Строка") Тогда

			Настройки.Вставить(Настройка.Ключ, СокрЛП(Настройка.Значение));

		КонецЕсли;

	КонецЦикла;

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

// Выводит сообщение об ошибке и выставляет параметр Отказ в "Истина".
//
// Параметры:
//  ТекстСообщения - Строка - текст сообщения.
//  Отказ          - Булево - признак отказа
//

Процедура СообщитьОбОшибке(ТекстСообщения, Отказ = Ложь) Экспорт

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

	ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);

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

// Выполняет загрузку правил для обмена данными (ПРО или ПКО) в ИБ.
//


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `ДеревоМетаданныхКонфигурации`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Функция ДеревоМетаданныхКонфигурации(Отбор = Неопределено)
Экспорт

	ИспользоватьОтбор = (Отбор <> Неопределено);

	КоллекцииОбъектовМетаданных = Новый ТаблицаЗначений;
	КоллекцииОбъектовМетаданных.Колонки.Добавить("Имя");
	КоллекцииОбъектовМетаданных.Колонки.Добавить("Синоним");
	КоллекцииОбъектовМетаданных.Колонки.Добавить("Картинка");
	КоллекцииОбъектовМетаданных.Колонки.Добавить("КартинкаОбъекта");

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

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

	Для Каждого СтрокаКоллекции Из КоллекцииОбъектовМетаданных Цикл

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

			Если ИспользоватьОтбор Тогда

				ОбъектПрошелФильтр = Истина;
				Для Каждого ЭлементОтбора Из Отбор Цикл

					Значение = ?(ВРег(ЭлементОтбора.Ключ) = ВРег("ПолноеИмя"), ОбъектМетаданных.ПолноеИмя(), ОбъектМетаданных[ЭлементОтбора.Ключ]);
					Если ЭлементОтбора.Значение.Найти(Значение) = Неопределено Тогда
						ОбъектПрошелФильтр = Ложь;
						Прервать;
					КонецЕсли;

				КонецЦикла;

				Если Не ОбъектПрошелФильтр Тогда
    // TODO: допиши оставшуюся часть

[Assistant]
Функция ДеревоМетаданныхКонфигурации(Отбор = Неопределено) Экспорт

	ИспользоватьОтбор = (Отбор <> Неопределено);

	КоллекцииОбъектовМетаданных = Новый ТаблицаЗначений;
	КоллекцииОбъектовМетаданных.Колонки.Добавить("Имя");
	КоллекцииОбъектовМетаданных.Колонки.Добавить("Синоним");
	КоллекцииОбъектовМетаданных.Колонки.Добавить("Картинка");
	КоллекцииОбъектовМетаданных.Колонки.Добавить("КартинкаОбъекта");

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

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

	Для Каждого СтрокаКоллекции Из КоллекцииОбъектовМетаданных Цикл

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

			Если ИспользоватьОтбор Тогда

				ОбъектПрошелФильтр = Истина;
				Для Каждого ЭлементОтбора Из Отбор Цикл

					Значение = ?(ВРег(ЭлементОтбора.Ключ) = ВРег("ПолноеИмя"), ОбъектМетаданных.ПолноеИмя(), ОбъектМетаданных[ЭлементОтбора.Ключ]);
					Если ЭлементОтбора.Значение.Найти(Значение) = Неопределено Тогда
						ОбъектПрошелФильтр = Ложь;
						Прервать;
					КонецЕсли;

				КонецЦикла;

				Если Не ОбъектПрошелФильтр Тогда
					Продолжить;
				КонецЕсли;

			КонецЕсли;

			СтрокаДереваОМ = СтрокаДерева.Строки.Добавить();
			СтрокаДереваОМ.Имя       = ОбъектМетаданных.Имя;
			СтрокаДереваОМ.ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
			СтрокаДереваОМ.Синоним   = ОбъектМетаданных.Синоним;
			СтрокаДереваОМ.Картинка  = СтрокаКоллекции.КартинкаОбъекта;

		КонецЦикла;

	КонецЦикла;

	// Удаляем строки без подчиненных элементов.
	Если ИспользоватьОтбор Тогда

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

		Для ОбратныйИндекс = 1 По КоличествоЭлементовКоллекции Цикл

			ТекущийИндекс = КоличествоЭлементовКоллекции - ОбратныйИндекс;
			СтрокаДерева = ДеревоМетаданных.Строки[ТекущийИндекс];
			Если СтрокаДерева.Строки.Количество() = 0 Тогда
				ДеревоМетаданных.Строки.Удалить(ТекущийИндекс);
			КонецЕсли;

		КонецЦикла;

	КонецЕсли;

	Возврат ДеревоМетаданных;

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

Процедура НоваяСтрокаКоллекцииОбъектовМетаданных(Имя, Синоним, Картинка, КартинкаОбъекта, Таб)

	НоваяСтрока = Таб.Добавить();
	НоваяСтрока.Имя               = Имя;
	НоваяСтрока.Синоним           = Синоним;
	НоваяСтрока.Картинка          = Картинка;
	НоваяСтрока.КартинкаОбъекта   = КартинкаОбъекта;

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

Функция КодПредопределенногоУзлаПланаОбмена(ИмяПланаОбмена) Экспорт

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

	ЭтотУзел = ОбменДаннымиПовтИсп.ПолучитьЭтотУзелПланаОбмена(ИмяПланаОбмена);

	Возврат СокрЛП(ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЭтотУзел, "Код"));

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

// Возвращает массив всех узлов для заданного плана обмена кроме предопределенного узла.
//
// Параметры:
//  ИмяПланаОбмена - Строка - имя плана обмена как оно задано в конфигураторе.
//
// Возвращаемое значение:
//  МассивУзлов - Массив - массив всех узлов для заданного плана обмена кроме предопределенного узла.
//

Функция УзлыПланаОбмена(ИмяПланаОбмена) Экспорт

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

	Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ИмяТаблицыПланаОбмена", "ПланОбмена." + ИмяПланаОбмена);

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

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

Функция ИмяКаталогаДляСопоставленияФайловаяИБ() Экспорт

	Возврат СтроковыеФункцииКлиентСервер.ПараметрыИзСтроки(СтрокаСоединенияИнформационнойБазы()).File
		+ ПолучитьРазделительПути() + "TempMessageForDataMatching";

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

Функция ПолноеИмяФайлаДляСопоставленияФайловаяИБ(ИмяФайла) Экспорт

	Возврат ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(ИмяКаталогаДляСопоставленияФайловаяИБ(), ИмяФайла);

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

// Останавливает выполнение кода на заданное время.
// Метод продублирован из БТС, т.к. п/с может использоваться без указанной библиотеки.
//
// Параметры:
//  Секунд - Число - время ожидания в секундах.
//


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `МеханизмРегистрацииОбъектовПередЗаписьюДокумента`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура МеханизмРегистрацииОбъектовПередЗаписьюДокумента(ИмяПланаОбмена, Источник, Отказ, РежимЗаписи, РежимПроведения)
Экспорт

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

	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ЗащитаПерсональныхДанных") Тогда

		Модуль = ОбщегоНазначения.ОбщийМодуль("ЗащитаПерсональныхДанных");
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура МеханизмРегистрацииОбъектовПередЗаписьюДокумента(ИмяПланаОбмена, Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт

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

	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ЗащитаПерсональныхДанных") Тогда

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

	КонецЕсли;

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

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

// Процедура-обработчик события "ПередЗаписью" ссылочных типов данных (кроме документов) для механизма регистрации
// объектов на узлах.
//
// Параметры:
//  ИмяПланаОбмена - Строка - имя плана обмена, для которого выполняется механизм регистрации.
//  Источник       - СправочникОбъект
//                 - ПланВидовХарактеристикОбъект - источник события, кроме типа ДокументОбъект.
//  Отказ          - Булево - флаг отказа от выполнения обработчика.
//

Процедура МеханизмРегистрацииОбъектовПередЗаписью(ИмяПланаОбмена, Источник, Отказ) Экспорт

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

	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ЗащитаПерсональныхДанных") Тогда

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

	КонецЕсли;

	ЗарегистрироватьИзменениеОбъекта(ИмяПланаОбмена, Источник, Отказ);

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

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

Процедура МеханизмРегистрацииОбъектовПередЗаписьюРегистра(ИмяПланаОбмена, Источник, Отказ, Замещение) Экспорт

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

	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ЗащитаПерсональныхДанных") Тогда

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

	КонецЕсли;

	ДополнительныеПараметры = Новый Структура("ЭтоРегистр,Замещение", Истина, Замещение);
	ЗарегистрироватьИзменениеОбъекта(ИмяПланаОбмена, Источник, Отказ, ДополнительныеПараметры);

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

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

Процедура МеханизмРегистрацииОбъектовПередЗаписьюКонстанты(ИмяПланаОбмена, Источник, Отказ) Экспорт

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

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

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

// Процедура-обработчик события "ПередУдалением" ссылочных типов данных для механизма регистрации объектов на узлах.
//
// Параметры:
//  ИмяПланаОбмена - Строка - имя плана обмена, для которого выполняется механизм регистрации.
//  Источник       - СправочникОбъект
//                 - ДокументОбъект
//                 - ПланВидовХарактеристикОбъект - источник события.
//  Отказ          - Булево - флаг отказа от выполнения обработчика.
//

Процедура МеханизмРегистрацииОбъектовПередУдалением(ИмяПланаОбмена, Источник, Отказ) Экспорт

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

	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ЗащитаПерсональныхДанных") Тогда

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

	КонецЕсли;

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

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

////////////////////////////////////////////////////////////////////////////////
// Процедуры и функции для использования в обработчиках событий правил регистрации.

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

Процедура ДополнитьПолучателей(Объект, Узлы) Экспорт

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

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

	КонецЦикла;

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

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

Процедура СократитьПолучателей(Объект, Узлы) Экспорт

	Получатели = СократитьМассив(Объект.ОбменДанными.Получатели, Узлы);

	// Очищаем список получателей и заполняем его заново.
	Объект.ОбменДанными.Получатели.Очистить();

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

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

// Определяет массив узлов-получателей для объекта при заданном плане обмена и выполняет регистрацию объекта на
// полученных узлах.
//
// Параметры:
//  Объект         - Произвольный - СправочникОбъект, ДокументОбъект и т.п. объект, для которого необходимо выполнить
//                   правила регистрации, и выполнить регистрацию на узлах.
//  ИмяПланаОбмена - Строка - имя плана обмена как оно задано в конфигураторе.
//  Отправитель    - ПланОбменаСсылка - узел плана обмена от которого принимается сообщение обмена.
//                    Если задан, то регистрация объекта не этом узле выполнятся не будет.
//


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `ПроверитьКоллизиюИзмененийДанных`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

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

		Возврат;

	ИначеЕсли ЭлементДанных.ДополнительныеСвойства.Свойство("ОбменДанными") И ЭлементДанных.ДополнительныеСвойства.ОбменДанными.АнализДанных Тогда

		Возврат;

	КонецЕсли;

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

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

	ЕстьКоллизия = ПланыОбмена.ИзменениеЗарегистрировано(Отправитель, ЭлементДанных);

	// Выполняем дополнительную проверку на изменение объекта
	// если объект до коллизии и после коллизии не изменен,
	// то считаем, что коллизии нет.
	Если ЕстьКоллизия Тогда

		Если ЭтоСсылочныйТип И Не ЭлементДанных.Ссылка.Пустая() Тогда

			ОбъектВБазе = ЭлементДанных.Ссылка.ПолучитьОбъект();
			СсылкаСуществует = (ОбъектВБазе <> Неопределено);

		Иначе
			СсылкаСуществует = Ложь;
			ОбъектВБазе = Неопределено;
		КонецЕсли;

		СтрокаОбъектаДоИзменения    = ДанныеОбъектаСтрокойДоИзменения(ЭлементДанных, МетаданныеОбъекта, ЭтоСсылочныйТип, СсылкаСуществует, ОбъектВБазе);
		СтрокаОбъектаПослеИзменения = ДанныеОбъектаСтрокойПослеИзменения(ЭлементДанных, МетаданныеОбъекта);

		// Если значения совпадают, то коллизии нет.
		Если СтрокаОбъектаДоИзменения = СтрокаОбъектаПослеИзменения Тогда

			ЕстьКоллизия = Ложь;

		КонецЕсли;

	КонецЕсли;

	Если ЕстьКоллизия Тогда

		ОбменДаннымиПереопределяемый.ПриКоллизииИзмененийДанных(ЭлементДанных, ПолучениеЭлемента, Отправитель, ЭтоПолучениеОтГлавного);

		Если ПолучениеЭлемента = ПолучениеЭлементаДанных.Авто Тогда
			ПолучениеЭлемента = ?(ЭтоПолучениеОтГлавного, ПолучениеЭлементаДанных.Принять, ПолучениеЭлементаДанных.Игнорировать);
		КонецЕсли;

		ЗаписатьОбъект = (ПолучениеЭлемента = ПолучениеЭлементаДанных.Принять);
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура ПроверитьКоллизиюИзмененийДанных(ЭлементДанных, ПолучениеЭлемента, Знач Отправитель, Знач ЭтоПолучениеОтГлавного)

	Если ТипЗнч(ЭлементДанных) = Тип("УдалениеОбъекта") Тогда

		Возврат;

	ИначеЕсли ЭлементДанных.ДополнительныеСвойства.Свойство("ОбменДанными") И ЭлементДанных.ДополнительныеСвойства.ОбменДанными.АнализДанных Тогда

		Возврат;

	КонецЕсли;

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

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

	ЕстьКоллизия = ПланыОбмена.ИзменениеЗарегистрировано(Отправитель, ЭлементДанных);

	// Выполняем дополнительную проверку на изменение объекта
	// если объект до коллизии и после коллизии не изменен,
	// то считаем, что коллизии нет.
	Если ЕстьКоллизия Тогда

		Если ЭтоСсылочныйТип И Не ЭлементДанных.Ссылка.Пустая() Тогда

			ОбъектВБазе = ЭлементДанных.Ссылка.ПолучитьОбъект();
			СсылкаСуществует = (ОбъектВБазе <> Неопределено);

		Иначе
			СсылкаСуществует = Ложь;
			ОбъектВБазе = Неопределено;
		КонецЕсли;

		СтрокаОбъектаДоИзменения    = ДанныеОбъектаСтрокойДоИзменения(ЭлементДанных, МетаданныеОбъекта, ЭтоСсылочныйТип, СсылкаСуществует, ОбъектВБазе);
		СтрокаОбъектаПослеИзменения = ДанныеОбъектаСтрокойПослеИзменения(ЭлементДанных, МетаданныеОбъекта);

		// Если значения совпадают, то коллизии нет.
		Если СтрокаОбъектаДоИзменения = СтрокаОбъектаПослеИзменения Тогда

			ЕстьКоллизия = Ложь;

		КонецЕсли;

	КонецЕсли;

	Если ЕстьКоллизия Тогда

		ОбменДаннымиПереопределяемый.ПриКоллизииИзмененийДанных(ЭлементДанных, ПолучениеЭлемента, Отправитель, ЭтоПолучениеОтГлавного);

		Если ПолучениеЭлемента = ПолучениеЭлементаДанных.Авто Тогда
			ПолучениеЭлемента = ?(ЭтоПолучениеОтГлавного, ПолучениеЭлементаДанных.Принять, ПолучениеЭлементаДанных.Игнорировать);
		КонецЕсли;

		ЗаписатьОбъект = (ПолучениеЭлемента = ПолучениеЭлементаДанных.Принять);

		ЗарегистрироватьПредупреждениеОКоллизииВЖурналеРегистрации(ЭлементДанных, МетаданныеОбъекта, ЗаписатьОбъект, ЭтоСсылочныйТип);

		Если Не ЭтоСсылочныйТип Тогда
			Возврат;
		КонецЕсли;

		Если ОбменДаннымиПовтИсп.ИспользуетсяВерсионирование(Отправитель) Тогда
			Если СсылкаСуществует Тогда

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

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

			КонецЕсли;

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

		КонецЕсли;

	КонецЕсли;

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

// Выполняет проверку на наличие запрета загрузки по дате.
//
// Параметры:
//   ЭлементДанных - СправочникОбъект
//                 - ДокументОбъект
//                 - РегистрСведенийНаборЗаписей -
//                   Данные, которые были зачитаны из сообщения обмена, но еще не были записаны в ИБ.
//   ПолучениеЭлемента - ПолучениеЭлементаДанных
//   Отправитель   - ПланОбменаОбъект
//

Процедура ПроверитьНаличиеЗапретаЗагрузкиПоДате(ЭлементДанных, ПолучениеЭлемента, Знач Отправитель)

	Если ОбменДаннымиПовтИсп.ЭтоУзелРаспределеннойИнформационнойБазы(Отправитель.Ссылка) Тогда
		Возврат;
	КонецЕсли;

	ЭтоУдалениеОбъекта = (ТипЗнч(ЭлементДанных) = Тип("УдалениеОбъекта"));

	Если Не ЭтоУдалениеОбъекта
		И ОбщегоНазначения.ЭтоКонстанта(ЭлементДанных.Метаданные()) Тогда
		Возврат;
	КонецЕсли;

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

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

		Отказ = Ложь;
		ОписаниеОшибки = "";

		МодульДатыЗапретаИзменения.ПроверитьДатыЗапретаЗагрузкиДанных(ЭлементДанных,
			Отправитель.Ссылка, Отказ, ОписаниеОшибки);

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

	КонецЕсли;

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

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

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


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `ОбработчикиОбновления`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

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

	Если Отбор = Неопределено Тогда
		Отбор = Новый Структура;
	КонецЕсли;

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ОбработчикиОбновления.ИмяОбработчика КАК ИмяОбработчика,
	|	ОбработчикиОбновления.РежимВыполнения КАК РежимВыполненияСсылка,
	|	ОбработчикиОбновления.ИмяБиблиотеки КАК ИмяБиблиотеки,
	|	ОбработчикиОбновления.Версия КАК Версия,
	|	ОбработчикиОбновления.Статус КАК СтатусСсылка,
	|	ОбработчикиОбновления.ДлительностьОбработки КАК ДлительностьОбработки,
	|	ОбработчикиОбновления.ИнформацияОбОшибке КАК ИнформацияОбОшибке,
	|	ОбработчикиОбновления.ОбластьДанныхВспомогательныеДанные КАК ОбластьДанных
	|ИЗ
	|	РегистрСведений.ОбработчикиОбновления КАК ОбработчикиОбновления
	|ГДЕ
	|	&УсловиеОбработчиковОбластей
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	ОбработчикиОбновления.ИмяОбработчика,
	|	ОбработчикиОбновления.РежимВыполнения,
	|	ОбработчикиОбновления.ИмяБиблиотеки,
	|	ОбработчикиОбновления.Версия,
	|	ОбработчикиОбновления.Статус,
	|	ОбработчикиОбновления.ДлительностьОбработки,
	|	ОбработчикиОбновления.ИнформацияОбОшибке,
	|	0
	|ИЗ
	|	РегистрСведений.ОбработчикиОбновленияОбщихДанных КАК ОбработчикиОбновления
	|ГДЕ
	|	&УсловиеОбработчиковОбщихДанных";

	УсловияЗапроса = Новый Массив;

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

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

	Если ЗначениеЗаполнено(УсловияЗапроса) Тогда
		УсловиеОбработчиковОбщихДанных = СтрСоединить(УсловияЗапроса, Символы.ПС + " И ");
	Иначе
		УсловиеОбработчиковОбщихДанных = "ИСТИНА";
	КонецЕсли;

	Если Отбор.Свойство("ОбластиДанных") Тогда
		ОбластиДанных = Отбор.ОбластиДанных;
	ИначеЕсли ОбщегоНазначения.РазделениеВключено() Тогда
		МодульРаботаВМоделиСервиса = ОбщегоНазначения.ОбщийМодуль("РаботаВМоделиСервиса");
		ОбластиДанных = МодульРаботаВМоделиСервиса.ИспользуемыеОбластиДанных().Выгрузить().ВыгрузитьКолонку(
			"ОбластьДанных");
    // TODO: допиши оставшуюся часть

[Assistant]
Функция ОбработчикиОбновления(Отбор = Неопределено) Экспорт

	Если Отбор = Неопределено Тогда
		Отбор = Новый Структура;
	КонецЕсли;

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ОбработчикиОбновления.ИмяОбработчика КАК ИмяОбработчика,
	|	ОбработчикиОбновления.РежимВыполнения КАК РежимВыполненияСсылка,
	|	ОбработчикиОбновления.ИмяБиблиотеки КАК ИмяБиблиотеки,
	|	ОбработчикиОбновления.Версия КАК Версия,
	|	ОбработчикиОбновления.Статус КАК СтатусСсылка,
	|	ОбработчикиОбновления.ДлительностьОбработки КАК ДлительностьОбработки,
	|	ОбработчикиОбновления.ИнформацияОбОшибке КАК ИнформацияОбОшибке,
	|	ОбработчикиОбновления.ОбластьДанныхВспомогательныеДанные КАК ОбластьДанных
	|ИЗ
	|	РегистрСведений.ОбработчикиОбновления КАК ОбработчикиОбновления
	|ГДЕ
	|	&УсловиеОбработчиковОбластей
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	ОбработчикиОбновления.ИмяОбработчика,
	|	ОбработчикиОбновления.РежимВыполнения,
	|	ОбработчикиОбновления.ИмяБиблиотеки,
	|	ОбработчикиОбновления.Версия,
	|	ОбработчикиОбновления.Статус,
	|	ОбработчикиОбновления.ДлительностьОбработки,
	|	ОбработчикиОбновления.ИнформацияОбОшибке,
	|	0
	|ИЗ
	|	РегистрСведений.ОбработчикиОбновленияОбщихДанных КАК ОбработчикиОбновления
	|ГДЕ
	|	&УсловиеОбработчиковОбщихДанных";

	УсловияЗапроса = Новый Массив;

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

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

	Если ЗначениеЗаполнено(УсловияЗапроса) Тогда
		УсловиеОбработчиковОбщихДанных = СтрСоединить(УсловияЗапроса, Символы.ПС + " И ");
	Иначе
		УсловиеОбработчиковОбщихДанных = "ИСТИНА";
	КонецЕсли;

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

	Если ОбластиДанных <> Неопределено Тогда
		УсловияЗапроса.Добавить("ОбработчикиОбновления.ОбластьДанныхВспомогательныеДанные В (&ОбластиДанных)");
		Запрос.УстановитьПараметр("ОбластиДанных", ОбластиДанных);
		Если Отбор.Свойство("ОбластиДанных") И Отбор.ОбластиДанных.Найти(0) = Неопределено Тогда
			УсловиеОбработчиковОбщихДанных = "ЛОЖЬ";
		КонецЕсли;
	КонецЕсли;

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

	Запрос.Текст = СтрЗаменить(Запрос.Текст, "&УсловиеОбработчиковОбластей", УсловиеОбработчиковОбластей);
	Запрос.Текст = СтрЗаменить(Запрос.Текст, "&УсловиеОбработчиковОбщихДанных", УсловиеОбработчиковОбщихДанных);

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

	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл

		Строка = ИнформацияПоОбработчикам.Добавить();
		ЗаполнитьЗначенияСвойств(Строка, Выборка);
		Строка.РежимВыполнения = ИменаРежимовПоЗначению[Выборка.РежимВыполненияСсылка];
		Строка.Статус = ИменаСтатусовПоЗначению[Выборка.СтатусСсылка];

	КонецЦикла;

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

	Возврат ИнформацияПоОбработчикам;

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

// Возвращает таблицу обновляемых объектов конфигурации со списком обработчиков,
// которые их обрабатывают на текущую версию.
//
// Возвращаемое значение:
//  Соответствие из КлючИЗначение:
//     * Ключ - Строка - полное имя объекта.
//     * Значение - Массив из Строка - имена выполняемых обработчиков обновления.
//


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `СброситьСведенияОбОбновлении`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

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

	НовыеСведенияОбОбновлении = НовыеСведенияОбОбновлении();

	Константы.ОтложенноеОбновлениеЗавершеноУспешно.Установить(Ложь);

	СведенияОбОбновлении.Вставить("ВремяНачалаОбновления");
	СведенияОбОбновлении.Вставить("ВремяОкончанияОбновления");
	СведенияОбОбновлении.Вставить("ПродолжительностьОбновления");
	СведенияОбОбновлении.Вставить("ВремяНачалаОтложенногоОбновления");
	СведенияОбОбновлении.Вставить("ВремяОкончаниеОтложенногоОбновления");
	СведенияОбОбновлении.Вставить("НомерСеанса", Новый СписокЗначений());
	СведенияОбОбновлении.Вставить("ОтложенноеОбновлениеЗавершеноУспешно");
	СведенияОбОбновлении.Вставить("ВыводитьОписаниеОбновлений", Ложь);
	СведенияОбОбновлении.Вставить("ПриостановленныеПроцедурыОбновления", Новый Массив);
	СведенияОбОбновлении.Вставить("ЗапущенныеПроцедурыОбновления", Новый Массив);
	Если СведенияОбОбновлении.УправлениеОтложеннымОбновлением.Свойство("ФорсироватьОбновление") Тогда
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура СброситьСведенияОбОбновлении(СведенияОбОбновлении)
	Если Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		Возврат;
	КонецЕсли;

	НовыеСведенияОбОбновлении = НовыеСведенияОбОбновлении();

	Константы.ОтложенноеОбновлениеЗавершеноУспешно.Установить(Ложь);

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

	СведенияОбОбновлении.Вставить("ДлительностьЭтаповОбновления", НовыеСведенияОбОбновлении.ДлительностьЭтаповОбновления);

	ЗаписатьСведенияОбОбновленииИнформационнойБазы(СведенияОбОбновлении);

	ЗаписатьСведенияОБлокируемыхОбъектах(НовыеСведенияОБлокируемыхОбъектах());
КонецПроцедуры

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

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

		ЗаписатьОшибку(ТекстОшибки);
		ТекстОшибок = ТекстОшибок + ТекстОшибки + Символы.ПС;
	КонецЕсли;

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

	Если РежимВыполненияОтложенныхОбработчиков = "Параллельно" И Обработчик.ЗапускатьТолькоВГлавномУзле
		И Обработчик.ЗапускатьИВПодчиненномУзлеРИБСФильтрами Тогда

		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'У отложенного обработчика ""%1""
			|некорректно заполнены значения свойств:
			| - ""%2""
			| - ""%3"".
			|
			|Данные свойства не могут одновременно принимать значение ""Истина"".'"),
			Обработчик.ИмяОбработчика,
			"ЗапускатьТолькоВГлавномУзле",
			"ЗапускатьИВПодчиненномУзлеРИБСФильтрами");
		ЗаписатьОшибку(ТекстОшибки);
		ТекстОшибок = ТекстОшибок + ТекстОшибки + Символы.ПС;
	КонецЕсли;

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

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

Процедура ПроверитьУникальностьИдентификаторовОтложенныхОбработчиков(ИтерацииОбновления)

	Если Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		Возврат;
	КонецЕсли;

	ТаблицаПроверкиУникальности = Новый ТаблицаЗначений;
	ТаблицаПроверкиУникальности.Колонки.Добавить("Идентификатор");
	ТаблицаПроверкиУникальности.Колонки.Добавить("Индекс");

	Для Каждого ИтерацияОбновления Из ИтерацииОбновления Цикл

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

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

	КонецЦикла;

	ИсходноеКоличествоСтрок = ТаблицаПроверкиУникальности.Количество();
	ТаблицаПроверкиУникальности.Свернуть("Идентификатор", "Индекс");
	ИтоговоеКоличествоСтрок = ТаблицаПроверкиУникальности.Количество();

	// Быстрая проверка.
	Если ИсходноеКоличествоСтрок = ИтоговоеКоличествоСтрок Тогда
		Возврат; // Все идентификаторы уникальны.
	КонецЕсли;

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

	ВызватьИсключение ТекстСообщения;

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


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `НовоеОписаниеГруппыПотоков`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Функция НовоеОписаниеГруппыПотоков()
Описание = Новый Структура;
	Описание.Вставить("Процедура");
	Описание.Вставить("ПроцедураЗавершения");
	Описание.Вставить("ПриАварийномЗавершении");
    // TODO: допиши оставшуюся часть

[Assistant]
Функция НовоеОписаниеГруппыПотоков()

	Описание = Новый Структура;
	Описание.Вставить("Процедура");
	Описание.Вставить("ПроцедураЗавершения");
	Описание.Вставить("ПриАварийномЗавершении");
	Описание.Вставить("ПриОтменеПотока");

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

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

// Описание группы потоков.
//
// Возвращаемое значение:
//  ТаблицаЗначений:
//     * Группы - Соответствие из КлючИЗначение - описание групп потоков, где:
//       ** Ключ - Строка - имя группы.
//       ** Значение - см. НовоеОписаниеГруппыПотоков
//     * Потоки - ТаблицаЗначений - описание потоков со следующими колонками:
//       ** Наименование - Строка - произвольное наименование потока (используется в наименовании фонового задания).
//       ** Группа - Строка - имя группы с описанием потока.
//       ** ИдентификаторЗадания - УникальныйИдентификатор - уникальный идентификатор фонового задания.
//       ** ПараметрыПроцедуры - Произвольный - параметры для Процедура.
//       ** ПараметрыПроцедурыЗавершения - Произвольный - параметры для ПроцедураЗавершения.
//       ** АдресРезультата - Строка - адрес временного хранилища для сохранения результата выполнения фонового задания.
//

Функция НовоеОписаниеПотоков()

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

	Возврат Потоки;

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

// Ожидать завершение потока в течение указанной длительности.
//
// Параметры:
//   Поток - СтрокаТаблицыЗначений из см. НовоеОписаниеПотоков
//   Длительность - Число - максимальная длительность ожидания в секундах.
//
// Возвращаемое значение:
//  Булево - Истина - поток выполнен, Ложь - поток еще выполняется.
//

Функция ОжидатьЗавершениеПотока(Поток, Длительность = 1)

	Если ЗначениеЗаполнено(Поток.ИдентификаторЗадания) Тогда
		Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(Поток.ИдентификаторЗадания);

		Если Задание <> Неопределено Тогда
			Задание = Задание.ОжидатьЗавершенияВыполнения(Длительность);
			ЗаданиеЗавершено = (Задание.Состояние <> СостояниеФоновогоЗадания.Активно);
			Возврат ЗаданиеЗавершено;
		КонецЕсли;
	КонецЕсли;

	Возврат Истина;

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

////////////////////////////////////////////////////////////////////////////////
// Механизм многопоточного выполнения обработчика обновления.

// Найти порцию данных для потока обработчика обновления.
//
// Параметры:
//  ПараметрыПоиска - см. НовыеПараметрыПоискаПорции
//  АдресРезультата - Строка - адрес результата выполнения процедуры. Возвращается таблица значений.
//

Процедура НайтиПорциюДляОбновления(ПараметрыПоиска, АдресРезультата) Экспорт

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

	Если Не ПоискСНачала Тогда
		СледующиеПараметрыОбхода(ПараметрыОбхода, Ложь);
	КонецЕсли;

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

	Пока ИтераторОбхода <> Неопределено Цикл
		СсылочныйОбъект = ИтераторОбхода.СсылочныйОбъект;
		ТабличныйОбъект = ИтераторОбхода.ТабличныйОбъект;
		УстановитьГраницуНачалаВыборки(ПараметрыПоиска, ИтераторОбхода.СсылочныйИндекс, ИтераторОбхода.ТабличныйИндекс);
		УстановитьГраницуКонцаВыборки(ПараметрыПоиска, СсылочныйОбъект, ТабличныйОбъект);
		МаксимумВыборки = ПараметрыВыборки.МаксимумВыборки;
		ПараметрыВыборки.ДополнительныеИсточникиДанных = ОбновлениеИнформационнойБазы.ИсточникиДанных(
			ДополнительныеИсточникиДанных,
			СсылочныйОбъект,
			ТабличныйОбъект);

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

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

		Количество = Данные.Количество();
		РезультатПоиска.Количество = РезультатПоиска.Количество + Количество;
		ПараметрыВыборки.МаксимумВыборки = ПараметрыВыборки.МаксимумВыборки - Количество;

		Если Количество > 0 Тогда
			ЗаписьНабора = НаборДанных.Добавить();
			ЗаписьНабора.СсылочныйОбъект = СсылочныйОбъект;
			ЗаписьНабора.ТабличныйОбъект = ТабличныйОбъект;
			ЗаписьНабора.Данные = Данные;
		КонецЕсли;

		Если РезультатПоиска.Количество < Максимум Тогда
			СледующиеПараметрыОбхода(ПараметрыОбхода, Количество = МаксимумВыборки);
			ИтераторОбхода = ТекущиеПараметрыОбхода(ПараметрыОбхода);
		Иначе
			Прервать;
		КонецЕсли;
	КонецЦикла;

	ПараметрыВыборки.ДополнительныеИсточникиДанных = ДополнительныеИсточникиДанных;
	РезультатПоиска.ПоискЗавершен = (ИтераторОбхода = Неопределено);
	ПоместитьВоВременноеХранилище(РезультатПоиска, АдресРезультата);

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

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


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `УстановитьОтборВТекстЗапроса`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура УстановитьОтборВТекстЗапроса(ОписаниеПолей, ТекстЗапроса, Запрос, ПрефиксИмениПараметра)
Отбор = "";
	СоединенияОтбора = "";

	Для Каждого ОписаниеПоля Из ОписаниеПолей Цикл
		ОчищаемыеТипы = Новый Соответствие;
		ОчищаемыеЗначения = Новый Соответствие;
		Для Каждого ОписаниеТипа Из ОписаниеПоля.Значение Цикл
			Если ТипЗнч(ОписаниеТипа.Значение) = Тип("Массив") Тогда
				ОчищаемыеЗначения.Вставить(ОписаниеТипа.Ключ, ОписаниеТипа.Значение);
			Иначе
				ОчищаемыеТипы.Вставить(ОписаниеТипа.Ключ, ОписаниеТипа.Значение);
			КонецЕсли;
		КонецЦикла;

		Если ОписаниеПоля.Значение.Количество() > 100
		   И ЗначениеЗаполнено(ОчищаемыеТипы) Тогда

			ИмяПараметра = ПрефиксИмениПараметра + ОписаниеПоля.Ключ;
			ТекстЗапросаВременнойТаблицы =
			"ВЫБРАТЬ
			|	ТекущаяТаблица.ПустаяСсылка КАК ПустаяСсылка
			|ПОМЕСТИТЬ ВременнаяТаблица
			|ИЗ
			|	&ВременнаяТаблица КАК ТекущаяТаблица
			|
			|ИНДЕКСИРОВАТЬ ПО
			|	ПустаяСсылка";
			ТекстЗапросаВременнойТаблицы = СтрЗаменить(ТекстЗапросаВременнойТаблицы,
				"ВременнаяТаблица", ИмяПараметра);
			Запрос.Текст = ТекстЗапросаВременнойТаблицы
				+ ОбщегоНазначения.РазделительПакетаЗапросов() + Запрос.Текст;
			СоединенияОтбора = СоединенияОтбора + ?(СоединенияОтбора = "", "", Символы.ПС);
			СоединенияОтбора = СоединенияОтбора + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			"		ЛЕВОЕ СОЕДИНЕНИЕ %1 КАК %1
			|		ПО (ТИПЗНАЧЕНИЯ(%1.ПустаяСсылка) = ТИПЗНАЧЕНИЯ(ТекущаяТаблица.%2))
			|", ИмяПараметра, ОписаниеПоля.Ключ);
			Отбор = Отбор + ?(Отбор = "", "", "
			|	ИЛИ ");
			Отбор = Отбор + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				"НЕ %1.ПустаяСсылка ЕСТЬ NULL", ИмяПараметра);
			ПустыеСсылки = Новый Массив;
			ТипыСсылок = Новый Массив;
			Для Каждого ОписаниеТипа Из ОчищаемыеТипы Цикл
				ПустыеСсылки.Добавить(ПредопределенноеЗначение(ОписаниеТипа.Значение + ".ПустаяСсылка"));
				ТипыСсылок.Добавить(ОписаниеТипа.Ключ);
			КонецЦикла;
			ЗначениеПараметра = Новый ТаблицаЗначений;
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура УстановитьОтборВТекстЗапроса(ОписаниеПолей, ТекстЗапроса, Запрос, ПрефиксИмениПараметра)

	Отбор = "";
	СоединенияОтбора = "";

	Для Каждого ОписаниеПоля Из ОписаниеПолей Цикл
		ОчищаемыеТипы = Новый Соответствие;
		ОчищаемыеЗначения = Новый Соответствие;
		Для Каждого ОписаниеТипа Из ОписаниеПоля.Значение Цикл
			Если ТипЗнч(ОписаниеТипа.Значение) = Тип("Массив") Тогда
				ОчищаемыеЗначения.Вставить(ОписаниеТипа.Ключ, ОписаниеТипа.Значение);
			Иначе
				ОчищаемыеТипы.Вставить(ОписаниеТипа.Ключ, ОписаниеТипа.Значение);
			КонецЕсли;
		КонецЦикла;

		Если ОписаниеПоля.Значение.Количество() > 100
		   И ЗначениеЗаполнено(ОчищаемыеТипы) Тогда

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

	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&Отбор", Отбор);
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ГДЕ", СоединенияОтбора + "ГДЕ");

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

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