///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОписаниеПеременных

&НаКлиенте
Перем ТекущийВыбранныйРеквизит;

&НаКлиенте
Перем СведенияОбОшибках;

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

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

	УстановитьУсловноеОформление();
	ДополнительнаяОбработкаСсылка = Параметры.ДополнительнаяОбработкаСсылка;

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

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
	
	ОтправитьОтчетОбОшибке();
	
КонецПроцедуры

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

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

#Область ОбработчикиСобытийЭлементовШапкиФормы

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

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

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

&НаКлиенте
Процедура СоставОбъектаПриСменеСтраницы(Элемент, ТекущаяСтраница)
	Элементы.РеквизитыСтрокаПоиска.Видимость = (ТекущаяСтраница = Элементы.Реквизиты);
КонецПроцедуры

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

&НаКлиенте
Процедура ПредставлениеИзменяемыхОбъектовАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
	ПолеВводаАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
КонецПроцедуры

&НаКлиенте
Процедура ПолеВводаАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
	ДанныеВыбора = ДанныеВыбора(Текст, Элемент.СписокВыбора);
	СтандартнаяОбработка = Не ЗначениеЗаполнено(Текст);
КонецПроцедуры

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

#Область ОбработчикиСобытийЭлементовТаблицыФормыКомпоновщикНастроекНастройкиОтбор

&НаКлиенте
Процедура ОбновитьНадписи()
	ОбновитьНадписиСервер();
КонецПроцедуры

&НаСервере
Процедура ОбновитьНадписиСервер()
	ОбновитьНадписьКоличествоВыбранных();
	СформироватьПояснениеОНастроенныхИзменениях();
	Алгоритм = ПредставлениеИзменяемыхОбъектов;
КонецПроцедуры

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

#Область ОбработчикиСобытийЭлементовТаблицыФормыОбъектыКоторыеНеУдалосьИзменить

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

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

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

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

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

#Область ОбработчикиСобытийЭлементовТаблицыФормыРеквизитыОбъекта

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

&НаКлиенте
Процедура РеквизитыОбъектаПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)
	ОписаниеРеквизита = РеквизитыОбъекта.НайтиПоИдентификатору(ПараметрыПеретаскивания.Значение[0]);
	ШаблонВставки = "[%1]";
	
	ТекстДляВставки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонВставки, ОписаниеРеквизита.Представление);
	ТекущиеДанные = РеквизитыОбъекта.НайтиПоИдентификатору(Строка);
	Если Не ПустаяСтрока(ТекущиеДанные.Значение) Тогда
		ТекстДляВставки = "+" + ТекстДляВставки;
	КонецЕсли;
	ТекущиеДанные.Значение = Строка(ТекущиеДанные.Значение) + ТекстДляВставки;
	Если Не СтрНачинаетсяС(СокрЛ(ТекущиеДанные.Значение), "=") Тогда
		ТекущиеДанные.Значение = "=" + ТекущиеДанные.Значение;
	КонецЕсли;
	ТекущиеДанные.Изменять = Истина;
КонецПроцедуры

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

&НаКлиенте
Функция ЕстьОшибкиВВыражениях()
	Результат = Ложь;
	Для Индекс = 0 По РеквизитыОбъекта.Количество() - 1 Цикл
		ОписаниеРеквизита = РеквизитыОбъекта[Индекс];
		Если ОписаниеРеквизита.Изменять И ТипЗнч(ОписаниеРеквизита.Значение) = Тип("Строка") 
			И СтрНачинаетсяС(ОписаниеРеквизита.Значение, "=") Тогда
			ТекстОшибки = "";
			Если ЕстьОшибкаВВыражении(ОписаниеРеквизита.Значение, ТекстОшибки) Тогда
				Результат = Истина;
				Сообщение = Новый СообщениеПользователю;
				Сообщение.Поле = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("РеквизитыОбъекта[%1].Значение", Формат(Индекс, "ЧГ=0"));
				Сообщение.Текст = ТекстОшибки;
				Сообщение.Сообщить();
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	Возврат Результат;
КонецФункции

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

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

#Область ОбработчикиСобытийЭлементовТаблицыФормыРеквизитыОбъектаАлгоритм

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

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

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

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

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

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

#Область ПодключаемыеОбработчики

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

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

// Параметры:
//   Команда - КомандаФормы
//
&НаКлиенте
Процедура Подключаемый_УстановитьНастройку(Команда)
	
	Если СтрНачинаетсяС(Команда.Имя, "Алгоритмы") Тогда
		МестоРазмещенияКоманд = Элементы.Алгоритмы;
		ШаблонИмениКоманды = МестоРазмещенияКоманд.Имя + "НастройкаИзменений";
		ИндексКоманды = Число(Сред(Команда.Имя, СтрДлина(ШаблонИмениКоманды) + 1));
		КодАлгоритма = ИсторияАлгоритмовСписок[ИндексКоманды].Значение;
		Алгоритм = ИсторияАлгоритмовСписок[ИндексКоманды].Представление;
		СформироватьПояснениеОНастроенныхИзменениях();
	Иначе
		МестоРазмещенияКоманд = Элементы.РанееИзмененныеРеквизиты;
		ШаблонИмениКоманды = МестоРазмещенияКоманд.Имя + "НастройкаИзменений";
		ИндексКоманды = Число(Сред(Команда.Имя, СтрДлина(ШаблонИмениКоманды) + 1));
		УстановитьНастройкуИзменения(ИсторияОперацийСписок[ИндексКоманды].Значение);
		СформироватьПояснениеОНастроенныхИзменениях();
	КонецЕсли;
	
КонецПроцедуры

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

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

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

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

&НаКлиенте
Процедура ОбновитьПояснениеОНастроенныхИзменениях()
	СформироватьПояснениеОНастроенныхИзменениях();
КонецПроцедуры

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

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

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

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

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

	//@skip-check new-color
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", Новый Цвет(192, 192, 192)); // АПК:1346 - автономная обработка не может использовать стили
	
	// Пояснения по связанным реквизитам
	
	Для Каждого Реквизит Из РеквизитыОбъекта Цикл
		Элемент = УсловноеОформление.Элементы.Добавить();
		
		ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.РеквизитыОбъектаЗначение.Имя);

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

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

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

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

&НаСервере
Функция ЕстьНастроенныеОтборы()
	Для Каждого ЭлементОтбора Из КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
		Если ЭлементОтбора.Использование Тогда
			Возврат Истина;
		КонецЕсли;
	КонецЦикла;
	Возврат Ложь;
КонецФункции

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

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

&НаСервере
Функция ЕстьНастроенныеИзменения()
	Возврат ИзменяемыеРеквизиты().Количество() > 0 Или ИзменяемыеТабличныеЧасти().Количество() > 0;
КонецФункции

&НаСервере
Процедура ДобавитьИзменениеВИсторию(СтруктураИзменения, ПредставлениеИзменения)
	
	Если Объект.ТипОперации = "ВыполнитьАлгоритм" Тогда
		Настройки = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить("ГрупповоеИзменениеОбъектов", 
			"ИсторияАлгоритмов/" + ВидыИзменяемыхОбъектов);
		
		Если Настройки = Неопределено Тогда
			Настройки = Новый Массив;
		Иначе
			Для Индекс = 0 По Настройки.ВГраница() Цикл
				Если Настройки.Получить(Индекс).Представление = ПредставлениеИзменения Тогда
					Настройки.Удалить(Индекс);
					Прервать;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
		
		Настройки.Вставить(0, Новый Структура("Изменение, Представление", СтруктураИзменения, ПредставлениеИзменения));
		
		Если Настройки.Количество() > 20 Тогда
			Настройки.Удалить(19);
		КонецЕсли;
		
		ОбщегоНазначения.ХранилищеОбщихНастроекСохранить(
			"ГрупповоеИзменениеОбъектов", "ИсторияАлгоритмов/" + ВидыИзменяемыхОбъектов, Настройки);
		
		ЗагрузитьИсториюОпераций();
		ЗаполнитьПодменюРанееИзмененныеРеквизиты();

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

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

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

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

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

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

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

