



&НаКлиенте
Процедура ПриОткрытии(Отказ)
	ЗаполнитьСписокПлановОбмена();
	ЗагрузитьНастройкиПланОбмена();
	УстановитьЗначениеПланаОбмена();

	ЗагрузитьНастройкиУзелОбмена();
	ПоказатьАтрибутыУзлаОбмена();
	АктивироватьЭлементыПриВыбореУзлаОбмена();

	ПредложитьВключитьОбъектыВODATA();
КонецПроцедуры


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


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

&НаСервере
Функция ПроверитьЧтоПланОбменаСуществует(ИмяПлана)
    Если ПустаяСтрока(ИмяПлана) Тогда
        Возврат Ложь;
    КонецЕсли;
	Возврат ПланыОбмена[ИмяПлана] <> Неопределено; 
КонецФункции

&НаКлиенте
Процедура ИмяПланаОбменаПриИзменении(Элемент)
   УстановитьЗначениеПланаОбмена();
   СохранитьНастройки();
   ПредложитьВключитьОбъектыВODATA();
КонецПроцедуры

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


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

	Если ПустаяСтрока(ИмяПланаОбмена) Тогда
        Состояние("Сначала выберите план обмена!");
        СтандартнаяОбработка = Ложь;
        Возврат;
    КонецЕсли;

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


// Без директивы — доступна и на клиенте, и на сервере. УзелОбмена может быть Неопределено
// (план не выбран/не существует), поэтому проверяем это перед вызовом метода Пустая().
Функция УзелПустой()
	Возврат УзелОбмена = Неопределено ИЛИ УзелОбмена.Пустая();
КонецФункции

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


	
&НаСервереБезКонтекста
Функция ПолучитьЭтотУзелНаСервере(ИмяПлана)
    Возврат ПланыОбмена[ИмяПлана].ЭтотУзел();
КонецФункции





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

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


&НаСервере
Процедура СохранитьНастройки()
	КлючОбъекта = "ВыгрузкаИзмененийПоODATA";
    КлючНастроек = "ОсновныеНастройки";
    
    Настройки = Новый Структура;
    Настройки.Вставить("ИмяПланаОбмена", ИмяПланаОбмена);
    Настройки.Вставить("УзелОбмена", УзелОбмена);
    
    ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, КлючНастроек, Настройки);

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

&НаКлиенте
Процедура УзелОбменаОбработкаВыбора(Элемент, ВыбранноеЗначение, ДополнительныеДанные, ВыборДобавлением, СтандартнаяОбработка)
		
	Если ВыбранноеЗначение = ПолучитьЭтотУзелНаСервере(ИмяПланаОбмена) Тогда
		СтандартнаяОбработка = Ложь;
		УзелОбмена = ПредопределенноеЗначение("ПланОбмена." + ИмяПланаОбмена + ".ПустаяСсылка");
		ПоказатьПредупреждение(, "Нельзя выбирать текущую базу (""Этот узел""). 
							|Пожалуйста, выберите узел базы-корреспондента.");
		
		
	КонецЕсли;
	ПоказатьАтрибутыУзлаОбмена();
	
КонецПроцедуры

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

&НаКлиенте
Процедура УзелОбменаПриИзменении(Элемент)
	ПоказатьАтрибутыУзлаОбмена();
	АктивироватьЭлементыПриВыбореУзлаОбмена();
	СохранитьНастройки();
КонецПроцедуры

&НаКлиенте
Процедура Обновить(Команда)
	ПоказатьАтрибутыУзлаОбмена();
	ЗаполнитьСтатистикуИзмененийНаСервере();

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


&НаСервере
Процедура ЗаполнитьСтатистикуИзмененийНаСервере()
	
	ТаблицаСтатистики.Очистить();

	Если УзелПустой() Тогда
		Возврат;
	КонецЕсли;

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

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

		ПолноеИмяМетаданного = ЭлементСостава.Метаданные.ПолноеИмя();

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

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

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


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

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

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

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

	ТаблицаИзменений.ТекстЗапроса = ТекстЗапроса;
	ТаблицаИзменений.Параметры.УстановитьЗначениеПараметра("Узел", Узел);
	
КонецПроцедуры


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


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

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

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

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

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

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


&НаСервере
Процедура ПолнаяОчисткаВсехИзмененийНаСервере()
	ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, );
