Групповое изменение реквизитов / Модуль объекта

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

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

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

// Для внутреннего использования.
Функция ТекстЗапроса(ТипыИзменяемыхОбъектов, ОграничитьВыборку = Ложь) Экспорт
	
	ОбъектыМетаданных = Новый Массив;
	Для Каждого ИмяОбъекта Из СтрРазделить(ТипыИзменяемыхОбъектов, ",", Ложь) Цикл
		ОбъектыМетаданных.Добавить(Метаданные.НайтиПоПолномуИмени(ИмяОбъекта));
	КонецЦикла;
	
	СтруктураОбъектов = ОбщиеРеквизитыОбъектов(ТипыИзменяемыхОбъектов);
	
	Результат = "";
	ПсевдонимТаблицы = "ПсевдонимЗаданнойТаблицы";
	Для Каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл
		
		Если Не ПустаяСтрока(Результат) Тогда
			Результат = Результат + Символы.ПС + Символы.ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС + Символы.ПС;
		КонецЕсли;
		
		ТекстЗапроса = "";
		
		Для Каждого ИмяРеквизита Из СтруктураОбъектов.Реквизиты Цикл
			Если Не ПустаяСтрока(ТекстЗапроса) Тогда
				ТекстЗапроса = ТекстЗапроса + "," + Символы.ПС;
			КонецЕсли;
			ТекстЗапроса = ТекстЗапроса + ПсевдонимТаблицы + "." + ИмяРеквизита + " КАК " + ИмяРеквизита;
		КонецЦикла;
		
		Для Каждого ТабличнаяЧасть Из СтруктураОбъектов.ТабличныеЧасти Цикл
			ИмяТабличнойЧасти = ТабличнаяЧасть.Ключ;
			ТекстЗапроса = ТекстЗапроса + "," + Символы.ПС + ПсевдонимТаблицы + "." + ИмяТабличнойЧасти + ".(";
			
			СтрокаРеквизитов = "НомерСтроки";
			РеквизитыТабличнойЧасти = ТабличнаяЧасть.Значение;
			Для Каждого ИмяРеквизита Из РеквизитыТабличнойЧасти Цикл
				Если Не ПустаяСтрока(СтрокаРеквизитов) Тогда
					СтрокаРеквизитов = СтрокаРеквизитов + "," + Символы.ПС;
				КонецЕсли;
				СтрокаРеквизитов = СтрокаРеквизитов + ИмяТабличнойЧасти + "." +  ИмяРеквизита + " КАК " + ИмяРеквизита; //@query-part-2
			КонецЦикла;
			ТекстЗапроса = ТекстЗапроса + СтрокаРеквизитов +"
			|)";
		КонецЦикла;
		
		ТекстЗапроса = "ВЫБРАТЬ " + ?(ОграничитьВыборку, "ПЕРВЫЕ 1001 ", "") 
			+ ТекстЗапроса + Символы.ПС + "

			|ИЗ
			|	"+ ОбъектМетаданных.ПолноеИмя() + " КАК " + ПсевдонимТаблицы; //@query-part-1
			
		Результат = Результат + ТекстЗапроса;
	КонецЦикла;
		
		
	Возврат Результат;
	
КонецФункции

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

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

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

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

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

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

// Параметры:
//   Блокировка - БлокировкаДанных 
//   Ссылка - ЛюбаяСсылка
//
Процедура ЗаблокироватьСсылку(Знач Блокировка, Знач Ссылка)
	
	ЗаблокироватьДанныеДляРедактирования(Ссылка);
	ЭлементБлокировки = Блокировка.Добавить(ОбщегоНазначения.ВидОбъектаПоСсылке(Ссылка) + "." + Ссылка.Метаданные().Имя);
	ЭлементБлокировки.УстановитьЗначение("Ссылка", Ссылка);

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

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

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

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

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

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

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

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

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

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

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

Функция ПрефиксИмениДопРеквизита()
	Возврат "ДопРеквизит_";
КонецФункции

Функция ПрефиксИмениДопСведения()
	Возврат "ДопСведение_";
КонецФункции

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

// Параметры:
//   СтрокаТаблицы - СтрокаТаблицыЗначений:
//    * НомерСтроки - Число
//   
//   ДанныеОбъекта - СтрокаДереваЗначений
//                 - Структура:
//    * Ссылка - ЛюбаяСсылка
//    * ТабличныеЧасти - ДеревоЗначений
//   
//   ИмяТаблицы - Строка
//
Функция СтрокаСоответствуетОтбору(СтрокаТаблицы, ДанныеОбъекта, ИмяТаблицы)
	
	Строки = ?(ТипЗнч(ДанныеОбъекта) = Тип("СтрокаДереваЗначений"), 
		ДанныеОбъекта.Строки, ДанныеОбъекта.ТабличныеЧасти.Строки);
	
	Возврат Строки.НайтиСтроки(Новый Структура(ИмяТаблицы + "НомерСтроки", СтрокаТаблицы.НомерСтроки)).Количество() = 1;
	
КонецФункции

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

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

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

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

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

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

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

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

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

#Область ИзменениеОбъектовВНесколькоПотоков

// АПК:581-выкл Экспортная, так как вызывается из фонового задания.
Функция РезультатИзмененияПорцииОбъектов(ОбрабатываемыеОбъекты, РезультатИзменения, НастройкиИзменения) Экспорт

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

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

Функция ОписаниеТабличныхЧастей(Параметры)

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

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

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

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

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

#Иначе
ВызватьИсключение НСтр("ru = 'Недопустимый вызов объекта на клиенте.'");
#КонецЕсли

Связанные материалы