&НаСервереБезКонтекста
Функция СтруктураНастроек()
	
	СтруктураНастроек = Новый Структура;
	СтруктураНастроек.Вставить("ИзменятьВТранзакции",    Ложь);
	СтруктураНастроек.Вставить("ПрерыватьПриОшибке",     Ложь);
	СтруктураНастроек.Вставить("ОбрабатыватьРекурсивно", Ложь);
	
	Возврат СтруктураНастроек;
	
КонецФункции

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

	ДоступноВыполнениеКодаВНебезопасномРежиме = ДоступноВыполнениеКодаВНебезопасномРежиме();
	Элементы.РежимВыполнения.Видимость        = ДоступноВыполнениеКодаВНебезопасномРежиме;
	
КонецПроцедуры

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

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

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

&НаСервереБезКонтекста
Функция ДоступныеПраваВыполнениеКода()
	
	Результат = Новый Структура();
	Результат.Вставить("ДоступноВыполнениеКодаВНебезопасномРежиме", ДоступноВыполнениеКодаВНебезопасномРежиме());
	Результат.Вставить("ДоступноВыполнениеКода", ДоступноВыполнениеКода());
	
	Возврат Результат;
КонецФункции

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

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

&НаКлиенте
Процедура УстановитьКнопкиНаВремяИзменения(НачалоИзменения)
	
	ВыполняетсяОбработка = НачалоИзменения;

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

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

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

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

&НаКлиенте
Процедура ОбработатьРезультатИзменения(РезультатИзменения = Неопределено, ПродолжитьОбработку = Неопределено)
	Перем КоличествоОшибок, КоличествоИзмененных;
	
	Если ПродолжитьОбработку = Неопределено Тогда
		ПродолжитьОбработку = Истина;
	КонецЕсли;
	
	Пока ПродолжитьОбработку Цикл
		ЗаполнитьСостояниеОбработанных(РезультатИзменения, КоличествоОшибок, КоличествоИзмененных);
		
		ТекущееСостояниеИзменения.КоличествоОшибок = КоличествоОшибок + ТекущееСостояниеИзменения.КоличествоОшибок;
		ТекущееСостояниеИзменения.КоличествоИзмененных = КоличествоИзмененных + ТекущееСостояниеИзменения.КоличествоИзмененных;
		
		Если НЕ (ТекущееСостояниеИзменения.ОстанавливатьИзменениеПриОшибке И РезультатИзменения.ЕстьОшибки) Тогда
			Прервать;
		КонецЕсли;
		
		// При наличии ошибок в транзакции - откатываем всю транзакцию.
		Если Объект.ИзменятьВТранзакции Тогда
			ПодключитьОбработчикОжидания("ЗавершитьИзменениеОбъектов", 0.1, Истина);
			Возврат; // Досрочный выход из цикла и процедуры.
		КонецЕсли;
		
		ТекстВопроса = НСтр("ru = 'При изменении элементов (группы элементов) возникли ошибки.
			|Прервать изменение элементов и перейти к просмотру ошибок?'");
		Кнопки = Новый СписокЗначений;
		Кнопки.Добавить(КодВозвратаДиалога.Прервать, НСтр("ru = 'Прервать'"));
		Кнопки.Добавить(КодВозвратаДиалога.Пропустить, НСтр("ru = 'Продолжить'"));
		Кнопки.Добавить(КодВозвратаДиалога.Нет, НСтр("ru = 'Больше не спрашивать'"));
		
		ОписаниеОповещения = Новый ОписаниеОповещения("ОбработатьРезультатИзмененияОтветПолучен", 
			ЭтотОбъект, РезультатИзменения);
		ПоказатьВопрос(ОписаниеОповещения, ТекстВопроса, Кнопки, , КодВозвратаДиалога.Прервать, 
			НСтр("ru = 'Ошибки при изменении элементов'"));
		Возврат;
	КонецЦикла;
	
	ТекущееСостояниеИзменения.ТекущаяПозиция = ТекущееСостояниеИзменения.ТекущаяПозиция + РезультатИзменения.СостояниеОбработки.Количество();
	
	Если ТекущееСостояниеИзменения.ПоказыватьПроцентОбработанных Тогда
		// Вычисляем текущий процент обработанных объектов.
		ТекущийПроцент = Окр(ТекущееСостояниеИзменения.ТекущаяПозиция / ТекущееСостояниеИзменения.КоличествоОбъектовДляОбработки * 100);
		Состояние(НСтр("ru = 'Обрабатываются элементы...'"), ТекущийПроцент, НСтр("ru = 'Изменение выделенных элементов'"));
	КонецЕсли;
	
	ЕстьЭлементыДляОбработки = ?(ТекущееСостояниеИзменения.ТекущаяПозиция < ТекущееСостояниеИзменения.КоличествоОбъектовДляОбработки, Истина, Ложь);
	
	Если ЕстьЭлементыДляОбработки И НЕ ТекущееСостояниеИзменения.ПрерватьИзменение Тогда
		ПодключитьОбработчикОжидания("ИзменитьПорциюОбъектов", 0.1, Истина);
	Иначе
		ПодключитьОбработчикОжидания("ЗавершитьИзменениеОбъектов", 0.1, Истина);
	КонецЕсли;

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

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

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

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

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

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

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

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

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

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

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

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

&НаСервере
Функция ИзменяемыеРеквизиты(ИмяТабличнойЧасти = "РеквизитыОбъекта")
	ТаблицаРеквизитов = ЭтотОбъект[ИмяТабличнойЧасти];
	Возврат ОбщегоНазначения.ТаблицаЗначенийВМассив(
		ТаблицаРеквизитов.Выгрузить(Новый Структура("Изменять", Истина)));
КонецФункции

&НаСервере
Функция ИзменяемыеТабличныеЧасти()
	Результат = Новый Структура;
	Для Каждого ТабличнаяЧасть Из ТабличныеЧастиОбъекта Цикл
		ИзменяемыеРеквизиты = ИзменяемыеРеквизиты(ТабличнаяЧасть.Значение);
		Если ИзменяемыеРеквизиты.Количество() > 0 Тогда
			ИмяТабличнойЧасти = Сред(ТабличнаяЧасть.Значение, СтрДлина("ТабличнаяЧасть") + 1);
			Результат.Вставить(ИмяТабличнойЧасти, ИзменяемыеРеквизиты);
		КонецЕсли;
	КонецЦикла;
	Возврат Результат;
КонецФункции

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

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

&НаСервереБезКонтекста
Функция ОбъектМетаданныхИерархический(СсылкаПервого)
	
	ВидОбъектаПоСсылке = ОбщегоНазначения.ВидОбъектаПоСсылке(СсылкаПервого);
	Возврат ((ВидОбъектаПоСсылке = "Справочник" Или ВидОбъектаПоСсылке = "ПланВидовХарактеристик") И СсылкаПервого.Метаданные().Иерархический)
	 	Или (ВидОбъектаПоСсылке = "ПланСчетов");
	
КонецФункции

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

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

&НаКлиенте
Процедура НастройкаОтбораНажатие(Элемент)
	ПерейтиКНастройкеОтбора();
КонецПроцедуры

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

&НаСервереБезКонтекста
Функция НастройкиОтбора()
	Результат = Новый Структура;
	Результат.Вставить("ОбновитьСписок", Ложь);
	Результат.Вставить("ВключитьТабличныеЧастиВВыборку", Ложь);
	Результат.Вставить("ОграничитьВыборку", Ложь);
	Возврат Результат;
КонецФункции

// Параметры:
//   НастройкиОтбора - Структура:
//     * ОграничитьВыборку - Булево
//     * ВключитьТабличныеЧастиВВыборку - Булево
//     * ОбновитьСписок - Булево
//   ТекстСообщенияОбОшибке - Строка
//
// Возвращаемое значение:
//   ДеревоЗначений:
//     * Ссылка - ЛюбаяСсылка
//
&НаСервере
Функция ВыбранныеОбъекты(НастройкиОтбора = Неопределено, ТекстСообщенияОбОшибке = "")
	
	Если НастройкиОтбора = Неопределено Тогда
		НастройкиОтбора = НастройкиОтбора();
	КонецЕсли;
	
	ОбновитьСписок = НастройкиОтбора.ОбновитьСписок;
	ВключитьТабличныеЧастиВВыборку = НастройкиОтбора.ВключитьТабличныеЧастиВВыборку;
	ОграничитьВыборку = НастройкиОтбора.ОграничитьВыборку;
	
	Если Не ОбновитьСписок И Не ОграничитьВыборку И Не ПустаяСтрока(АдресСпискаВыбранных) Тогда
		Возврат ПолучитьИзВременногоХранилища(АдресСпискаВыбранных);
	КонецЕсли;
		
	Результат = Новый ДеревоЗначений;
	
	Если Не ПустаяСтрока(ВидыИзменяемыхОбъектов) Тогда
		ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
		ТекстЗапроса = ОбработкаОбъект.ТекстЗапроса(ВидыИзменяемыхОбъектов, ОграничитьВыборку);
		СхемаКомпоновкиДанных = СхемаКомпоновкиДанных(ТекстЗапроса);
		
		КомпоновщикНастроекКомпоновкиДанных = Новый КомпоновщикНастроекКомпоновкиДанных;
		АдресСхемы = ПоместитьВоВременноеХранилище(СхемаКомпоновкиДанных, УникальныйИдентификатор);
		КомпоновщикНастроекКомпоновкиДанных.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемы));
		КомпоновщикНастроекКомпоновкиДанных.ЗагрузитьНастройки(КомпоновщикНастроек.Настройки);
		Если ВключитьТабличныеЧастиВВыборку Тогда
			УстановитьНастройкуСтруктурыВыводаРезультата(КомпоновщикНастроекКомпоновкиДанных.Настройки, ВключитьТабличныеЧастиВВыборку);
		КонецЕсли;
		
		Если ОбъектыКоторыеНеУдалосьИзменить.Количество() > 0 И Не Объект.ИзменятьВТранзакции Тогда // повтор для неизмененных
			ЭлементОтбора = КомпоновщикНастроекКомпоновкиДанных.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
			ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
			ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
			ЭлементОтбора.ПравоеЗначение = Новый СписокЗначений;
			ЭлементОтбора.ПравоеЗначение.ЗагрузитьЗначения(ОбъектыКоторыеНеУдалосьИзменить.Выгрузить().ВыгрузитьКолонку("Объект"));
		КонецЕсли;
		
		Результат = Новый ДеревоЗначений;
		КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
		Попытка
			МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных,
				КомпоновщикНастроекКомпоновкиДанных.Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
		Исключение
			ТекстСообщенияОбОшибке = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
			Возврат Результат;
		КонецПопытки;
			
		ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
		ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных);

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

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

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

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