КонецПроцедуры


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






&НаСервере
Процедура ВключитьПланИЕгоОбъктыВODATAНаСервере()

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

	СоставOData = ПолучитьСоставСтандартногоИнтерфейсаOData();
	ЕстьИзменения = Ложь;

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

	Для Каждого ЭлементСостава Из ОбъектМетаданныхПлана.Состав Цикл
		ОбъектМетаданных = ЭлементСостава.Метаданные;
		ПолноеИмяМетаданного = ОбъектМетаданных.ПолноеИмя();

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

	// Состав OData устанавливаем один раз после сбора всех изменений: операция дорогая,
	// она переопределяет весь стандартный интерфейс OData целиком.
	Если ЕстьИзменения Тогда
		УстановитьСоставСтандартногоИнтерфейсаOData(СоставOData);
	КонецЕсли;

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

&НаКлиенте
Процедура ВключитьПланИЕгоОбъктыВODATA(Команда)
	ВключитьПланИЕгоОбъктыВODATAНаСервере();
КонецПроцедуры


&НаСервере
Функция ПолучитьЧислоОбъектовВнеODATA()
	// Сколько объектов плана обмена (включая сам план) ещё НЕ включено в состав стандартного
	// интерфейса OData. 0 — всё включено. Используется для предупреждения пользователю.
	ОбъектМетаданныхПлана = Метаданные.ПланыОбмена.Найти(ИмяПланаОбмена);
	Если ОбъектМетаданныхПлана = Неопределено Тогда
		Возврат 0;
	КонецЕсли;

	СоставOData = ПолучитьСоставСтандартногоИнтерфейсаOData();
	Количество = 0;

	Если СоставOData.Найти(ОбъектМетаданныхПлана) = Неопределено Тогда
		Количество = Количество + 1;
	КонецЕсли;

	Для Каждого ЭлементСостава Из ОбъектМетаданныхПлана.Состав Цикл
		Если СоставOData.Найти(ЭлементСостава.Метаданные) = Неопределено Тогда
			Количество = Количество + 1;
		КонецЕсли;
	КонецЦикла;

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


&НаКлиенте
Процедура ПредложитьВключитьОбъектыВODATA()
	// Если не все объекты плана включены в OData — предупреждаем и предлагаем включить (Да/Нет).
	Если ПустаяСтрока(ИмяПланаОбмена) Тогда
		Возврат;
	КонецЕсли;

	ЧислоВне = ПолучитьЧислоОбъектовВнеODATA();
	Если ЧислоВне = 0 Тогда
		Возврат;
	КонецЕсли;

	Текст = "Не все объекты плана обмена """ + ИмяПланаОбмена + """ включены в стандартный интерфейс OData."
		+ Символы.ПС + "Не включено объектов: " + Строка(ЧислоВне) + "."
		+ Символы.ПС + "Без этого внешний модуль cdc-1c не сможет прочитать их по OData."
		+ Символы.ПС + Символы.ПС + "Включить сейчас?";

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


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


&НаСервере
Процедура ИнициализироватьВыгрузкуВсехОбъектовНаСервере()
	// Помечает к выгрузке по нескольку записей КАЖДОГО объекта плана обмена, чтобы все объекты хотя бы
	// раз попали в SelectChanges. Внешний модуль (cdc-1c) при первом появлении объекта в пакете ставит
	// ему признак полной выгрузки (если её ещё не было) и затем выгружает объект целиком через OData.
	// Здесь регистрируем лишь небольшую выборку — это дёшево и достаточно, чтобы «объявить» объект;
	// полную перекачку всех данных через обмен не делаем (её сделает cdc-1c постранично по OData).

	Если УзелПустой() Тогда
		Сообщить("Сначала выберите узел обмена!");
		Возврат;
	КонецЕсли;

	КоличествоЗаписей = 10;
	МетаданныеПлана = Метаданные.ПланыОбмена[ИмяПланаОбмена];

	Для Каждого ЭлементСостава Из МетаданныеПлана.Состав Цикл
		ОбъектМетаданных = ЭлементСостава.Метаданные;
		ПолноеИмя = ОбъектМетаданных.ПолноеИмя();

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

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

		// Сбой по одному объекту не должен прерывать инициализацию остальных.
		Попытка
			Если ЭтоРегистрСРегистратором(ОбъектМетаданных) Тогда
				Зарегистрировано = ЗарегистрироватьЗаписиРегистра(ОбъектМетаданных, КоличествоЗаписей);
			ИначеЕсли Метаданные.Константы.Содержит(ОбъектМетаданных) Тогда
				ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, ОбъектМетаданных);
				Зарегистрировано = 1;
			Иначе
				Зарегистрировано = ЗарегистрироватьСсылочныеЗаписи(ОбъектМетаданных, КоличествоЗаписей);
			КонецЕсли;
			Сообщить("""" + ПолноеИмя + """: зарегистрировано записей — " + Строка(Зарегистрировано));
		Исключение
			Сообщить("""" + ПолноеИмя + """ — ошибка регистрации: " + ОписаниеОшибки());
		КонецПопытки;
	КонецЦикла;

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


&НаСервере
Функция ЭтоРегистрСРегистратором(ОбъектМетаданных)
	Возврат Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных)
		Или Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных)
		Или Метаданные.РегистрыРасчета.Содержит(ОбъектМетаданных)
		Или (Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных)
			И ОбъектМетаданных.РежимЗаписи <> Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.Независимый);
