#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область СлужебныеПроцедурыИФункции
Функция ТекстЗапроса(ТипыИзменяемыхОбъектов, ОграничитьВыборку = Ложь) Экспорт
ОбъектыМетаданных = Новый Массив;
Для Каждого ИмяОбъекта Из СтрРазделить(ТипыИзменяемыхОбъектов, ",", Ложь) Цикл
ОбъектыМетаданных.Добавить(Метаданные.НайтиПоПолномуИмени(ИмяОбъекта));
КонецЦикла;
СтруктураОбъектов = ОбщиеРеквизитыОбъектов(ТипыИзменяемыхОбъектов);
Результат = "";
ПсевдонимТаблицы = "ПсевдонимЗаданнойТаблицы";
Для Каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл
Если Не ПустаяСтрока(Результат) Тогда
Результат = Результат + Символы.ПС + Символы.ПС + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС + Символы.ПС;
КонецЕсли;
ТекстЗапроса = "";
Для Каждого ИмяРеквизита Из СтруктураОбъектов.Реквизиты Цикл
Если Не ПустаяСтрока(ТекстЗапроса) Тогда
ТекстЗапроса = ТекстЗапроса + "," + Символы.ПС;
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + ПсевдонимТаблицы + "." + ИмяРеквизита + " КАК " + ИмяРеквизита;
КонецЦикла;
Для Каждого ТабличнаяЧасть Из СтруктураОбъектов.ТабличныеЧасти Цикл
ИмяТабличнойЧасти = ТабличнаяЧасть.Ключ;
ТекстЗапроса = ТекстЗапроса + "," + Символы.ПС + ПсевдонимТаблицы + "." + ИмяТабличнойЧасти + ".(";
СтрокаРеквизитов = "НомерСтроки";
РеквизитыТабличнойЧасти = ТабличнаяЧасть.Значение;
Для Каждого ИмяРеквизита Из РеквизитыТабличнойЧасти Цикл
Если Не ПустаяСтрока(СтрокаРеквизитов) Тогда
СтрокаРеквизитов = СтрокаРеквизитов + "," + Символы.ПС;
КонецЕсли;
СтрокаРеквизитов = СтрокаРеквизитов + ИмяТабличнойЧасти + "." + ИмяРеквизита + " КАК " + ИмяРеквизита;
КонецЦикла;
ТекстЗапроса = ТекстЗапроса + СтрокаРеквизитов +"
|)";
КонецЦикла;
ТекстЗапроса = "ВЫБРАТЬ " + ?(ОграничитьВыборку, "ПЕРВЫЕ 1001 ", "")
+ ТекстЗапроса + Символы.ПС + "
|ИЗ
| "+ ОбъектМетаданных.ПолноеИмя() + " КАК " + ПсевдонимТаблицы;
Результат = Результат + ТекстЗапроса;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ОбщиеРеквизитыОбъектов(ТипыОбъектов) Экспорт
ОбъектыМетаданных = Новый Массив;
Для Каждого ИмяОбъекта Из СтрРазделить(ТипыОбъектов, ",", Ложь) Цикл
ОбъектыМетаданных.Добавить(Метаданные.НайтиПоПолномуИмени(ИмяОбъекта));
КонецЦикла;
Результат = Новый Структура;
Результат.Вставить("Реквизиты", Новый Массив);
Результат.Вставить("ТабличныеЧасти", Новый Структура);
Если ОбъектыМетаданных.Количество() = 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 Тогда
ВнестиИзмененияВТабличныеЧасти(ИзменяемыйОбъект, ДанныеОбъекта, Параметры.ИзменяемыеТабличныеЧасти);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ВыполнитьКодАлгоритма(Знач Объект, Знач КодАлгоритма, Знач ВыполнитьВБезопасномРежиме)
Если ВыполнитьВБезопасномРежиме Или НЕ ПравоДоступа("Администрирование", Метаданные) Тогда
КодАлгоритма = "Объект = Параметры;
|" + КодАлгоритма;
ОбщегоНазначения.ВыполнитьВБезопасномРежиме(КодАлгоритма, Объект);
Иначе
Выполнить КодАлгоритма;
КонецЕсли;
КонецПроцедуры
Функция РазделениеВключено()
ДоступнаРаботаВМоделиСервиса = Метаданные.ФункциональныеОпции.Найти("РаботаВМоделиСервиса");
Если ДоступнаРаботаВМоделиСервиса <> Неопределено Тогда
ИмяОпции = "РаботаВМоделиСервиса";
Возврат ЭтоРазделеннаяКонфигурация() И ПолучитьФункциональнуюОпцию(ИмяОпции);
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЭтоРазделеннаяКонфигурация()
ЕстьРазделители = Ложь;
Для каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
Если ОбщийРеквизит.РазделениеДанных = Метаданные.СвойстваОбъектов.РазделениеДанныхОбщегоРеквизита.Разделять Тогда
ЕстьРазделители = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ЕстьРазделители;
КонецФункции
Функция ОпределитьРежимЗаписи(Знач ИзменяемыйОбъект, Знач ЭтоДокумент, Знач РежимРазработчика)
РежимЗаписи = Неопределено;
Если РежимРазработчика Тогда
РежимЗаписи = Неопределено;
ИзменяемыйОбъект.ОбменДанными.Загрузка = Истина;
ИначеЕсли ЭтоДокумент Тогда
РежимЗаписи = РежимЗаписиДокумента.Запись;
Если ИзменяемыйОбъект.Проведен Тогда
РежимЗаписи = РежимЗаписиДокумента.Проведение;
ИначеЕсли ИзменяемыйОбъект.Метаданные().Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить Тогда
РежимЗаписи = РежимЗаписиДокумента.ОтменаПроведения;
КонецЕсли;
КонецЕсли;
Возврат РежимЗаписи;
КонецФункции
Функция СвойствоНужноИзменять(Ссылка, Свойство, Параметры)
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Свойства") Тогда
МодульУправлениеСвойствами = ОбщегоНазначения.ОбщийМодуль("УправлениеСвойствами");
Если МодульУправлениеСвойствами = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
ВидОбъектаПоСсылке = ОбщегоНазначения.ВидОбъектаПоСсылке(Ссылка);
Если (ВидОбъектаПоСсылке = "Справочник" ИЛИ ВидОбъектаПоСсылке = "ПланВидовХарактеристик")
И ОбщегоНазначения.ОбъектЯвляетсяГруппой(Ссылка) Тогда
Возврат Ложь;
КонецЕсли;
Если НЕ МодульУправлениеСвойствами.ПроверитьСвойствоУОбъекта(Ссылка, Свойство) Тогда
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции
Функция ТекстОшибокПроверкиЗаполнения()
Результат = "";
МассивСообщений = ПолучитьСообщенияПользователю(Истина);
Для Каждого СообщениеПользователю Из МассивСообщений Цикл
Результат = Результат + СообщениеПользователю.Текст + Символы.ПС;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ЗаполнитьРезультатИзменения(Результат, Ссылка, СообщениеОбОшибке)
СостояниеИзменения = Новый Структура;
СостояниеИзменения.Вставить("КодОшибки", "Ошибка");
СостояниеИзменения.Вставить("СообщениеОбОшибке", СообщениеОбОшибке);
Результат.СостояниеОбработки.Вставить(Ссылка, СостояниеИзменения);
Результат.ЕстьОшибки = Истина;
КонецПроцедуры
Процедура ЗаполнитьРезультатИзмененияДополнительныхСвойств(Результат, Ссылка, ИзменяемыйОбъект, Изменения = Неопределено)
СостояниеИзменения = Новый Структура;
СостояниеИзменения.Вставить("КодОшибки", "");
СостояниеИзменения.Вставить("СообщениеОбОшибке", "");
СостояниеИзменения.Вставить("ЗначенияИзмененныхРеквизитов", Новый Соответствие);
Если Изменения <> Неопределено Тогда
Для Каждого ИмяРеквизита Из Изменения.ИзменяемыеРеквизитыОбъекта Цикл
СостояниеИзменения.ЗначенияИзмененныхРеквизитов.Вставить(ИмяРеквизита, ИзменяемыйОбъект[ИмяРеквизита]);
КонецЦикла;
КонецЕсли;
СостояниеИзменения.Вставить("ЗначенияИзмененныхДопРеквизитов",
?(Изменения <> Неопределено, Изменения.ИзменяемыеДопРеквизитыОбъекта, Изменения));
СостояниеИзменения.Вставить("ЗначенияИзмененныхДопСведений",
?(Изменения <> Неопределено, Изменения.ИзменяемыеДопСведенияОбъекта, Изменения));
Результат.СостояниеОбработки.Вставить(Ссылка, СостояниеИзменения);
КонецПроцедуры
Функция ПрефиксИмениДопРеквизита()
Возврат "ДопРеквизит_";
КонецФункции
Функция ПрефиксИмениДопСведения()
Возврат "ДопСведение_";
КонецФункции
Процедура ВнестиИзмененияВТабличныеЧасти(ИзменяемыйОбъект, ДанныеОбъекта, ИзмененияВТабличныхЧастях)
Для Каждого ИзмененияТабличнойЧасти Из ИзмененияВТабличныхЧастях Цикл
ИмяТаблицы = ИзмененияТабличнойЧасти.Ключ;
ИзменяемыеРеквизиты = ИзмененияТабличнойЧасти.Значение;
Для Каждого СтрокаТаблицы Из ИзменяемыйОбъект[ИмяТаблицы] Цикл
Если СтрокаСоответствуетОтбору(СтрокаТаблицы, ДанныеОбъекта, ИмяТаблицы) Тогда
Для Каждого ИзменяемыйРеквизит Из ИзменяемыеРеквизиты Цикл
СтрокаТаблицы[ИзменяемыйРеквизит.Имя] = ИзменяемыйРеквизит.Значение;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция СтрокаСоответствуетОтбору(СтрокаТаблицы, ДанныеОбъекта, ИмяТаблицы)
Строки = ?(ТипЗнч(ДанныеОбъекта) = Тип("СтрокаДереваЗначений"),
ДанныеОбъекта.Строки, ДанныеОбъекта.ТабличныеЧасти.Строки);
Возврат Строки.НайтиСтроки(Новый Структура(ИмяТаблицы + "НомерСтроки", СтрокаТаблицы.НомерСтроки)).Количество() = 1;
КонецФункции
Процедура ЗаполнитьКоллекциюДоступныхДляИзмененияОбъектов(ДоступныеОбъекты, ПоказыватьСкрытые) Экспорт
КоллекцииОбъектовМетаданных = Новый Массив;
КоллекцииОбъектовМетаданных.Добавить(Метаданные.Справочники);
КоллекцииОбъектовМетаданных.Добавить(Метаданные.Документы);
КоллекцииОбъектовМетаданных.Добавить(Метаданные.БизнесПроцессы);
КоллекцииОбъектовМетаданных.Добавить(Метаданные.Задачи);
КоллекцииОбъектовМетаданных.Добавить(Метаданные.ПланыВидовРасчета);
КоллекцииОбъектовМетаданных.Добавить(Метаданные.ПланыВидовХарактеристик);
КоллекцииОбъектовМетаданных.Добавить(Метаданные.ПланыСчетов);
КоллекцииОбъектовМетаданных.Добавить(Метаданные.ПланыОбмена);
ПрефиксУдаляемыхОбъектов = "удалить";
УдаляемыеОбъекты = Новый СписокЗначений;
МенеджерыОбъектов = МенеджерыОбъектовДляРедактированияРеквизитов();
Для Каждого КоллекцияОбъектовМетаданных Из КоллекцииОбъектовМетаданных Цикл
Для Каждого ОбъектМетаданных Из КоллекцияОбъектовМетаданных Цикл
Если Не ОбщегоНазначения.ОбъектМетаданныхДоступенПоФункциональнымОпциям(ОбъектМетаданных) Тогда
Продолжить;
КонецЕсли;
Если Не ПоказыватьСкрытые Тогда
Если СтрНачинаетсяС(НРег(ОбъектМетаданных.Имя), ПрефиксУдаляемыхОбъектов)
Или ЭтоСлужебныйОбъект(ОбъектМетаданных, МенеджерыОбъектов) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если ПравоДоступа("Изменение", ОбъектМетаданных) Тогда
Если СтрНачинаетсяС(НРег(ОбъектМетаданных.Имя), ПрефиксУдаляемыхОбъектов) Тогда
УдаляемыеОбъекты.Добавить(ОбъектМетаданных.ПолноеИмя(), ОбъектМетаданных.Представление());
Иначе
ДоступныеОбъекты.Добавить(ОбъектМетаданных.ПолноеИмя(), ОбъектМетаданных.Представление());
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
ДоступныеОбъекты.СортироватьПоПредставлению();
УдаляемыеОбъекты.СортироватьПоПредставлению();
Для Каждого Элемент Из УдаляемыеОбъекты Цикл
ДоступныеОбъекты.Добавить(Элемент.Значение, Элемент.Представление);
КонецЦикла;
КонецПроцедуры
Функция ЭтоСлужебныйОбъект(Знач ОбъектМетаданных, Знач МенеджерыОбъектов)
НастройкиРедактированияРеквизитов = НастройкиРедактированияРеквизитов(ОбъектМетаданных, МенеджерыОбъектов);
Редактируемые = НастройкиРедактированияРеквизитов.Редактируемые;
НеРедактируемые = НастройкиРедактированияРеквизитов.НеРедактируемые;
Если ТипЗнч(НеРедактируемые) = Тип("Массив") И НеРедактируемые.Найти("*") <> Неопределено
Или ТипЗнч(Редактируемые) = Тип("Массив") И Не ЗначениеЗаполнено(Редактируемые) Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция НастройкиРедактированияРеквизитов(ОбъектМетаданных, МенеджерыОбъектов = Null) Экспорт
Если МенеджерыОбъектов = Null Тогда
МенеджерыОбъектов = МенеджерыОбъектовДляРедактированияРеквизитов();
КонецЕсли;
Редактируемые = Неопределено;
НеРедактируемые = Неопределено;
ДоступныеМетоды = МетодыМенеджераОбъектаДляРедактированияРеквизитов(ОбъектМетаданных.ПолноеИмя(), МенеджерыОбъектов);
ПрочитатьРедактируемые = ДоступныеМетоды.РеквизитыРедактируемыеВГрупповойОбработке;
ПрочитатьНеРедактируемые = ДоступныеМетоды.РеквизитыНеРедактируемыеВГрупповойОбработке;
МенеджерОбъекта = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ОбъектМетаданных.ПолноеИмя());
Если ПрочитатьРедактируемые Тогда
Редактируемые = МенеджерОбъекта.РеквизитыРедактируемыеВГрупповойОбработке();
КонецЕсли;
Если ПрочитатьНеРедактируемые Тогда
НеРедактируемые = МенеджерОбъекта.РеквизитыНеРедактируемыеВГрупповойОбработке();
КонецЕсли;
ИнтеграцияПодсистемБСП.ПриОпределенииРедактируемыхРеквизитовОбъекта(
ОбъектМетаданных, Редактируемые, НеРедактируемые);
ГрупповоеИзменениеОбъектовПереопределяемый.ПриОпределенииРедактируемыхРеквизитовОбъекта(
ОбъектМетаданных, Редактируемые, НеРедактируемые);
Результат = Новый Структура;
Результат.Вставить("Редактируемые", Редактируемые);
Результат.Вставить("НеРедактируемые", НеРедактируемые);
Возврат Результат;
КонецФункции
Функция МетодыМенеджераОбъектаДляРедактированияРеквизитов(ИмяОбъекта, МенеджерыОбъектов)
ДоступныеМетоды = Новый Структура;
ДоступныеМетоды.Вставить("РеквизитыРедактируемыеВГрупповойОбработке", Ложь);
ДоступныеМетоды.Вставить("РеквизитыНеРедактируемыеВГрупповойОбработке", Ложь);
СведенияОМенеджереОбъекта = МенеджерыОбъектов[ИмяОбъекта];
Если СведенияОМенеджереОбъекта = Неопределено Тогда
Возврат ДоступныеМетоды;
КонецЕсли;
Для Каждого ИмяМетода Из СтрРазделить(СведенияОМенеджереОбъекта, Символы.ПС, Ложь) Цикл
Если ИмяМетода = "РеквизитыРедактируемыеВГрупповойОбработке" Тогда
ДоступныеМетоды.РеквизитыРедактируемыеВГрупповойОбработке = Истина;
ИначеЕсли ИмяМетода = "РеквизитыНеРедактируемыеВГрупповойОбработке" Тогда
ДоступныеМетоды.РеквизитыНеРедактируемыеВГрупповойОбработке = Истина;
ИначеЕсли ИмяМетода = "*" Тогда
ДоступныеМетоды.РеквизитыРедактируемыеВГрупповойОбработке = Истина;
ДоступныеМетоды.РеквизитыНеРедактируемыеВГрупповойОбработке = Истина;
КонецЕсли;
КонецЦикла;
Возврат ДоступныеМетоды;
КонецФункции
Функция МенеджерыОбъектовДляРедактированияРеквизитов()
ОбъектыСЗаблокированнымиРеквизитами = Новый Соответствие;
ИнтеграцияПодсистемБСП.ПриОпределенииОбъектовСРедактируемымиРеквизитами(ОбъектыСЗаблокированнымиРеквизитами);
ГрупповоеИзменениеОбъектовПереопределяемый.ПриОпределенииОбъектовСРедактируемымиРеквизитами(ОбъектыСЗаблокированнымиРеквизитами);
Возврат ОбъектыСЗаблокированнымиРеквизитами;
КонецФункции
Функция ВычислитьВыражение(Знач Выражение, Объект, ДоступныеРеквизиты)
Если Не(ТипЗнч(Выражение) = Тип("Строка") И СтрНачинаетсяС(Выражение, "=")) Тогда
Возврат Выражение;
КонецЕсли;
Если СтрНачинаетсяС(Выражение, "'=") Тогда
Возврат Сред(Выражение, 2);
КонецЕсли;
Выражение = Сред(Выражение, 2);
Для Каждого ОписаниеРеквизита Из ДоступныеРеквизиты Цикл
Если СтрНайти(Выражение, "[" + ОписаниеРеквизита.Представление + "]") = 0 Тогда
Продолжить;
КонецЕсли;
Значение = "";
Если ОписаниеРеквизита.ВидОперации = 1 Тогда
Значение = Объект[ОписаниеРеквизита.Имя];
ИначеЕсли ОписаниеРеквизита.ВидОперации < 4 Тогда
МодульУправлениеСвойствами = ОбщегоНазначения.ОбщийМодуль("УправлениеСвойствами");
СписокСвойств = Новый Массив;
СписокСвойств.Добавить(ОписаниеРеквизита.Свойство);
ЗначенияСвойств = МодульУправлениеСвойствами.ЗначенияСвойств(Объект.Ссылка, Истина, Истина, СписокСвойств);
Для Каждого СтрокаТаблицы Из ЗначенияСвойств.НайтиСтроки(Новый Структура("Свойство", ОписаниеРеквизита.Свойство)) Цикл
Значение = СтрокаТаблицы.Значение;
КонецЦикла;
Иначе
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Реквизит ""%1"" не поддерживается в выражениях'"), ОписаниеРеквизита.Представление);
ВызватьИсключение ТекстОшибки;
КонецЕсли;
Выражение = СтрЗаменить(Выражение, "[" + ОписаниеРеквизита.Представление + "]", """"
+ СтрЗаменить(СтрЗаменить(Значение, """", """"""), Символы.ПС, Символы.ПС + "|") + """");
КонецЦикла;
Возврат ОбщегоНазначения.ВычислитьВБезопасномРежиме(Выражение);
КонецФункции
Процедура ОтключитьОбновлениеКлючейДоступа(Отключить, ПланироватьОбновление = Истина)
Если Не Пользователи.ЭтоПолноправныйПользователь() Тогда
Возврат;
КонецЕсли;
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда
МодульУправлениеДоступом = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступом");
МодульУправлениеДоступом.ОтключитьОбновлениеКлючейДоступа(Отключить, ПланироватьОбновление);
КонецЕсли;
КонецПроцедуры
#Область ИзменениеОбъектовВНесколькоПотоков
Функция РезультатИзмененияПорцииОбъектов(ОбрабатываемыеОбъекты, РезультатИзменения, НастройкиИзменения) Экспорт
Ссылка = Неопределено;
ЗаписатьОшибку = Истина;
ОтключитьОбновлениеКлючейДоступа(Истина);
Если НастройкиИзменения.ИзменятьВТранзакции Тогда
НачатьТранзакцию();
КонецЕсли;
Попытка
Если НастройкиИзменения.ИзменятьВТранзакции Тогда
Блокировка = Новый БлокировкаДанных;
Для Каждого ДанныеОбъекта Из ОбрабатываемыеОбъекты Цикл
Ссылка = ДанныеОбъекта.Ссылка;
ЗаблокироватьСсылку(Блокировка, ДанныеОбъекта.Ссылка);
КонецЦикла;
Блокировка.Заблокировать();
КонецЕсли;
Для Каждого ДанныеОбъекта Из ОбрабатываемыеОбъекты Цикл
ЗаписатьОшибку = Истина;
НачатьТранзакцию();
Попытка
Ссылка = ДанныеОбъекта.Ссылка;
Если Не НастройкиИзменения.ИзменятьВТранзакции Тогда
Блокировка = Новый БлокировкаДанных;
ЗаблокироватьСсылку(Блокировка, Ссылка);
Блокировка.Заблокировать();
КонецЕсли;
ИзменяемыйОбъект = Ссылка.ПолучитьОбъект();
Изменения = Неопределено;
Если НастройкиИзменения.ТипОперации = "ВыполнитьАлгоритм" Тогда
ВыполнитьКодАлгоритма(ИзменяемыйОбъект, НастройкиИзменения.КодАлгоритма,
НастройкиИзменения.ВыполнятьКодАлгоритмаВБезопасномРежиме);
Иначе
Изменения = ВнестиИзменения(ДанныеОбъекта, ИзменяемыйОбъект, НастройкиИзменения);
КонецЕсли;
ЭтоДокумент = Метаданные.Документы.Содержит(ИзменяемыйОбъект.Метаданные());
РежимЗаписи = ОпределитьРежимЗаписи(ИзменяемыйОбъект, ЭтоДокумент, НастройкиИзменения.РежимРазработчика);
Если Не НастройкиИзменения.РежимРазработчика Тогда
Если Не ЭтоДокумент Или РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
Если Не ИзменяемыйОбъект.ПроверитьЗаполнение() Тогда
ВызватьИсключение ТекстОшибокПроверкиЗаполнения();
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Изменения <> Неопределено И Изменения.МассивЗаписейДопСведений.Количество() > 0 Тогда
Для Каждого МенеджерЗаписи Из Изменения.МассивЗаписейДопСведений Цикл
МенеджерЗаписи.Записать(Истина);
КонецЦикла;
КонецЕсли;
Если Изменения <> Неопределено И ЗначениеЗаполнено(Изменения.ИзменяемыеВнешниеРеквизиты) Тогда
ПользователиСлужебный.ПриИзмененииВнешнихРеквизитов(ИзменяемыйОбъект,
Изменения.ИзменяемыеВнешниеРеквизиты);
КонецЕсли;
НастроеныИзменения = ЗначениеЗаполнено(НастройкиИзменения.ИзменяемыеРеквизиты)
Или ЗначениеЗаполнено(НастройкиИзменения.ИзменяемыеТабличныеЧасти);
ЗаписыватьОбъект = НастройкиИзменения.ВариантЗаписиОбъекта <> "НеЗаписывать"
И (ИзменяемыйОбъект.Модифицированность() Или Не НастроеныИзменения);
Если ЗаписыватьОбъект Тогда
Если РежимЗаписи <> Неопределено Тогда
ИзменяемыйОбъект.Записать(РежимЗаписи);
Иначе
ИзменяемыйОбъект.Записать();
КонецЕсли;
КонецЕсли;
ЗаполнитьРезультатИзмененияДополнительныхСвойств(РезультатИзменения, Ссылка, ИзменяемыйОбъект, Изменения);
РазблокироватьДанныеДляРедактирования(Ссылка);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
Если НастройкиИзменения.ИзменятьВТранзакции Тогда
РазблокироватьДанныеДляРедактирования(Ссылка);
КонецЕсли;
ЗаполнитьРезультатИзменения(РезультатИзменения, Ссылка, ИнформацияОбОшибке());
Если НастройкиИзменения.ОстанавливатьИзменениеПриОшибке Или НастройкиИзменения.ИзменятьВТранзакции Тогда
ЗаписатьОшибку = Ложь;
ВызватьИсключение;
КонецЕсли;
Продолжить;
КонецПопытки;
КонецЦикла;
ОтключитьОбновлениеКлючейДоступа(Ложь);
Если НастройкиИзменения.ИзменятьВТранзакции Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Исключение
Если НастройкиИзменения.ИзменятьВТранзакции Тогда
ОтменитьТранзакцию();
Для Каждого ДанныеОбъекта Из ОбрабатываемыеОбъекты Цикл
РазблокироватьДанныеДляРедактирования(ДанныеОбъекта.Ссылка);
КонецЦикла;
КонецЕсли;
ОтключитьОбновлениеКлючейДоступа(Ложь, НастройкиИзменения.ИзменятьВТранзакции);
Если ЗаписатьОшибку Тогда
КраткоеПредставлениеОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаполнитьРезультатИзменения(РезультатИзменения, Ссылка, КраткоеПредставлениеОшибки);
КонецЕсли;
КонецПопытки;
Возврат РезультатИзменения;
КонецФункции
Функция ВыполнитьИзменениеОбъектовВНесколькоПотоков(Параметры, ОбрабатываемыеОбъекты, РезультатИзменения,
ОстанавливатьИзменениеПриОшибке, ВыполнятьКодАлгоритмаВБезопасномРежиме)
ИдентификаторФормы = Новый УникальныйИдентификатор;
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(ИдентификаторФормы);
ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'Групповое изменение реквизитов'");
МассивПорций = Новый Массив;
ПорцияОбъектов = Новый Массив;
СчетчикОбъектов = 0;
КоличествоПотоковДлительныхОпераций = ДлительныеОперации.ДопустимоеКоличествоПотоков();
ОбрабатыватьВОдинПоток = Параметры.ИзменятьВТранзакции Или Параметры.ПрерыватьПриОшибке;
Если КоличествоПотоковДлительныхОпераций > 0 И Не ОбрабатыватьВОдинПоток Тогда
ЧислоОбъектовВПорции = Цел(ОбрабатываемыеОбъекты.Количество() / КоличествоПотоковДлительныхОпераций);
Иначе
ЧислоОбъектовВПорции = ОбрабатываемыеОбъекты.Количество();
КонецЕсли;
ОписаниеТабличныхЧастей = ОписаниеТабличныхЧастей(Параметры);
Для Каждого ДанныеОбъекта Из ОбрабатываемыеОбъекты Цикл
Если СчетчикОбъектов = ЧислоОбъектовВПорции Тогда
МассивПорций.Добавить(ПорцияОбъектов);
ПорцияОбъектов = Новый Массив;
СчетчикОбъектов = 0;
КонецЕсли;
ТабличныеЧасти = ОписаниеТабличныхЧастей.Скопировать();
РекурсивноеДобавлениеСтрокДереваЗначений(ТабличныеЧасти, ДанныеОбъекта);
ДанныеПорции = Новый Структура;
ДанныеПорции.Вставить("Ссылка", ДанныеОбъекта.Ссылка);
ДанныеПорции.Вставить("ТабличныеЧасти", ТабличныеЧасти);
ПорцияОбъектов.Добавить(ДанныеПорции);
СчетчикОбъектов = СчетчикОбъектов + 1;
КонецЦикла;
Если ПорцияОбъектов.Количество() > 0 Тогда
МассивПорций.Добавить(ПорцияОбъектов);
КонецЕсли;
ПараметрыМетода = Новый Соответствие;
ВерхняяГраницаПорций = МассивПорций.ВГраница();
НастройкиИзменения = НастройкиИзменения(Параметры, ВыполнятьКодАлгоритмаВБезопасномРежиме);
Для ИндексПорции = 0 По ВерхняяГраницаПорций Цикл
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(МассивПорций[ИндексПорции]);
МассивПараметров.Добавить(РезультатИзменения);
МассивПараметров.Добавить(НастройкиИзменения);
ПараметрыМетода.Вставить(ИндексПорции, МассивПараметров);
КонецЦикла;
ИмяФункции = "Обработка.ГрупповоеИзменениеРеквизитов.МодульОбъекта.РезультатИзмененияПорцииОбъектов";
РезультатВыполнения = ДлительныеОперации.ВыполнитьФункциюВНесколькоПотоков(ИмяФункции,
ПараметрыВыполнения, ПараметрыМетода);
Возврат РезультатВыполнения;
КонецФункции
Функция ОписаниеТабличныхЧастей(Параметры)
ОписаниеТабличныхЧастей = Новый ДеревоЗначений;
ОбъектыДляИзменения = Параметры.ОбъектыДляИзменения.Получить();
Если ОбъектыДляИзменения = Неопределено Тогда
ОбъектыДляИзменения = Параметры.ОбрабатываемыеОбъекты.Получить();
КонецЕсли;
Для Каждого Колонка Из ОбъектыДляИзменения.Колонки Цикл
ОписаниеТабличныхЧастей.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения, Колонка.Заголовок, Колонка.Ширина);
КонецЦикла;
Возврат ОписаниеТабличныхЧастей;
КонецФункции
Процедура РекурсивноеДобавлениеСтрокДереваЗначений(Получатель, Источник)
Для Каждого СтрокаИсточника Из Источник.Строки Цикл
ТекущаяСтрока = Получатель.Строки.Добавить();
ЗаполнитьЗначенияСвойств(ТекущаяСтрока, СтрокаИсточника);
Если СтрокаИсточника.Строки.Количество() > 0 Тогда
РекурсивноеДобавлениеСтрокДереваЗначений(ТекущаяСтрока, СтрокаИсточника);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция НастройкиИзменения(Параметры, ВыполнятьКодАлгоритмаВБезопасномРежиме)
НастройкиИзменения = Новый Структура;
НастройкиИзменения.Вставить("ВариантЗаписиОбъекта");
НастройкиИзменения.Вставить("ВыполнятьКодАлгоритмаВБезопасномРежиме", ВыполнятьКодАлгоритмаВБезопасномРежиме);
НастройкиИзменения.Вставить("ДоступныеРеквизиты");
НастройкиИзменения.Вставить("ИзменяемыеРеквизиты");
НастройкиИзменения.Вставить("ИзменяемыеТабличныеЧасти");
НастройкиИзменения.Вставить("ИзменятьВТранзакции");
НастройкиИзменения.Вставить("КодАлгоритма");
НастройкиИзменения.Вставить("ОстанавливатьИзменениеПриОшибке");
НастройкиИзменения.Вставить("РежимРазработчика");
НастройкиИзменения.Вставить("ТипОперации");
ЗаполнитьЗначенияСвойств(НастройкиИзменения, Параметры);
Возврат НастройкиИзменения;
КонецФункции
#КонецОбласти
#КонецОбласти
#Иначе
ВызватьИсключение НСтр("ru = 'Недопустимый вызов объекта на клиенте.'");
#КонецЕсли