&НаСервере
Функция СхемаКомпоновкиДанных(ТекстЗапроса)
	
	СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
	
	ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить();
	ИсточникДанных.Имя = "ИсточникДанных1";
	ИсточникДанных.ТипИсточникаДанных = "local";
	
	НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
	НаборДанных.ИсточникДанных = "ИсточникДанных1";
	НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
	НаборДанных.Запрос = ТекстЗапроса;
	НаборДанных.Имя = "НаборДанных1";
	
	Возврат СхемаКомпоновкиДанных;
	
КонецФункции

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

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

&НаСервере
Процедура ИнициализироватьНастройкиФормы()
	ИнициализироватьКомпоновщикНастроек();
	ЗагрузитьМетаданныеОбъекта();
	ЗагрузитьИсториюОпераций();
	ЗаполнитьПодменюРанееИзмененныеРеквизиты();
	ПредставлениеИзменяемыхОбъектов = ПредставлениеИзменяемыхОбъектов();
	ОбновитьНадписиСервер();
КонецПроцедуры

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

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

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

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

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

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

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

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

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

&НаСервере
Функция ФильтруемыеРеквизиты()

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

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

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

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

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

		Если СведенияОРеквизитах.НередактируемыеРеквизиты.Найти(ОписаниеТабличнойЧасти.Имя + ".*") <> Неопределено Тогда
			Продолжить;
		КонецЕсли;
		Если СведенияОРеквизитах.ФильтруемыеРеквизиты.Найти(ОписаниеТабличнойЧасти.Имя + ".*") <> Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		ДоступныеДляИзмененияРеквизиты = ДоступныеДляИзмененияРеквизиты(ОписаниеТабличнойЧасти, СведенияОРеквизитах, 
			ДоступныеТабличныеЧасти[ОписаниеТабличнойЧасти.Имя]);
		Если ДоступныеДляИзмененияРеквизиты.Количество() = 0 Тогда
			Продолжить;
		КонецЕсли;
		
		ИмяРеквизита = "ТабличнаяЧасть" + ОписаниеТабличнойЧасти.Имя;
		ТаблицаЗначений = Новый РеквизитФормы(ИмяРеквизита, Новый ОписаниеТипов("ТаблицаЗначений"), , ОписаниеТабличнойЧасти.Представление());
		НовыеРеквизитыФормы.Добавить(ТаблицаЗначений);
		
		Для Каждого ОписаниеКолонки Из КолонкиТаблиц Цикл 
			РеквизитТаблицы = Новый РеквизитФормы(ОписаниеКолонки.Имя, ОписаниеКолонки.Тип, ТаблицаЗначений.Имя, ОписаниеКолонки.Представление);
			НовыеРеквизитыФормы.Добавить(РеквизитТаблицы);
		КонецЦикла;
		
		ТаблицыОбъекта.Вставить(ИмяРеквизита, ОписаниеТабличнойЧасти);
		ТабличныеЧастиОбъекта.Добавить(ИмяРеквизита, ОписаниеТабличнойЧасти.Представление());
	КонецЦикла;
	ИзменитьРеквизиты(НовыеРеквизитыФормы);
	
	Для Каждого ТаблицаОбъекта Из ТаблицыОбъекта Цикл
		ИмяРеквизита = ТаблицаОбъекта.Ключ;
		ИмяСтраницы = "Страница" + ИмяРеквизита;
		Страница = Элементы.Добавить(ИмяСтраницы, Тип("ГруппаФормы"), Элементы.СоставОбъекта);
		Страница.Вид = ВидГруппыФормы.Страница;
		ОписаниеТабличнойЧасти = ТаблицаОбъекта.Значение;
		Страница.Заголовок = ОписаниеТабличнойЧасти.Представление();
		
		ТаблицаФормы = Элементы.Добавить(ИмяРеквизита, Тип("ТаблицаФормы"), Страница);
		ТаблицаФормы.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
		ТаблицаФормы.ПутьКДанным = ИмяРеквизита;
		ТаблицаФормы.ПоложениеКоманднойПанели = ПоложениеКоманднойПанелиЭлементаФормы.Нет;
		ТаблицаФормы.Заголовок = ОписаниеТабличнойЧасти.Представление();
		ТаблицаФормы.УстановитьДействие("ПередНачаломИзменения", "Подключаемый_ПередНачаломИзменения");
		ТаблицаФормы.ИзменятьПорядокСтрок = Ложь;
		ТаблицаФормы.ИзменятьСоставСтрок = Ложь;
		ТаблицаФормы.КартинкаСтрок = БиблиотекаКартинок.ВидыОпераций;
		ТаблицаФормы.ПутьКДаннымКартинкиСтроки = ИмяРеквизита + ".ВидОперации";
		ТаблицаФормы.Высота = 5;
		
		Для Каждого ОписаниеКолонки Из КолонкиТаблиц Цикл 
			Если ОписаниеКолонки.ВидПоля = Неопределено Тогда
				Продолжить;
			КонецЕсли;
			ИмяРеквизита = ОписаниеКолонки.Имя;
			ИмяЭлемента = ТаблицаФормы.Имя + ИмяРеквизита;
			КолонкаТаблицы = Элементы.Добавить(ИмяЭлемента, Тип("ПолеФормы"), ТаблицаФормы);
			Если ОписаниеКолонки.Картинка <> Неопределено Тогда
				КолонкаТаблицы.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
				КолонкаТаблицы.КартинкаШапки = ОписаниеКолонки.Картинка;
			КонецЕсли;
			КолонкаТаблицы.ПутьКДанным = ТаблицаОбъекта.Ключ + "." + ИмяРеквизита;
			КолонкаТаблицы.Вид = ОписаниеКолонки.ВидПоля;
			КолонкаТаблицы.РежимРедактирования = РежимРедактированияКолонки.ВходПриВводе;
			КолонкаТаблицы.ТолькоПросмотр = ОписаниеКолонки.ТолькоПросмотр;
			Если ОписаниеКолонки.Действия <> Неопределено Тогда
				Для Каждого Действие Из ОписаниеКолонки.Действия Цикл
					КолонкаТаблицы.УстановитьДействие(Действие.Ключ, Действие.Значение);
				КонецЦикла;
			КонецЕсли;
		КонецЦикла;
		
		ДоступныеДляИзмененияРеквизиты = ДоступныеДляИзмененияРеквизиты(ОписаниеТабличнойЧасти, СведенияОРеквизитах,
			ДоступныеТабличныеЧасти[ОписаниеТабличнойЧасти.Имя]);	
		Для Каждого ОписаниеРеквизита Из ДоступныеДляИзмененияРеквизиты Цикл
			ДанныеФормыТаблица = ЭтотОбъект[ТаблицаОбъекта.Ключ]; // см. ОписанияКолонокТаблицыРеквизитов
			Реквизит = ДанныеФормыТаблица.Добавить();
			Реквизит.Имя = ОписаниеРеквизита.Имя;
			Реквизит.Представление = ?(ПустаяСтрока(ОписаниеРеквизита.Представление()), ОписаниеРеквизита.Имя, 
				ОписаниеРеквизита.Представление());
			Реквизит.ДопустимыеТипы = ОписаниеРеквизита.Тип;
			Реквизит.СвязиПараметровВыбора = СвязиПараметровВыбораСтрокой(ОписаниеРеквизита.СвязиПараметровВыбора);
			Реквизит.ПараметрыВыбора = ПараметрыВыбораСтрокой(ОписаниеРеквизита.ПараметрыВыбора);
			Реквизит.ВидОперации = 1;
			Реквизит.ПредставлениеСвязейПараметровВыбора = ПредставлениеСвязейПараметровВыбора(
				ОписаниеРеквизита.СвязиПараметровВыбора, ОбъектМетаданных);
		КонецЦикла;
	КонецЦикла;
	