КонецФункции


&НаСервере
Функция ЭтоСсылочныйОбъект(ОбъектМетаданных)
	Возврат Метаданные.Справочники.Содержит(ОбъектМетаданных)
		Или Метаданные.Документы.Содержит(ОбъектМетаданных)
		Или Метаданные.ПланыСчетов.Содержит(ОбъектМетаданных)
		Или Метаданные.ПланыВидовХарактеристик.Содержит(ОбъектМетаданных)
		Или Метаданные.ПланыВидовРасчета.Содержит(ОбъектМетаданных)
		Или Метаданные.БизнесПроцессы.Содержит(ОбъектМетаданных)
		Или Метаданные.Задачи.Содержит(ОбъектМетаданных)
		Или Метаданные.ПланыОбмена.Содержит(ОбъектМетаданных);
КонецФункции


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


&НаСервере
Функция ЗарегистрироватьЗаписиРегистра(ОбъектМетаданных, КоличествоЗаписей)
	// Изменения регистра регистрируются по регистратору: берём несколько разных регистраторов
	// и регистрируем набор записей каждого. Отбора по регистратору достаточно — читать набор не нужно.
	Менеджер = ПолучитьМенеджерРегистра(ОбъектМетаданных);
	Если Менеджер = Неопределено Тогда
		Возврат 0;
	КонецЕсли;

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

	Счётчик = 0;
	Пока Выборка.Следующий() Цикл
		НаборЗаписей = Менеджер.СоздатьНаборЗаписей();
		НаборЗаписей.Отбор.Регистратор.Установить(Выборка.Регистратор);
		ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, НаборЗаписей);
		Счётчик = Счётчик + 1;
	КонецЦикла;
	Возврат Счётчик;
КонецФункции


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

	Счётчик = 0;
	Пока Выборка.Следующий() Цикл
		ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, Выборка.Ссылка);
		Счётчик = Счётчик + 1;
	КонецЦикла;
	Возврат Счётчик;
КонецФункции


&НаКлиенте
Процедура ИнициализироватьВыгрузкуВсехОбъектов(Команда)
	Состояние("Пожалуйста, подождите, идёт регистрация по нескольку записей каждого объекта...");
	ИнициализироватьВыгрузкуВсехОбъектовНаСервере();
	ЗаполнитьСтатистикуИзмененийНаСервере();
	Состояние("Завершено");
КонецПроцедуры