КонецПроцедуры

// Параметры:
//   ОписаниеТабличнойЧасти - Структура:
//     * Реквизиты - Массив из ОбъектМетаданныхРеквизит
//   СведенияОРеквизитах - Структура
//   ДоступныеРеквизиты - Массив
//
// Возвращаемое значение:
//   Массив из ОбъектМетаданныхРеквизит
//
&НаСервере
Функция ДоступныеДляИзмененияРеквизиты(ОписаниеТабличнойЧасти, СведенияОРеквизитах, ДоступныеРеквизиты)
	
	Результат = Новый Массив;
	
	Для Каждого ОписаниеРеквизита Из ОписаниеТабличнойЧасти.Реквизиты Цикл
		Если ДоступныеРеквизиты.Найти(ОписаниеРеквизита.Имя) = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если Не ПравоДоступа("Редактирование", ОписаниеРеквизита) Тогда
			Продолжить;
		КонецЕсли;
		
		Если СведенияОРеквизитах.НередактируемыеРеквизиты.Найти(ОписаниеТабличнойЧасти.Имя + "." + ОписаниеРеквизита.Имя) <> Неопределено Тогда
			Продолжить;
		КонецЕсли;
		Если СведенияОРеквизитах.ФильтруемыеРеквизиты.Найти(ОписаниеТабличнойЧасти.Имя + "." + ОписаниеРеквизита.Имя) <> Неопределено Тогда
			Продолжить;
		КонецЕсли;
		Если ЭтоИсключаемыйТипРеквизита(ОписаниеРеквизита, СведенияОРеквизитах.ИсключаемыеТипыРеквизитов) Тогда
			Продолжить;	
		КонецЕсли;
		
		Результат.Добавить(ОписаниеРеквизита);
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

// Возвращаемое значение:
//   ТаблицаЗначений:
//   * Имя - Строка
//   * Тип - Строка
//   * Представление - Строка 
//   * ВидПоля - Строка
//   * Действия - Структура:
//     ** ПриИзменении - Булево
//     ** Подключаемый_ПриИзмененииФлажка - Булево
//   * ТолькоПросмотр - Булево
//   * Картинка - Картинка
//
&НаСервере
Функция ОписанияКолонокТаблицыРеквизитов()
	
	КолонкиТаблиц = Новый ТаблицаЗначений;
	КолонкиТаблиц.Колонки.Добавить("Имя");
	КолонкиТаблиц.Колонки.Добавить("Тип");
	КолонкиТаблиц.Колонки.Добавить("Представление");
	КолонкиТаблиц.Колонки.Добавить("ВидПоля");
	КолонкиТаблиц.Колонки.Добавить("Действия");
	КолонкиТаблиц.Колонки.Добавить("ТолькоПросмотр", Новый ОписаниеТипов("Булево"));
	КолонкиТаблиц.Колонки.Добавить("Картинка");
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "Имя";
	ОписаниеКолонки.Тип = Новый ОписаниеТипов("Строка");
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "Представление";
	ОписаниеКолонки.Тип = Новый ОписаниеТипов("Строка");
	ОписаниеКолонки.Представление = НСтр("ru = 'Реквизит'");
	ОписаниеКолонки.ВидПоля = ВидПоляФормы.ПолеВвода;
	ОписаниеКолонки.ТолькоПросмотр = Истина;
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "Изменять";
	ОписаниеКолонки.Тип = Новый ОписаниеТипов("Булево");
	ОписаниеКолонки.ВидПоля = ВидПоляФормы.ПолеФлажка;
	ОписаниеКолонки.Картинка = БиблиотекаКартинок.Изменить;
	ОписаниеКолонки.Действия = Новый Структура("ПриИзменении", "Подключаемый_ПриИзмененииФлажка");
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "Значение";
	ОписаниеКолонки.Тип = ВсеТипы();
	ОписаниеКолонки.Представление = НСтр("ru = 'Новое значение'");
	ОписаниеКолонки.ВидПоля = ВидПоляФормы.ПолеВвода;
	ОписаниеКолонки.Действия = Новый Структура("ПриИзменении", "Подключаемый_ЗначениеПриИзменении");
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "ДопустимыеТипы";
	ОписаниеКолонки.Тип = Новый ОписаниеТипов("ОписаниеТипов");
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "СвязиПараметровВыбора";
	ОписаниеКолонки.Тип = Новый ОписаниеТипов("Строка");
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "ПараметрыВыбора";
	ОписаниеКолонки.Тип = Новый ОписаниеТипов("Строка");
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "ВидОперации";
	ОписаниеКолонки.Тип = Новый ОписаниеТипов("Число");
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "Свойство";
	ОписаниеКолонки.Тип = Новый ОписаниеТипов("Строка");
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "ВыборГруппИЭлементов";
	ОписаниеКолонки.Тип = Новый ОписаниеТипов("Строка");
	
	ОписаниеКолонки = КолонкиТаблиц.Добавить();
	ОписаниеКолонки.Имя = "ПредставлениеСвязейПараметровВыбора";
	ОписаниеКолонки.Тип = Новый ОписаниеТипов("Строка");
	
	Возврат КолонкиТаблиц;
	
КонецФункции

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

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

&НаКлиенте
Процедура ОбновитьСчетчикиИзменяемыхРеквизитов(Знач ТаблицаФормы = Неопределено)
	
	СписокТаблиц = Новый Массив;
	Если ТаблицаФормы <> Неопределено Тогда
		СписокТаблиц.Добавить(ТаблицаФормы);
	Иначе
		СписокТаблиц.Добавить(Элементы.РеквизитыОбъекта);
		Для Каждого ТабличнаяЧасть Из ТабличныеЧастиОбъекта Цикл
			СписокТаблиц.Добавить(Элементы[ТабличнаяЧасть.Значение]);
		КонецЦикла;
	КонецЕсли;
	
	Для Каждого ТаблицаФормы Из СписокТаблиц Цикл
		ТабличнаяЧасть = ЭтотОбъект[ТаблицаФормы.Имя];
		КоличествоИзменяемых = 0;
		Для Каждого Реквизит Из ТабличнаяЧасть Цикл
			Если Реквизит.Изменять Тогда
				КоличествоИзменяемых = КоличествоИзменяемых + 1;
			КонецЕсли;
		КонецЦикла;
	
		Страница = ТаблицаФормы.Родитель;// ГруппаФормы
		Страница.Заголовок = ТаблицаФормы.Заголовок + ?(КоличествоИзменяемых = 0, "", " (" + КоличествоИзменяемых+ ")");
	КонецЦикла;
	
КонецПроцедуры

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

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

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

&НаСервере
Процедура ДобавитьДополнительныеРеквизитыИСведенияВНабор()
	
	ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
	
	СписокВидовИзменяемыхОбъектов = СтрРазделить(ВидыИзменяемыхОбъектов, ",", Ложь);
	ОбщийСписокРеквизитов = СписокСвойствДляВидаОбъектов(СписокВидовИзменяемыхОбъектов[0]);
	Для Индекс = 1 По СписокВидовИзменяемыхОбъектов.Количество() - 1 Цикл
		ОбщийСписокРеквизитов = ОбработкаОбъект.ПересечениеМножеств(ОбщийСписокРеквизитов, СписокСвойствДляВидаОбъектов(СписокВидовИзменяемыхОбъектов[Индекс]));
	КонецЦикла;
	
	ДобавляемыеСвойства = Новый Массив;
	
	Если КонтекстныйВызов Тогда
		НастройкиОтбора = НастройкиОтбора();
		НастройкиОтбора.ОбновитьСписок = Истина;
		ВыбранныеОбъекты = ВыбранныеОбъекты(НастройкиОтбора).Строки;
		Для Каждого ДанныеОбъекта Из ВыбранныеОбъекты Цикл
			ОбъектДляИзменения = ДанныеОбъекта.Ссылка;
			
			ВидОбъектаПоСсылке = ОбщегоНазначения.ВидОбъектаПоСсылке(ОбъектДляИзменения);
			Если (ВидОбъектаПоСсылке = "Справочник" ИЛИ ВидОбъектаПоСсылке = "ПланВидовХарактеристик")
				И ОбщегоНазначения.ОбъектЯвляетсяГруппой(ОбъектДляИзменения) Тогда
				Продолжить;
			КонецЕсли;
			
			МодульУправлениеСвойствами = ОбщегоНазначения.ОбщийМодуль("УправлениеСвойствами");
			СписокСвойств = МодульУправлениеСвойствами.СвойстваОбъекта(ОбъектДляИзменения);
			Для Каждого Свойство Из СписокСвойств Цикл
				Если ОбщийСписокРеквизитов.Найти(Свойство) = Неопределено Тогда
					Продолжить;
				КонецЕсли;
				
				Если ДобавляемыеСвойства.Найти(Свойство) <> Неопределено Тогда
					Продолжить;
				КонецЕсли;
				
				ДобавляемыеСвойства.Добавить(Свойство);
			КонецЦикла;
		КонецЦикла;
	Иначе
		ДобавляемыеСвойства = ОбщийСписокРеквизитов;
	КонецЕсли;
	
	ДобавитьСвойстваВСписокРеквизитов(ДобавляемыеСвойства);
	РеквизитыОбъекта.Сортировать("Представление");
	
КонецПроцедуры

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

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

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

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

&НаСервере
Функция ЭтоИсключаемыйТипРеквизита(ОписаниеРеквизита, ИсключаемыеТипыРеквизитов)

	Если ИсключаемыеТипыРеквизитов = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;

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

&НаСервере
Функция ФильтрРеквизитов()

	Результат = Новый ТаблицаЗначений;
	Результат.Колонки.Добавить("ТипОбъекта", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(80)));
	Результат.Колонки.Добавить("Реквизит", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(80)));
	
	// Все объекты.
	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "*";
	Фильтр.Реквизит = "Наименование";

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "*";
	Фильтр.Реквизит = "ПометкаУдаления";

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "*";
	Фильтр.Реквизит = "Ссылка";

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "*";
	Фильтр.Реквизит = "ДополнительныеРеквизиты.*";

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "*";
	Фильтр.Реквизит = "КонтактнаяИнформация.*";

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

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "Справочники";
	Фильтр.Реквизит = "Код";

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "Справочники";
	Фильтр.Реквизит = "Предопределенный";

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "Справочники";
	Фильтр.Реквизит = "ЭтоГруппа";

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "Справочники";
	Фильтр.Реквизит = "РеквизитДопУпорядочивания";
	
	// Документы.
	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "Документы";
	Фильтр.Реквизит = "Номер";

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

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "ПланыСчетов";
	Фильтр.Реквизит = "Код";

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "ПланыСчетов";
	Фильтр.Реквизит = "Предопределенный";

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "ПланыСчетов";
	Фильтр.Реквизит = "Порядок";

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

	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "БизнесПроцессы";
	Фильтр.Реквизит = "Дата";
	
	// Планы обмена.
	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "ПланыОбмена";
	Фильтр.Реквизит = "Код";
	
	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "ПланыОбмена";
	Фильтр.Реквизит = "НомерОтправленного";
	
	Фильтр = Результат.Добавить();
	Фильтр.ТипОбъекта = "ПланыОбмена";
	Фильтр.Реквизит = "НомерПринятого";
	
	Результат.Индексы.Добавить("ТипОбъекта");
	
	Возврат Результат;
КонецФункции
	
// Параметры:
//   ОбъектМетаданных - ОбъектМетаданных
// 
// Возвращаемое значение:
//   Соответствие
//
&НаСервере
Функция ФильтрРедактированияПоТипу(ОбъектМетаданных)
	
	ФильтрТаблица = ФильтрРеквизитов();
	
	// Реквизиты, блокируемые для любого типа объектов метаданных.
	ОбщийФильтр = ФильтрТаблица.НайтиСтроки(Новый Структура("ТипОбъекта", "*"));
	
	// Реквизиты, блокируемые для указанного типа объектов метаданных.
	ФильтрПоТипуОбъекта = ФильтрТаблица.НайтиСтроки(Новый Структура("ТипОбъекта", 
		ОбщегоНазначения.ИмяБазовогоТипаПоОбъектуМетаданных(ОбъектМетаданных)));
	
	ФильтруемыеРеквизиты = Новый Соответствие;
	
	Для Каждого СтрокаОписание Из ОбщийФильтр Цикл
		ФильтруемыеРеквизиты[СтрокаОписание.Реквизит] = Истина;
	КонецЦикла;
	
	Для Каждого СтрокаОписание Из ФильтрПоТипуОбъекта Цикл
		ФильтруемыеРеквизиты[СтрокаОписание.Реквизит] = Истина;
	КонецЦикла;
	
	ПрефиксУдаляемыхРеквизитов = "Удалить";
	ОписаниеРеквизитов = ОбъектМетаданных.Реквизиты; // Массив из ОбъектМетаданныхРеквизит
	Для Каждого Реквизит Из ОписаниеРеквизитов Цикл
		Если НРег(Лев(Реквизит.Имя, СтрДлина(ПрефиксУдаляемыхРеквизитов))) = НРег(ПрефиксУдаляемыхРеквизитов) Тогда
			ФильтруемыеРеквизиты[Реквизит.Имя] = Истина;
		КонецЕсли;
	КонецЦикла;
	Для Каждого ТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
		Если НРег(Лев(ТабличнаяЧасть.Имя, СтрДлина(ПрефиксУдаляемыхРеквизитов))) = НРег(ПрефиксУдаляемыхРеквизитов) Тогда
			ФильтруемыеРеквизиты[ТабличнаяЧасть.Имя + ".*"] = Истина;
		Иначе
			ОписаниеРеквизитовТабличнойЧасти = ТабличнаяЧасть.Реквизиты; // Массив из ОбъектМетаданныхРеквизит
			Для Каждого Реквизит Из ОписаниеРеквизитовТабличнойЧасти Цикл
				Если НРег(Лев(Реквизит.Имя, СтрДлина(ПрефиксУдаляемыхРеквизитов))) = НРег(ПрефиксУдаляемыхРеквизитов) Тогда
					ФильтруемыеРеквизиты[ТабличнаяЧасть.Имя + "." + Реквизит.Имя] = Истина;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
	КонецЦикла;
	
	Возврат ФильтруемыеРеквизиты;
	
КонецФункции

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

&НаСервере
Процедура СформироватьПояснениеОНастроенныхИзменениях()
	
	ЕстьОтборПоСтрокам = Ложь;
	Для Каждого ЭлементОтбора Из ЭлементыОтбораБезИерархии(КомпоновщикНастроек.Настройки.Отбор.Элементы) Цикл
		Если Не ЭлементОтбора.Использование Тогда
			Продолжить;
		КонецЕсли;
		Для Каждого ТабличнаяЧасть Из ТабличныеЧастиОбъекта Цикл
			ИмяТабличнойЧасти = Сред(ТабличнаяЧасть.Значение, СтрДлина("ТабличнаяЧасть") + 1);
			Если СтрНачинаетсяС(ЭлементОтбора.ЛевоеЗначение, ИмяТабличнойЧасти) Тогда
				ЕстьОтборПоСтрокам = Истина;
				Прервать;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
	ИзменяемыеТабличныеЧасти = Новый Соответствие;
	Для Каждого ТабличнаяЧасть Из ТабличныеЧастиОбъекта Цикл
		ИзменяемыеРеквизиты = Новый Массив;
		Для Каждого Реквизит Из ЭтотОбъект[ТабличнаяЧасть.Значение] Цикл
			Если Реквизит.Изменять Тогда
				ИзменяемыеРеквизиты.Добавить(Реквизит.Представление);
			КонецЕсли;
		КонецЦикла;
		Если ИзменяемыеРеквизиты.Количество() > 0 Тогда 
			ИзменяемыеТабличныеЧасти.Вставить(ТабличнаяЧасть.Представление, ИзменяемыеРеквизиты);
		КонецЕсли;
	КонецЦикла;
	
	ИзменяемыеРеквизиты = Новый Массив;
	Для Каждого Реквизит Из РеквизитыОбъекта Цикл
		Если Реквизит.Изменять Тогда
			ИзменяемыеРеквизиты.Добавить(Реквизит.Представление);
		КонецЕсли;
	КонецЦикла;
	
	Если Не ЕстьВыбранныеОбъекты() Тогда
		Пояснение = НСтр("ru = 'Не выбраны элементы, реквизиты которых необходимо изменить.'");
	Иначе
		Если ИзменяемыеРеквизиты.Количество() = 1 Тогда
			ШаблонПояснения = НСтр("ru = 'Изменить реквизит %1 в выбранных элементах'") // например, "Изменить реквизит ""Склад""..."
		ИначеЕсли ИзменяемыеРеквизиты.Количество() > 3 Тогда
			ШаблонПояснения = НСтр("ru = 'Изменить реквизиты (%1) в выбранных элементах'"); // например, "Изменить реквизиты (5)..."
		ИначеЕсли ИзменяемыеРеквизиты.Количество() > 1 Тогда
			ШаблонПояснения = НСтр("ru = 'Изменить реквизиты %1 в выбранных элементах'"); // например, "Изменить реквизиты ""Склад"", ""Офис""..."
		Иначе	
			ШаблонПояснения = "";
		КонецЕсли;
		
		Если ИзменяемыеРеквизиты.Количество() > 3 Тогда
			Пояснение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонПояснения, ИзменяемыеРеквизиты.Количество());
		ИначеЕсли ИзменяемыеРеквизиты.Количество() > 0 Тогда
			Пояснение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонПояснения, ИменаРеквизитов(ИзменяемыеРеквизиты));
		Иначе
			Пояснение = "";
		КонецЕсли;
		
		Для Каждого ТабличнаяЧасть Из ИзменяемыеТабличныеЧасти Цикл
			
			ИзменяемыеРеквизиты = ТабличнаяЧасть.Значение;
			Если ИзменяемыеРеквизиты.Количество() = 0 Тогда
				Продолжить;
			КонецЕсли;
			
			Если ИзменяемыеРеквизиты.Количество() = 1 Тогда
				ШаблонПояснения = ?(ПустаяСтрока(Пояснение),
					НСтр("ru = 'Изменить реквизит %1 в табличной части ""%2""'"),
					НСтр("ru = 'реквизит %1 в табличной части ""%2""'")); 
			ИначеЕсли ИзменяемыеРеквизиты.Количество() > 3 Тогда
				ШаблонПояснения = ?(ПустаяСтрока(Пояснение),
					НСтр("ru = 'Изменить реквизиты (%1) в табличной части ""%2""'"),
					НСтр("ru = 'реквизиты (%1) в табличной части ""%2""'")); 
			Иначе 
				ШаблонПояснения = ?(ПустаяСтрока(Пояснение),
					НСтр("ru = 'Изменить реквизиты %1 в табличной части ""%2""'"),
					НСтр("ru = 'реквизиты %1 в табличной части ""%2""'")); 
			КонецЕсли;
			
			Если Не ПустаяСтрока(Пояснение) Тогда
				Пояснение = Пояснение + ", ";
			КонецЕсли;
			Если ИзменяемыеРеквизиты.Количество() > 3 Тогда
				Пояснение = Пояснение + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонПояснения, 
					ИзменяемыеРеквизиты.Количество(), ТабличнаяЧасть.Ключ);
			Иначе
				Пояснение = Пояснение + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонПояснения, 
					ИменаРеквизитов(ИзменяемыеРеквизиты), ТабличнаяЧасть.Ключ);
			КонецЕсли;
		КонецЦикла;
		
		Если Не ПустаяСтрока(Пояснение) Тогда
			Пояснение = Пояснение + ".";
			Если ИзменяемыеТабличныеЧасти.Количество() > 0 Тогда
				Если ЕстьОтборПоСтрокам Тогда 
					Пояснение = Пояснение + " " + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(
						"ru = 'Изменения будут выполнены в тех строках выбранных элементов, которые удовлетворяют <a href = ""%1"">условиям отбора</a>.'"),
						"ПерейтиКНастройкеОтбора");
				Иначе
					Пояснение = Пояснение + " " + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр(
						"ru = 'Изменения будут выполнены <a href = ""%1"">во всех строках</a> выбранных элементов.'"),
						"ПерейтиКНастройкеОтбора");
				КонецЕсли;
			КонецЕсли;
		Иначе
			Пояснение = НСтр("ru = 'Выполнить <b>перезапись</b> выбранных элементов.'");
		КонецЕсли;
	КонецЕсли;
	
	Элементы.ПояснениеОНастроенныхИзменениях.Заголовок = СтроковыеФункции.ФорматированнаяСтрока(Пояснение);
	Если ПустаяСтрока(КодАлгоритма) Тогда
		КодАлгоритма = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru='// Доступные переменные:
		|// %1 - обрабатываемый объект'"), "Объект") + Символы.ПС;
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Функция ИменаРеквизитов(Знач ИзменяемыеРеквизиты)
	
	ИменаРеквизитов = "";
	Для Каждого Реквизит Из ИзменяемыеРеквизиты Цикл
		Если Не ПустаяСтрока(ИменаРеквизитов) Тогда
			ИменаРеквизитов = ИменаРеквизитов + ", ";
		КонецЕсли;
		ИменаРеквизитов = ИменаРеквизитов + """" + Реквизит + """";
	КонецЦикла;
	Возврат ИменаРеквизитов;

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

&НаСервере
Функция ЕстьВыбранныеОбъекты()
	НастройкиОтбора = НастройкиОтбора();
	НастройкиОтбора.ОграничитьВыборку = Истина;
	Возврат ВыбранныеОбъекты(НастройкиОтбора).Строки.Количество() > 0;
КонецФункции

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

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

&НаСервере
Процедура ЗаполнитьПодменюСоСпискомАлгоритмов()
	МестоРазмещенияКоманд = Элементы.Алгоритмы;
	
	УдаляемыеЭлементы = Новый Массив;
	Для Каждого Настройка Из МестоРазмещенияКоманд.ПодчиненныеЭлементы Цикл
		Если Настройка.Имя = "ЗаглушкаАлгоритмы" Тогда
			Продолжить;
		КонецЕсли;
		УдаляемыеЭлементы.Добавить(Настройка);
	КонецЦикла;
	
	Для Каждого Настройка Из УдаляемыеЭлементы Цикл
		Команды.Удалить(Команды[Настройка.Имя]);
		Элементы.Удалить(Настройка);
	КонецЦикла;
	
	Для Каждого Настройка Из ИсторияАлгоритмовСписок Цикл
		НомерКоманды = ИсторияАлгоритмовСписок.Индекс(Настройка);
		ИмяКоманды = МестоРазмещенияКоманд.Имя + "НастройкаИзменений" + НомерКоманды;
		
		КомандаФормы = Команды.Добавить(ИмяКоманды);
		КомандаФормы.Действие = "Подключаемый_УстановитьНастройку";
		КомандаФормы.Заголовок = Настройка.Представление;
		КомандаФормы.ИзменяетСохраняемыеДанные = Ложь;
		
		НовыйЭлемент = Элементы.Добавить(ИмяКоманды, Тип("КнопкаФормы"), МестоРазмещенияКоманд);
		НовыйЭлемент.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели;
		НовыйЭлемент.ИмяКоманды = ИмяКоманды;
	КонецЦикла;
	
	Элементы.ЗаглушкаАлгоритмы.Видимость = ИсторияАлгоритмовСписок.Количество() = 0;
КонецПроцедуры

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

&НаСервере
Функция ПараметрыВыбораСтрокой(ПараметрыВыбора)
	Результат = "";
	
	Для Каждого ОписаниеПараметраВыбора Из ПараметрыВыбора Цикл
		ТекущийПВСтрока = "[ПолеОтбора];[ТипСтрока];[ЗначениеСтрока]";
		ТипЗначения = ТипЗнч(ОписаниеПараметраВыбора.Значение);
		
		Если ТипЗначения = Тип("ФиксированныйМассив") Тогда
			СтроковоеПредставлениеТипа = "ФиксированныйМассив";
			ЗначениеСтрока = "";
			
			Для Каждого Элемент Из ОписаниеПараметраВыбора.Значение Цикл
				ЗначениеСтрокаШаблон = "[Тип]*[Значение]";
				ЗначениеСтрокаШаблон = СтрЗаменить(ЗначениеСтрокаШаблон, "[Тип]", ОбщегоНазначения.СтроковоеПредставлениеТипа(ТипЗнч(Элемент)));
				ЗначениеСтрокаШаблон = СтрЗаменить(ЗначениеСтрокаШаблон, "[Значение]", XMLСтрока(Элемент));
				ЗначениеСтрока = ЗначениеСтрока + ?(ПустаяСтрока(ЗначениеСтрока), "", "#") + ЗначениеСтрокаШаблон;
			КонецЦикла;
		Иначе
			СтроковоеПредставлениеТипа = ОбщегоНазначения.СтроковоеПредставлениеТипа(ТипЗначения);
			ЗначениеСтрока = XMLСтрока(ОписаниеПараметраВыбора.Значение);
		КонецЕсли;
		
		Если Не ПустаяСтрока(ЗначениеСтрока) Тогда
			ТекущийПВСтрока = СтрЗаменить(ТекущийПВСтрока, "[ПолеОтбора]", ОписаниеПараметраВыбора.Имя);
			ТекущийПВСтрока = СтрЗаменить(ТекущийПВСтрока, "[ТипСтрока]", СтроковоеПредставлениеТипа);
			ТекущийПВСтрока = СтрЗаменить(ТекущийПВСтрока, "[ЗначениеСтрока]", ЗначениеСтрока);
			
			Результат = Результат + ТекущийПВСтрока + Символы.ПС;
		КонецЕсли;
	КонецЦикла;
	
	Результат = Лев(Результат, СтрДлина(Результат)-1);
	Возврат Результат;
КонецФункции

&НаСервере
Функция СвязиПараметровВыбораСтрокой(СвязиПараметровВыбора)
	Результат = "";
	
	Для Каждого ОписаниеСвязиПараметровВыбора Из СвязиПараметровВыбора Цикл
		ТекущаяСПВСтрока = "[ИмяПараметра];[ИмяРеквизита]";
		ТекущаяСПВСтрока = СтрЗаменить(ТекущаяСПВСтрока, "[ИмяПараметра]", ОписаниеСвязиПараметровВыбора.Имя);
		ТекущаяСПВСтрока = СтрЗаменить(ТекущаяСПВСтрока, "[ИмяРеквизита]", ОписаниеСвязиПараметровВыбора.ПутьКДанным);
		Результат = Результат + ТекущаяСПВСтрока + Символы.ПС;
	КонецЦикла;
	
	Результат = Лев(Результат, СтрДлина(Результат)-1);
	Возврат Результат;
КонецФункции

&НаСервере
Функция ПредставлениеСвязейПараметровВыбора(СвязиПараметровВыбора, ОбъектМетаданных)
	Результат = "";
	
	СвязанныеРеквизиты = Новый Массив;
	Для Каждого ОписаниеСвязиПараметровВыбора Из СвязиПараметровВыбора Цикл
		ИмяРеквизита = ОписаниеСвязиПараметровВыбора.ПутьКДанным;
		ПредставлениеТабличнойЧасти = "";
		ВладелецРеквизитов = ОбъектМетаданных;
		ЧастиИмени = СтрРазделить(ИмяРеквизита, ".", Истина);
		Если ЧастиИмени.Количество() = 2 Тогда
			ИмяРеквизита = ЧастиИмени[1];
			ИмяТабличнойЧасти = ЧастиИмени[0];
			ВладелецРеквизитов = ОбъектМетаданных.ТабличныеЧасти.Найти(ИмяТабличнойЧасти);
			Если ВладелецРеквизитов <> Неопределено Тогда
				ПредставлениеТабличнойЧасти = ВладелецРеквизитов.Представление();
			КонецЕсли;
		КонецЕсли;
		Если ВладелецРеквизитов <> Неопределено Тогда
			Реквизит = ВладелецРеквизитов.Реквизиты.Найти(ИмяРеквизита);
			Если Реквизит = Неопределено Тогда
				ОписаниеСтандартныхРеквизитов = ВладелецРеквизитов.СтандартныеРеквизиты;// ОписанияСтандартныхРеквизитов
				Для Каждого СтандартныйРеквизит Из ОписаниеСтандартныхРеквизитов Цикл
					Если СтандартныйРеквизит.Имя = ИмяРеквизита Тогда
						Реквизит = СтандартныйРеквизит;
						Прервать;
					КонецЕсли;
				КонецЦикла;
			КонецЕсли;
			Если Реквизит <> Неопределено Тогда
				ПредставлениеРеквизита = Реквизит.Представление();
				Если Не ПустаяСтрока(ПредставлениеТабличнойЧасти) Тогда
					ПредставлениеРеквизита = ПредставлениеРеквизита + " (" + НСтр("ru = 'таблица'") + " " 
						+ ПредставлениеТабличнойЧасти + ")";
				КонецЕсли;
				СвязанныеРеквизиты.Добавить(ПредставлениеРеквизита);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Если СвязанныеРеквизиты.Количество() > 0 Тогда
		ШаблонПредставленияСвязей = НСтр("ru = 'Зависит от реквизитов: %1.'");
		Если СвязанныеРеквизиты.Количество() = 1 Тогда
			ШаблонПредставленияСвязей = НСтр("ru = 'Зависит от реквизита %1.'");
		КонецЕсли;
		Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			ШаблонПредставленияСвязей, СтрСоединить(СвязанныеРеквизиты, ", "));
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

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

&НаКлиенте
Процедура ПояснениеОНастроенныхИзмененияхОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка)
	Если НавигационнаяСсылкаФорматированнойСтроки = "ПерейтиКНастройкеОтбора" Тогда
		СтандартнаяОбработка = Ложь;
		ПерейтиКНастройкеОтбора();
	КонецЕсли;
КонецПроцедуры

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

&НаКлиенте
Функция ПараметрыКонструктора(Формула)
	Результат = Новый Структура;
	Результат.Вставить("Формула", Формула);
	Результат.Вставить("ОперандыЗаголовок", НСтр("ru = 'Доступные реквизиты'"));
	Результат.Вставить("Операнды", Операнды());
	Результат.Вставить("Расширенный", Ложь);
	Возврат Результат;
КонецФункции

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

&НаКлиенте
Функция ЕстьОшибкаВВыражении(Знач Выражение, ТекстОшибки = "")
	
	Выражение = Сред(Выражение, 2);
	
	Для Каждого ОписаниеРеквизита Из РеквизитыОбъекта Цикл
		Выражение = СтрЗаменить(Выражение, "[" + ОписаниеРеквизита.Представление + "]", """1""");
	КонецЦикла;
	
	Попытка
		Возврат Вычислить(Выражение) = Неопределено;
	Исключение
		ТекстОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		Возврат Истина;
	КонецПопытки;
	
КонецФункции

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

&НаКлиенте
Функция ДанныеВыбора(Строка, СписокВыбора)
	
	Результат = Новый СписокЗначений;
	
	Если Не ЗначениеЗаполнено(Строка) Тогда
		Возврат Результат;
	КонецЕсли;
	
	Для Каждого Элемент Из СписокВыбора Цикл
		ПредставлениеЭлемента = Элемент.Представление;
		
		СтрокаПоиска = ПредставлениеЭлемента;
		
		ФорматированныеСтроки = Новый Массив;
		Для Каждого Подстрока Из СтрРазделить(Строка, " ", Ложь) Цикл
			Позиция = СтрНайти(НРег(СтрокаПоиска), НРег(Подстрока));
			Если Позиция = 0 Тогда
				ФорматированныеСтроки = Неопределено;
				Прервать;
			КонецЕсли;
			
			ПодстрокаДоВхождения = Лев(СтрокаПоиска, Позиция - 1);
			ПодстрокаВхождения = Сред(СтрокаПоиска, Позиция, СтрДлина(Подстрока));
			СтрокаПоиска = Сред(СтрокаПоиска, Позиция + СтрДлина(Подстрока));
			
			ФорматированныеСтроки.Добавить(ПодстрокаДоВхождения);
			//@skip-check new-font
			//@skip-check new-color
			ФорматированныеСтроки.Добавить(Новый ФорматированнаяСтрока(ПодстрокаВхождения,
				Новый Шрифт( , , Истина), Новый Цвет(0,128,0))); // АПК:1345 АПК:1346 - автономная обработка не может использовать стили
		КонецЦикла;
		
		Если Не ЗначениеЗаполнено(ФорматированныеСтроки) Тогда
			Продолжить;
		КонецЕсли;
		
		ФорматированныеСтроки.Добавить(СтрокаПоиска);
		СтрокаСПодсветкой = Новый ФорматированнаяСтрока(ФорматированныеСтроки); // АПК:1356 - можно использовать составную форматированную строку, так как массив строк формируется из переданного в функцию текста.
		
		Результат.Добавить(Элемент.Значение, СтрокаСПодсветкой);
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

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

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

&НаКлиенте
Функция СведенияОбОшибках()
	
	Если СведенияОбОшибках = Неопределено Тогда
		СведенияОбОшибках = Новый Соответствие;
	КонецЕсли;
	
	Возврат СведенияОбОшибках;
	
КонецФункции

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

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

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