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

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

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
УстановитьУсловноеОформление();

	СмешаннаяВажность = НСтр("ru = 'Различная'");
    // TODO: допиши оставшуюся часть

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

	УстановитьУсловноеОформление();

	СмешаннаяВажность = НСтр("ru = 'Различная'");

	// Контроль количества вариантов осуществляется до открытия формы.
	ИзменяемыеВарианты.ЗагрузитьЗначения(Параметры.Варианты);
	КоличествоВариантов = ИзменяемыеВарианты.Количество();
	ЗаполнитьРазделы();

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

&НаКлиенте

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

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

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

&НаКлиенте

Процедура ДеревоПодсистемИспользованиеПриИзменении(Элемент)
	ВариантыОтчетовКлиент.ДеревоПодсистемИспользованиеПриИзменении(ЭтотОбъект, Элемент);
КонецПроцедуры

&НаКлиенте

Процедура ДеревоПодсистемВажностьПриИзменении(Элемент)
	ВариантыОтчетовКлиент.ДеревоПодсистемВажностьПриИзменении(ЭтотОбъект, Элемент);
КонецПроцедуры

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

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

&НаКлиенте

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

&НаКлиенте

Процедура СнятьФлажки(Команда)
	СнятьФлажкиРазделов();
	Элементы.ДеревоПодсистем.Развернуть(ДеревоПодсистем.ПолучитьЭлементы()[0].ПолучитьИдентификатор(), Истина);
КонецПроцедуры

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

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

&НаСервере

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

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

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

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

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

	ЦветЗаблокированногоРеквизита = Метаданные.ЭлементыСтиля.ЗаблокированныйРеквизитЦвет;
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветЗаблокированногоРеквизита.Значение);

	ВариантыОтчетов.УстановитьУсловноеОформлениеДереваПодсистем(ЭтотОбъект);

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

&НаСервере

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

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

	Найденные = ДеревоПриемник.Строки.НайтиСтроки(Новый Структура("Использование", 2), Истина);
	Для Каждого СтрокаДерева Из Найденные Цикл
		СтрокаДерева.Использование = 0;
		СтрокаДерева.Модифицированность = Истина;
	КонецЦикла;

	ЗначениеВРеквизитФормы(ДеревоПриемник, "ДеревоПодсистем");
КонецПроцедуры

&НаСервере

Процедура ЗаполнитьРазделы()

	ДанныеЗаполнения = ДанныеЗаполненияРазделов();
	ОтфильтрованныеВарианты = ДанныеЗаполнения.ОтфильтрованныеВарианты;

	КоличествоОшибок = ОтфильтрованныеВарианты.Количество();

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

			СообщенияОбОшибках.Подробно = СокрЛ(СообщенияОбОшибках.Подробно) + Символы.ПС + "    - " + Строка(
				СтрокаТаблицы.Ссылка);
			ИзменяемыеВарианты.Удалить(ИзменяемыеВарианты.НайтиПоЗначению(СтрокаТаблицы.Ссылка));
		КонецЦикла;

		КоличествоВариантов = ИзменяемыеВарианты.Количество();

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

		СообщенияОбОшибках = Новый ФиксированнаяСтруктура(СообщенияОбОшибках);
	КонецЕсли;

	ВхожденияПодсистем = ДанныеЗаполнения.ВхожденияПодсистем;

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

	ДеревоПриемник = РеквизитФормыВЗначение("ДеревоПодсистем", Тип("ДеревоЗначений"));
	ДеревоПриемник.Строки.Очистить();

	ДобавитьПодсистемыВДерево(ДеревоПриемник, ДеревоИсточник, ВхожденияПодсистем);

	ЗначениеВРеквизитФормы(ДеревоПриемник, "ДеревоПодсистем");
КонецПроцедуры

// Возвращает данные для заполнения дерева разделов.
//
// Возвращаемое значение:
//  Структура:
//    * ОтфильтрованныеВарианты - ТаблицаЗначений:
//        ** Ссылка - СправочникСсылка.ВариантыОтчетов
//        ** Причина - Число
//    * ВхожденияПодсистем - ТаблицаЗначений:
//        ** Ссылка - СправочникСсылка.ВариантыОтчетов
//        ** Количество - Число
//        ** Важность - Строка
//
&НаСервере

Функция ДанныеЗаполненияРазделов()

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

	Пакет = Запрос.ВыполнитьПакет();
	Граница = Пакет.ВГраница();

	ДанныеЗаполнения = Новый Структура;
	ДанныеЗаполнения.Вставить("ОтфильтрованныеВарианты", Пакет[Граница - 1].Выгрузить());
	ДанныеЗаполнения.Вставить("ВхожденияПодсистем", Пакет[Граница].Выгрузить());

	Возврат ДанныеЗаполнения;

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

&НаСервере


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

Процедура ИмяФункции(ИменаПараметровСеанса, УстановленныеПараметры) Экспорт

	Если ИменаПараметровСеанса = Неопределено Или ИменаПараметровСеанса.Найти("УстановленныеРасширения") <> Неопределено Тогда

		ПараметрыСеанса.УстановленныеРасширения = УстановленныеРасширения(Истина);
		УстановленныеПараметры.Добавить("УстановленныеРасширения");
	КонецЕсли;

	Если ИменаПараметровСеанса = Неопределено Или ИменаПараметровСеанса.Найти("ПодключенныеРасширения") <> Неопределено Тогда

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

	Если ИменаПараметровСеанса <> Неопределено И ИменаПараметровСеанса.Найти("ВерсияРасширений") <> Неопределено Тогда

		ПараметрыСеанса.ВерсияРасширений = ВерсияРасширений();
		УстановленныеПараметры.Добавить("ВерсияРасширений");
	КонецЕсли;

	Если ИменаПараметровСеанса = Неопределено И ТекущийРежимЗапуска() <> Неопределено Тогда

		ЗарегистрироватьИспользованиеВерсииРасширений(Истина);
	КонецЕсли;

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

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

Функция УстановленныеРасширения(ПриЗапуске = Ложь) Экспорт

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

	Индекс = Расширения.Количество();
	Пока Индекс > 0 Цикл
		Индекс = Индекс - 1;
		Расширение = Расширения.Получить(Индекс);
		Если Base64Строка(Расширение.ХешСумма) = "AAAAAAAAAAAAAAAAAAAAAAAAAAA=" Тогда
			Расширения.Удалить(Индекс);
		КонецЕсли;
	КонецЦикла;

	Основные    = Новый Массив;
	Исправления = Новый Массив;

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

	// Исключить из контроля расширения только для неразделенных пользователей,
	// так как они не подключаются в областях и не вносят изменений
	// в код конфигурации (это инструменты администратора сервиса).
	НеразделенныйРежим = ОбщегоНазначения.РазделениеВключено()
		И Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных();

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

	УстановленныеРасширения = Новый Структура;
	УстановленныеРасширения.Вставить("Основные", КонтрольныеСуммыРасширений(Основные));
	УстановленныеРасширения.Вставить("Исправления", КонтрольныеСуммыРасширений(Исправления));
	УстановленныеРасширения.Вставить("ОсновныеСостояние", КонтрольныеСуммыРасширений(Основные, "Все"));
	УстановленныеРасширения.Вставить("ИсправленияСостояние", КонтрольныеСуммыРасширений(Исправления, "Все"));

	Если ПриЗапуске И АктивныеРасширения.Количество() = 0 И НеподключенныеРасширения.Количество() = 0
		И РасширенияБазыДанных.Количество() <> 0 И СтандартныеПодсистемыСервер.ЭтоБазоваяВерсияКонфигурации() Тогда

		УстановленныеРасширения.Вставить("РасширенияНедоступны");
	КонецЕсли;

	Если ПриЗапуске Тогда
		УстановитьНачальноеЗарегистрированноеСостояние(УстановленныеРасширения, УстановленныеРасширения);
	КонецЕсли;

	Возврат Новый ФиксированнаяСтруктура(УстановленныеРасширения);

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

// Для функции ДлительныеОперации.ЗапуститьФоновоеЗаданиеСКонтекстомКлиента.

Процедура ВставитьЗарегистрированныйСоставУстановленныхРасширений(Параметры) Экспорт

	РасширенияИзмененыДинамически();

	УстановитьПривилегированныйРежим(Истина);
	УстановленныеРасширения = ПараметрыСеанса.УстановленныеРасширения;
	УстановитьПривилегированныйРежим(Ложь);

	Свойства = Новый Структура;
	Свойства.Вставить("ОсновныеСостояние", УстановленныеРасширения.ОсновныеЗарегистрированноеСостояние);
	Свойства.Вставить("ИсправленияСостояние", УстановленныеРасширения.ИсправленияЗарегистрированноеСостояние);

	Параметры.Вставить("ЗарегистрированныйСоставУстановленныхРасширений", Свойства);

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

// Для процедуры ДлительныеОперации.ВыполнитьСКонтекстомКлиента.

Процедура ВосстановитьЗарегистрированныйСоставУстановленныхРасширений(Параметры) Экспорт

	Если Параметры.Свойство("ЗарегистрированныйСоставУстановленныхРасширений") Тогда
		УстановитьНачальноеЗарегистрированноеСостояние(
			Параметры.ЗарегистрированныйСоставУстановленныхРасширений);
	КонецЕсли;

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

// Возвращаемое значение:
//  ФиксированнаяСтруктура
//

Функция УстановленныеРасширенияПриЗапуске() Экспорт

	Результат = Новый Структура;
	Результат.Вставить("Основные", "");
	Результат.Вставить("Исправления", "");
	Результат.Вставить("ОсновныеСостояние", "");
	Результат.Вставить("ИсправленияСостояние", "");

	ЗаполнитьЗначенияСвойств(Результат, ПараметрыСеанса.УстановленныеРасширения);

	Возврат Новый ФиксированнаяСтруктура(Результат);

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

// Возвращает признак изменения состава расширений после запуска сеанса.
//
// Возвращаемое значение:
//  Булево
//

[Assistant] Процедура УстановкаПараметровСеанса(ИменаПараметровСеанса, УстановленныеПараметры)


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

Процедура ИмяФункции(ИдентификаторыРасширений, ТекстОшибки) Экспорт

	УдаляемыеРасширения = Новый Массив;

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

	Если Не ЗначениеЗаполнено(ТекстОшибки) Тогда
		Попытка
			Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных()
				И РасширенияКонфигурации.Получить().Количество() = 0 Тогда

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

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

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

			ТекстОшибки = ТекстОшибки + Символы.ПС + Символы.ПС
				+ НСтр("ru = 'Удаленные расширения были восстановлены.'");
		КонецЕсли;
	КонецЕсли;

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

// Для общих форм Расширения, УстановленныеИсправления.
//
// Возвращаемое значение:
//  Массив из УникальныйИдентификатор
//

Функция ЗапросыНаОтменуРазрешенийИспользованияВнешнегоМодуля(ИдентификаторыРасширений) Экспорт

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

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

	Разрешения = Новый Массив;

	Для Каждого ИдентификаторРасширения Из ИдентификаторыРасширений Цикл
		ТекущееРасширение = НайтиРасширение(ИдентификаторРасширения);
		Разрешения.Добавить(МодульРаботаВБезопасномРежиме.РазрешениеНаИспользованиеВнешнегоМодуля(
			ТекущееРасширение.Имя, Base64Строка(ТекущееРасширение.ХешСумма)));
	КонецЦикла;

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

	Возврат Запросы;

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

// Возвращаемое значение:
//  Булево
//

Функция ВсеРасширенияПодключены() Экспорт

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

	КоличествоРасширений = РасширенияКонфигурации.Получить().Количество();
	КоличествоПодключенныхРасширений = РасширенияКонфигурации.Получить(,
		ИсточникРасширенийКонфигурации.СеансАктивные).Количество();

	Возврат КоличествоРасширений = КоличествоПодключенныхРасширений;

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

// Возвращаемое значение:
//  Дата - оперативная отметка универсального времени, полученная
//         при первом вызове этой функции в сеансе.
//         Разные ПК имеют разное время, что влияет на результат.
//

Функция ОперативнаяОтметкаВремениСеанса() Экспорт

	УстановитьОтключениеБезопасногоРежима(Истина);
	УстановитьПривилегированныйРежим(Истина);

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

	УстановитьПривилегированныйРежим(Ложь);
	УстановитьОтключениеБезопасногоРежима(Ложь);

	Возврат ОтметкаВремени;

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

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

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

// Возвращает контрольные суммы указанных расширений.
//
// Параметры:
//  Расширения - Массив - получить контрольные суммы указанных расширений.
//  УчитыватьСостояниеРасширений - Булево - учитывать признаки Активно и БезопасныйРежим.
//
// Возвращаемое значение:
//  Строка - строки вида "<Имя расширения> (<Версия расширения>) <Контрольная сумма>".
//

Функция КонтрольныеСуммыРасширений(Расширения, СвойстваПодключения = "", ВключаяКонфигурацию = Истина)

	Список = Новый СписокЗначений;

	Для Каждого Расширение Из Расширения Цикл
		Список.Добавить(КонтрольнаяСуммаРасширения(Расширение, СвойстваПодключения));
	КонецЦикла;

	Если ВключаяКонфигурацию И Список.Количество() <> 0 Тогда
		КонтрольнаяСумма = "#" + Метаданные.Имя + " (" + Метаданные.Версия + ")";
		Список.Добавить(КонтрольнаяСумма);
	КонецЕсли;

	КонтрольныеСуммы = "";
	Для Каждого Элемент Из Список Цикл
		КонтрольныеСуммы = КонтрольныеСуммы + Символы.ПС + Элемент.Значение;
	КонецЦикла;

	Возврат СокрЛ(КонтрольныеСуммы);

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

// Для функций КонтрольныеСуммыРасширений и УстановленныеРасширения.

[Assistant] Процедура УдалитьРасширения(ИдентификаторыРасширений, ТекстОшибки)


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

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

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

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

	Если ТипЗнч(Параметры.ОбновляемыеКомпоненты) <> Тип("Массив") Или Параметры.ОбновляемыеКомпоненты.Количество() = 0 Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Некорректное значение параметра %1 формы %2.'"),
			"ОбновляемыеКомпоненты", "ОбновлениеКомпонентСПортала1СИТС");
	КонецЕсли;

	ДанныеАутентификацииПорталаСохранены = ДанныеАутентификацииПорталаСохранены();
	ДоступнаЗагрузкаСПортала = ВнешниеКомпонентыСлужебный.ДоступнаЗагрузкаСПортала();

	ТекстПояснения = "";
	ПредложитьОбновление = Ложь;
	ПараметрОбновляемыеКомпоненты = Параметры.ОбновляемыеКомпоненты; // Массив из СправочникСсылка.ВнешниеКомпоненты
	РеквизитыКомпонент = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(ПараметрОбновляемыеКомпоненты,
		"Идентификатор, Версия, ОбновлятьСПортала1СИТС");
	Для Каждого ОбновляемаяКомпонента Из ПараметрОбновляемыеКомпоненты Цикл
		Реквизиты = РеквизитыКомпонент[ОбновляемаяКомпонента];
		ТекстПояснения = ТекстПояснения + ВнешниеКомпонентыСлужебный.ПредставлениеКомпоненты(Реквизиты.Идентификатор,
			Реквизиты.Версия) + ?(Реквизиты.ОбновлятьСПортала1СИТС, "", " - " + НСтр("ru = 'обновление отключено'")
			+ ".") + Символы.ПС;

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

	Если ПредложитьОбновление Тогда

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

		Элементы.ПодключитьИнтернетПоддержку.Видимость = Не ДанныеАутентификацииПорталаСохранены;
		Элементы.Закрыть.Видимость = Ложь;

	Иначе
		Элементы.ДекорацияПояснение.Заголовок = ТекстПояснения;
		Элементы.ПодключитьИнтернетПоддержку.Видимость = Ложь;
		Элементы.Загрузить.Видимость = Ложь;
		Элементы.Отмена.Видимость = Ложь;
		Элементы.Закрыть.Видимость = Истина;
	КонецЕсли;

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

&НаКлиенте
Процедура ПриОткрытии(Отказ)

	Если Не ДоступнаЗагрузкаСПортала Тогда
		Отказ = Истина;
	КонецЕсли;

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

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

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

&НаКлиенте
Процедура ПодключитьИнтернетПоддержку(Команда = Неопределено)

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

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

&НаКлиенте
Процедура Загрузить(Команда)

	Если Не ДанныеАутентификацииПорталаСохранены Тогда
		ПодключитьИнтернетПоддержку();
		Возврат;
	КонецЕсли;

	Элементы.Загрузить.Доступность = Ложь;
	Элементы.Страницы.ТекущаяСтраница = Элементы.ДлительнаяОперация;

	ДлительнаяОперация = НачатьОбновлениеКомпонентСПортала();

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

	ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	ПараметрыОжидания.ФормаВладелец = ЭтотОбъект;
	ПараметрыОжидания.ВыводитьОкноОжидания = Ложь;

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

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

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

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

&НаКлиенте
Процедура ПослеПодключенияИнтернетПоддержки(Результат, Параметр) Экспорт

	Если ТипЗнч(Результат) = Тип("Структура") Тогда
		Элементы.ПодключитьИнтернетПоддержку.Видимость = Ложь;
		ДанныеАутентификацииПорталаСохранены = Истина;
	КонецЕсли;

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

&НаСервереБезКонтекста
Функция ДанныеАутентификацииПорталаСохранены()

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

	Возврат Ложь;

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

&НаСервере
Функция НачатьОбновлениеКомпонентСПортала()

	Если Не ВнешниеКомпонентыСлужебный.ДоступнаЗагрузкаСПортала() Тогда
		Возврат Неопределено;
	КонецЕсли;

	ПараметрыПроцедуры = ВнешниеКомпонентыСлужебный.ПараметрыОбновленияКомпонентСПортала();
	ПараметрыПроцедуры.ОбновляемыеКомпоненты = ОбновляемыеКомпоненты.ВыгрузитьЗначения();

	ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
	ПараметрыВыполнения.НаименованиеФоновогоЗадания = НСтр("ru = 'Обновление внешней компоненты.'");

	Возврат ДлительныеОперации.ВыполнитьВФоне("ВнешниеКомпонентыСлужебный.ОбновитьКомпонентыСПортала",
		ПараметрыПроцедуры, ПараметрыВыполнения);

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

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

	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Если Результат.Статус = "Ошибка" Тогда
		КраткоеПредставлениеОшибки = Результат.КраткоеПредставлениеОшибки;
		Элементы.Страницы.ТекущаяСтраница = Элементы.Ошибка;
	КонецЕсли;

	Если Результат.Статус = "Выполнено" Тогда

		РезультатОбновления = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);

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

		Элементы.Страницы.ТекущаяСтраница = Элементы.Выполнено;
		Элементы.Загрузить.Видимость = Ложь;
		Элементы.Отмена.Видимость = Ложь;
		Элементы.Закрыть.Видимость = Истина;
	КонецЕсли;

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

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

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

Tasks-develope/src/cf/Catalogs/ВнешниеКомпоненты/Forms/ОбновлениеКомпонентСПортала1СИТС/Ext/Form/Module.bsl


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

Процедура ИмяФункции(Отказ, СтандартнаяОбработка)

	// Начальное значение настройки до загрузки данных из настроек.
	ВыбиратьИерархически = Истина;

	НовыйХранимыеПараметры();

	МассивПустыхСсылок = Неопределено;
	Параметры.Свойство("Назначение", МассивПустыхСсылок);
	ЗаполнитьПараметрыДинамическихСписков(МассивПустыхСсылок);

	Если Параметры.РежимВыбора Тогда
		СтандартныеПодсистемыСервер.УстановитьКлючНазначенияФормы(ЭтотОбъект, "ВыборПодбор");
		РежимОткрытияОкна = РежимОткрытияОкнаФормы.БлокироватьОкноВладельца;

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

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

	// Скрытие переданного пользователя из формы выбора пользователей.
	Если ТипЗнч(Параметры.СкрываемыеПользователи) = Тип("СписокЗначений") Тогда

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

	ОформитьИСкрытьНедействительныхВнешнихПользователей();
	НастроитьПараметрыСпискаВнешнихПользователейДляКомандыУстановитьПароль();
	НастроитьПорядокГруппыВсеВнешниеПользователи(ГруппыВнешнихПользователей);

	ХранимыеПараметры.Вставить("РасширенныйПодбор", Параметры.РасширенныйПодбор);
	Элементы.ВыбранныеПользователиИГруппы.Видимость = ХранимыеПараметры.РасширенныйПодбор;
	Элементы.ВидПользователей.Видимость = Не ХранимыеПараметры.РасширенныйПодбор;
	ХранимыеПараметры.Вставить("ИспользоватьГруппы",
		ПолучитьФункциональнуюОпцию("ИспользоватьГруппыПользователей"));

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

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

	Если Параметры.РежимВыбора Тогда

		Если Элементы.Найти("ПользователиИБ") <> Неопределено Тогда
			Элементы.ПользователиИБ.Видимость = Ложь;
		КонецЕсли;
		Элементы.СведенияОВнешнихПользователях.Видимость = Ложь;
		Элементы.ГруппыВнешнихПользователей.РежимВыбора =
			ХранимыеПараметры.ВыборГруппВнешнихПользователей;

		// Отключение перетаскивания пользователя в формах выбора и подбора пользователей.
		Элементы.ВнешниеПользователиСписок.РазрешитьНачалоПеретаскивания = Ложь;

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

		Если Параметры.ЗакрыватьПриВыборе = Ложь Тогда
			// Режим подбора.
			Элементы.ВнешниеПользователиСписок.МножественныйВыбор = Истина;

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

			Если ХранимыеПараметры.ВыборГруппВнешнихПользователей Тогда
				Элементы.ГруппыВнешнихПользователей.МножественныйВыбор = Истина;
			КонецЕсли;
		КонецЕсли;
	Иначе
		Элементы.ВнешниеПользователиСписок.РежимВыбора  = Ложь;
		Элементы.ГруппыВнешнихПользователей.РежимВыбора = Ложь;
		Элементы.Комментарии.Видимость = Ложь;

		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
			"ВыбратьВнешнегоПользователя", "Видимость", Ложь);

		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
			"ВыбратьГруппуВнешнихПользователей", "Видимость", Ложь);
	КонецЕсли;

	ХранимыеПараметры.Вставить("ГруппаВсеПользователи",
		Справочники.ГруппыВнешнихПользователей.ВсеВнешниеПользователи);

	ХранимыеПараметры.Вставить("ТекущаяСтрока", Параметры.ТекущаяСтрока);
	НастроитьФормуПоИспользованиюГруппПользователей();
	ХранимыеПараметры.Удалить("ТекущаяСтрока");

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

		Элементы.ФормаИзменитьВыделенные.Видимость = Ложь;
		Элементы.ВнешниеПользователиСписокКонтекстноеМенюИзменитьВыделенные.Видимость = Ложь;
	КонецЕсли;

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

	Если Не УровеньДоступа.УправлениеСписком Тогда
		Элементы.ФормаУстановитьПароль.Видимость = Ложь;
		Элементы.ВнешниеПользователиСписокКонтекстноеМенюУстановитьПароль.Видимость = Ложь;
	КонецЕсли;

	Если ОбщегоНазначения.ЭтоАвтономноеРабочееМесто() Тогда
		ТолькоПросмотр = Истина;
	КонецЕсли;

	Если ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
		Элементы.ЗавершитьИЗакрыть.Отображение = ОтображениеКнопки.Картинка;
	КонецЕсли;

	ПользователиСлужебный.НастроитьПолеНомерКартинкиДинамическогоСписка(ВнешниеПользователиСписок);

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

&НаКлиенте

Процедура ПриОткрытии(Отказ)

	Если Параметры.РежимВыбора Тогда
		ПроверкаИзмененияТекущегоЭлементаФормы();
	КонецЕсли;

#Если МобильныйКлиент Тогда
	Если ХранимыеПараметры.Свойство("ИспользоватьГруппы") И ХранимыеПараметры.ИспользоватьГруппы Тогда
		Элементы.ГруппаГруппы.Заголовок = ?(Элементы.ГруппыВнешнихПользователей.ТекущиеДанные = Неопределено,
			НСтр("ru = 'Группы внешних пользователей'"),
			Строка(Элементы.ГруппыВнешнихПользователей.ТекущиеДанные.Ссылка));
	КонецЕсли;
#КонецЕсли

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

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

	Если ВРег(ИмяСобытия) = ВРег("Запись_ГруппыВнешнихПользователей")
	   И Источник = Элементы.ГруппыВнешнихПользователей.ТекущаяСтрока
	 Или ВРег(ИмяСобытия) = ВРег("РазмещениеПользователейВГруппах")
	 Или ВРег(ИмяСобытия) = ВРег("Запись_ГруппыДоступа") Тогда

		Элементы.ГруппыВнешнихПользователей.Обновить();
		Элементы.ВнешниеПользователиСписок.Обновить();
		ОбновитьСодержимоеФормыПриИзмененииГруппы(ЭтотОбъект);

	ИначеЕсли ВРег(ИмяСобытия) = ВРег("Запись_НаборКонстант") Тогда

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

	КонецЕсли;

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

&НаСервере

Процедура ПередЗагрузкеДанныхИзНастроекНаСервере(Настройки)

	Если ТипЗнч(Настройки["ВыбиратьИерархически"]) = Тип("Булево") Тогда
		ВыбиратьИерархически = Настройки["ВыбиратьИерархически"];
	КонецЕсли;

	Если НЕ ВыбиратьИерархически Тогда
		ОбновитьСодержимоеФормыПриИзмененииГруппы(ЭтотОбъект);
	КонецЕсли;

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

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

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

&НаКлиенте

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


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

Процедура ИмяФункции(Элемент)

	Если СтандартныеПодсистемыКлиент.ЭтоЭлементДинамическогоСписка(Элементы.ВнешниеПользователиСписок) Тогда
		ВозможноСменитьПароль = Элементы.ВнешниеПользователиСписок.ТекущиеДанные.ВозможноСменитьПароль;
	Иначе
		ВозможноСменитьПароль = Ложь;
	КонецЕсли;

	Элементы.ФормаУстановитьПароль.Доступность = ВозможноСменитьПароль;
	Элементы.ВнешниеПользователиСписокКонтекстноеМенюУстановитьПароль.Доступность = ВозможноСменитьПароль;

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

&НаКлиенте

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

	СтандартнаяОбработка = Ложь;

	Если Не ХранимыеПараметры.РасширенныйПодбор Тогда
		ОповеститьОВыборе(Значение);
	Иначе
		ПолучитьКартинкиИЗаполнитьСписокВыбранных(Значение);
	КонецЕсли;

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

&НаКлиенте

Процедура ВнешниеПользователиСписокПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа)

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

	ПараметрыФормы = Новый Структура(
		"ГруппаНовогоВнешнегоПользователя", Элементы.ГруппыВнешнихПользователей.ТекущаяСтрока);

	Если ЗначениеЗаполнено(ХранимыеПараметры.ОтборОбъектАвторизации) Тогда

		ПараметрыФормы.Вставить(
			"ОбъектАвторизацииНовогоВнешнегоПользователя",
			ХранимыеПараметры.ОтборОбъектАвторизации);
	КонецЕсли;

	Если Копирование И Элемент.ТекущиеДанные <> Неопределено Тогда
		ПараметрыФормы.Вставить("ЗначениеКопирования", Элемент.ТекущаяСтрока);
	КонецЕсли;

	ОткрытьФорму(
		"Справочник.ВнешниеПользователи.ФормаОбъекта",
		ПараметрыФормы,
		Элементы.ВнешниеПользователиСписок);

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

&НаКлиенте

Процедура ВнешниеПользователиСписокПередНачаломИзменения(Элемент, Отказ)

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

	Если Не ЗначениеЗаполнено(Элемент.ТекущаяСтрока) Тогда
		Возврат;
	КонецЕсли;

	ПараметрыФормы = Новый Структура("Ключ", Элемент.ТекущаяСтрока);
	ОткрытьФорму("Справочник.ВнешниеПользователи.ФормаОбъекта", ПараметрыФормы, Элемент);

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

&НаСервереБезКонтекста

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

	ПользователиСлужебный.ДинамическийСписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки);

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

&НаКлиенте

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

	СтандартнаяОбработка = Ложь;

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

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

#Область ОбработчикиСобытийЭлементовТаблицыФормыСписокВыбранныхПользователейИГрупп

&НаКлиенте

Процедура СписокВыбранныхПользователейИГруппВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)

	УдалитьИзСпискаВыбранных();
	Модифицированность = Истина;

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

&НаКлиенте

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

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

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

&НаКлиенте

Процедура СоздатьГруппуВнешнихПользователей(Команда)

	ТекущиеДанные = Элементы.ГруппыВнешнихПользователей.ТекущиеДанные;
	Если Не СтандартныеПодсистемыКлиент.ЭтоЭлементДинамическогоСписка(ТекущиеДанные) Тогда
		Возврат;
	КонецЕсли;

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

	Элементы.ГруппыВнешнихПользователей.ДобавитьСтроку();

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

&НаКлиенте

Процедура НазначитьГруппы(Команда)

	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("Пользователи", Элементы.ВнешниеПользователиСписок.ВыделенныеСтроки);
	ПараметрыФормы.Вставить("ВнешниеПользователи", Истина);

	ОткрытьФорму("ОбщаяФорма.ГруппыПользователей", ПараметрыФормы);

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

&НаКлиенте

Процедура УстановитьПароль(Команда)

	ТекущиеДанные = Элементы.ВнешниеПользователиСписок.ТекущиеДанные;

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

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

&НаКлиенте

Процедура ЗавершитьИЗакрыть(Команда)

	Если ХранимыеПараметры.РасширенныйПодбор Тогда
		МассивПользователей = РезультатВыбора();
		ОповеститьОВыборе(МассивПользователей);
		Модифицированность = Ложь;
		Закрыть(МассивПользователей);
	КонецЕсли;

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

&НаКлиенте

Процедура ВыбратьПользователяКоманда(Команда)

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

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

&НаКлиенте

Процедура ОтменитьВыборПользователяИлиГруппы(Команда)

		УдалитьИзСпискаВыбранных();

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

&НаКлиенте

Процедура ОчиститьСписокВыбранныхПользователейИГрупп(Команда)

	УдалитьИзСпискаВыбранных(Истина);

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

&НаКлиенте

Процедура ВыбратьГруппу(Команда)

	МассивГрупп = Элементы.ГруппыВнешнихПользователей.ВыделенныеСтроки;
	ПолучитьКартинкиИЗаполнитьСписокВыбранных(МассивГрупп);

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

&НаКлиенте

Процедура СведенияОВнешнихПользователях(Команда)

	ОткрытьФорму(
		"Отчет.СведенияОПользователях.ФормаОбъекта",
		Новый Структура("КлючВарианта", "СведенияОВнешнихПользователях"),
		ЭтотОбъект,
		"СведенияОВнешнихПользователях");

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

////////////////////////////////////////////////////////////////////////////////
// Поддержка группового изменения объектов.

&НаКлиенте

Процедура ИзменитьВыделенные(Команда)

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

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

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

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

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

Функция НовыйХранимыеПараметры()

	ХранимыеПараметры = Новый Структура;
	ХранимыеПараметры.Вставить("ВыборГруппВнешнихПользователей", Параметры.ВыборГруппВнешнихПользователей);

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

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

&НаСервере

Процедура ЗаполнитьПараметрыДинамическихСписков(МассивПустыхСсылок = Неопределено)

	Используется = МассивПустыхСсылок <> Неопределено И МассивПустыхСсылок.Количество() <> 0;

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

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

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

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

&НаСервере

[Assistant] Процедура ВнешниеПользователиСписокПриАктивизацииСтроки(Элемент)


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

Процедура ИмяФункции()

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

	ЭлементЦветаОформления = ЭлементУсловногоОформления.Оформление.Элементы.Найти("TextColor");
	ЭлементЦветаОформления.Значение = Метаданные.ЭлементыСтиля.ТекстЗапрещеннойЯчейкиЦвет.Значение;
	ЭлементЦветаОформления.Использование = Истина;

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

	ЭлементОформляемогоПоля = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
	ЭлементОформляемогоПоля.Поле = Новый ПолеКомпоновкиДанных("ВнешниеПользователиСписок");
	ЭлементОформляемогоПоля.Использование = Истина;

	ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
		ВнешниеПользователиСписок, "Недействителен", Ложь, , , Истина);

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

&НаСервере

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

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

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

	ОбновитьЗначениеПараметраКомпоновкиДанных(ВнешниеПользователиСписок, "ВозможноСменитьТолькоСвойПароль",
		Не Пользователи.ЭтоПолноправныйПользователь());

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

&НаСервере

Процедура НастроитьПорядокГруппыВсеВнешниеПользователи(Список)

	Перем Порядок;

	// Порядок.
	Порядок = Список.КомпоновщикНастроек.Настройки.Порядок;
	Порядок.ИдентификаторПользовательскойНастройки = "ОсновнойПорядок";

	Порядок.Элементы.Очистить();

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

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

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

&НаКлиенте

Процедура ПроверкаИзмененияТекущегоЭлементаФормы()

	Если ТекущийЭлемент <> ПоследнийЭлемент Тогда
		ПриИзмененииТекущегоЭлементаФормы();
		ПоследнийЭлемент = ТекущийЭлемент;
	КонецЕсли;

#Если ВебКлиент Тогда
	ПодключитьОбработчикОжидания("ПроверкаИзмененияТекущегоЭлементаФормы", 0.7, Истина);
#Иначе
	ПодключитьОбработчикОжидания("ПроверкаИзмененияТекущегоЭлементаФормы", 0.1, Истина);
#КонецЕсли

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

&НаКлиенте

Процедура ПриИзмененииТекущегоЭлементаФормы()

	Если ТекущийЭлемент = Элементы.ГруппыВнешнихПользователей Тогда
		Элементы.Комментарии.ТекущаяСтраница = Элементы.КомментарийГруппы;

	ИначеЕсли ТекущийЭлемент = Элементы.ВнешниеПользователиСписок Тогда
		Элементы.Комментарии.ТекущаяСтраница = Элементы.КомментарийПользователя;

	КонецЕсли

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

&НаСервере

Процедура УдалитьИзСпискаВыбранных(УдалитьВсех = Ложь)

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

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

	ОбновитьЗаголовокСпискаВыбранныхПользователейИГрупп();

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

&НаКлиенте

Процедура ПолучитьКартинкиИЗаполнитьСписокВыбранных(МассивВыбранныхЭлементов)

	ВыбранныеЭлементыИКартинки = Новый Массив;
	Для Каждого ВыбранныйЭлемент Из МассивВыбранныхЭлементов Цикл

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

		ВыбранныеЭлементыИКартинки.Добавить(
			Новый Структура("ВыбранныйЭлемент, НомерКартинки", ВыбранныйЭлемент, НомерКартинки));
	КонецЦикла;

	ЗаполнитьСписокВыбранныхПользователейИГрупп(ВыбранныеЭлементыИКартинки);

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

&НаСервере

Функция РезультатВыбора()

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

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

&НаСервере

[Assistant] Процедура ОформитьИСкрытьНедействительныхВнешнихПользователей()


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

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

Процедура ОпределитьНесоответствияПользователяСПользователемИБ(ПараметрыЗаписи = Неопределено)
// Проверка соответствия свойства ПолноеИмя пользователяИБ и
	// реквизита Наименование внешнего пользователя. А также значений свойств по умолчанию.

	ПоказатьНесоответствие = Истина;
	ПоказатьКомандыУстраненияРазличий = Ложь;

	Если НЕ ПользовательИБСуществует Тогда
		ПоказатьНесоответствие = Ложь;

	ИначеЕсли Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
		ПользовательИБПолноеИмя = Объект.Наименование;
		ПоказатьНесоответствие = Ложь;

	ИначеЕсли УровеньДоступа.УправлениеСписком Тогда

		УточнениеСвойств = Новый Массив;
		ЕстьРазличияУстранимыеБезАдминистратора = Ложь;

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

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

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

		Если ПользовательИБПолноеИмя <> Объект.Наименование Тогда
			ЕстьРазличияУстранимыеБезАдминистратора = Истина;

			УточнениеСвойств.Вставить(0, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Полное имя ""%1""'"),
				ПользовательИБПолноеИмя));
		КонецЕсли;

		Если ПользовательИБПользовательОС <> "" Тогда
			УточнениеСвойств.Добавить(НСтр("ru = 'Пользователь ОС (указан)'"));
		КонецЕсли;

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

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

		УстановитьПривилегированныйРежим(Истина);
		ОтличаютсяСохраненныеСвойстваПользователяИБ = ЗначениеЗаполнено(Объект.Ссылка)
			И РегистрыСведений.СведенияОПользователях.ОтличаютсяСохраненныеСвойстваПользователяИБ(Объект);
		УстановитьПривилегированныйРежим(Ложь);

		ЕстьРазличияУстранимыеБезАдминистратора =
			ЕстьРазличияУстранимыеБезАдминистратора
			Или ОтличаютсяСохраненныеСвойстваПользователяИБ;

		Если УточнениеСвойств.Количество() > 0
		 Или ОтличаютсяСохраненныеСвойстваПользователяИБ Тогда

			СтрокаУточненияСвойств = "";
			ТекущаяСтрока = "";
			Для каждого УточнениеСвойства Из УточнениеСвойств Цикл
				Если СтрДлина(ТекущаяСтрока + УточнениеСвойства) > 90 Тогда
					СтрокаУточненияСвойств = СтрокаУточненияСвойств + СокрП(ТекущаяСтрока) + ", " + Символы.ПС;
					ТекущаяСтрока = "";
				КонецЕсли;
				ТекущаяСтрока = ТекущаяСтрока + ?(ЗначениеЗаполнено(ТекущаяСтрока), ", ", "") + УточнениеСвойства;
			КонецЦикла;
			Если ЗначениеЗаполнено(ТекущаяСтрока) Тогда
				СтрокаУточненияСвойств = СтрокаУточненияСвойств + ТекущаяСтрока;
			КонецЕсли;
			Если ПоказатьКомандыУстраненияРазличий
			 Или ЕстьРазличияУстранимыеБезАдминистратора
			   И ДействияВФорме.СвойстваЭлемента = "Редактирование" Тогда

				Рекомендация = Символы.ПС
					+ НСтр("ru = 'Нажмите ""Записать"", чтобы устранить различия и не выводить это предупреждение.'");

			ИначеЕсли Не Пользователи.ЭтоПолноправныйПользователь() Тогда
				Рекомендация = Символы.ПС
					+ НСтр("ru = 'Обратитесь к администратору, чтобы устранить различия.'");
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура ОпределитьНесоответствияПользователяСПользователемИБ(ПараметрыЗаписи = Неопределено)

	// Проверка соответствия свойства ПолноеИмя пользователяИБ и
	// реквизита Наименование внешнего пользователя. А также значений свойств по умолчанию.

	ПоказатьНесоответствие = Истина;
	ПоказатьКомандыУстраненияРазличий = Ложь;

	Если НЕ ПользовательИБСуществует Тогда
		ПоказатьНесоответствие = Ложь;

	ИначеЕсли Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
		ПользовательИБПолноеИмя = Объект.Наименование;
		ПоказатьНесоответствие = Ложь;

	ИначеЕсли УровеньДоступа.УправлениеСписком Тогда

		УточнениеСвойств = Новый Массив;
		ЕстьРазличияУстранимыеБезАдминистратора = Ложь;

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

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

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

		Если ПользовательИБПолноеИмя <> Объект.Наименование Тогда
			ЕстьРазличияУстранимыеБезАдминистратора = Истина;

			УточнениеСвойств.Вставить(0, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Полное имя ""%1""'"),
				ПользовательИБПолноеИмя));
		КонецЕсли;

		Если ПользовательИБПользовательОС <> "" Тогда
			УточнениеСвойств.Добавить(НСтр("ru = 'Пользователь ОС (указан)'"));
		КонецЕсли;

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

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

		УстановитьПривилегированныйРежим(Истина);
		ОтличаютсяСохраненныеСвойстваПользователяИБ = ЗначениеЗаполнено(Объект.Ссылка)
			И РегистрыСведений.СведенияОПользователях.ОтличаютсяСохраненныеСвойстваПользователяИБ(Объект);
		УстановитьПривилегированныйРежим(Ложь);

		ЕстьРазличияУстранимыеБезАдминистратора =
			ЕстьРазличияУстранимыеБезАдминистратора
			Или ОтличаютсяСохраненныеСвойстваПользователяИБ;

		Если УточнениеСвойств.Количество() > 0
		 Или ОтличаютсяСохраненныеСвойстваПользователяИБ Тогда

			СтрокаУточненияСвойств = "";
			ТекущаяСтрока = "";
			Для каждого УточнениеСвойства Из УточнениеСвойств Цикл
				Если СтрДлина(ТекущаяСтрока + УточнениеСвойства) > 90 Тогда
					СтрокаУточненияСвойств = СтрокаУточненияСвойств + СокрП(ТекущаяСтрока) + ", " + Символы.ПС;
					ТекущаяСтрока = "";
				КонецЕсли;
				ТекущаяСтрока = ТекущаяСтрока + ?(ЗначениеЗаполнено(ТекущаяСтрока), ", ", "") + УточнениеСвойства;
			КонецЦикла;
			Если ЗначениеЗаполнено(ТекущаяСтрока) Тогда
				СтрокаУточненияСвойств = СтрокаУточненияСвойств + ТекущаяСтрока;
			КонецЕсли;
			Если ПоказатьКомандыУстраненияРазличий
			 Или ЕстьРазличияУстранимыеБезАдминистратора
			   И ДействияВФорме.СвойстваЭлемента = "Редактирование" Тогда

				Рекомендация = Символы.ПС
					+ НСтр("ru = 'Нажмите ""Записать"", чтобы устранить различия и не выводить это предупреждение.'");

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

	Элементы.СвойстваОбработкаНесоответствия.Видимость = ПоказатьНесоответствие;
	Элементы.СвойстваПояснениеНесоответствия.ВертикальноеПоложение = ?(ЗначениеЗаполнено(Рекомендация),
		ВертикальноеПоложениеЭлемента.Верх, ВертикальноеПоложениеЭлемента.Центр);

	// Определение сопоставления несуществующего пользователя ИБ с пользователем в справочнике.
	ЕстьНовоеСопоставлениеСНесуществующимПользователемИБ =
		НЕ ПользовательИБСуществует И ЗначениеЗаполнено(Объект.ИдентификаторПользователяИБ);

	Если ПараметрыЗаписи <> Неопределено
	   И ЕстьСопоставлениеСНесуществующимПользователемИБ
	   И НЕ ЕстьНовоеСопоставлениеСНесуществующимПользователемИБ Тогда

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

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

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

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

	Элементы.СопоставлениеПояснениеНесоответствия.Заголовок =
		НСтр("ru = 'Несуществующий пользователь информационной базы.'") + Рекомендация;

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

////////////////////////////////////////////////////////////////////////////////
// Начальное заполнение, проверка заполнения, доступность свойств.

&НаКлиентеНаСервереБезКонтекста


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

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

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

	Ошибки = Неопределено;

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

	// Проверка незаполненных и повторяющихся внешних пользователей.
	ПроверенныеРеквизитыОбъекта.Добавить("Состав.ВнешнийПользователь");

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

	Для каждого ТекущаяСтрока Из Состав Цикл
		НомерСтроки = Состав.Индекс(ТекущаяСтрока);

		// Проверка заполнения значения.
		Если НЕ ЗначениеЗаполнено(ТекущаяСтрока.ВнешнийПользователь) Тогда
			ОбщегоНазначенияКлиентСервер.ДобавитьОшибкуПользователю(Ошибки,
				"Объект.Состав[%1].ВнешнийПользователь",
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)

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

	Ошибки = Неопределено;

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

	// Проверка незаполненных и повторяющихся внешних пользователей.
	ПроверенныеРеквизитыОбъекта.Добавить("Состав.ВнешнийПользователь");

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

	Для каждого ТекущаяСтрока Из Состав Цикл
		НомерСтроки = Состав.Индекс(ТекущаяСтрока);

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

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

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

	ОбщегоНазначения.УдалитьНепроверяемыеРеквизитыИзМассива(ПроверяемыеРеквизиты, ПроверенныеРеквизитыОбъекта);

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

Процедура ПередЗаписью(Отказ)

	// АПК:75-выкл проверка ОбменДанными.Загрузка должна быть после блокировки регистра.
	// Блокировка всего регистра используется вместо установки разделяемой блокировки на справочник,
	// которая приводит к взаимоблокировке при иерархическом обновлении составов групп пользователей,
	// а также вместо последовательной исключительной блокировки регистра в разрезе групп,
	// которая также приводит к взаимоблокировке в ряде случаев.
	Блокировка = Новый БлокировкаДанных;
	Блокировка.Добавить("РегистрСведений.СоставыГруппПользователей");
	Блокировка.Заблокировать();
	// АПК:75-вкл

	Если ОбменДанными.Загрузка Тогда
		Возврат;
	КонецЕсли;

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

	ЭтоНовый = ЭтоНовый();

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

	ТекстОшибки = ТекстОшибкиПроверкиРодителя();
	Если ЗначениеЗаполнено(ТекстОшибки) Тогда
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

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

		СтарыеЗначения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(
			Ссылка, "ВсеОбъектыАвторизации, Родитель");

		СтарыйРодитель                      = СтарыеЗначения.Родитель;
		СтароеЗначениеВсеОбъектыАвторизации = СтарыеЗначения.ВсеОбъектыАвторизации;

		Если ЗначениеЗаполнено(Ссылка)
		   И Ссылка <> Справочники.ГруппыВнешнихПользователей.ВсеВнешниеПользователи Тогда

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

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

Процедура ПриЗаписи(Отказ)

	Если ОбменДанными.Загрузка Тогда
		Возврат;
	КонецЕсли;

	Если ПользователиСлужебный.ЗапретРедактированияРолей() Тогда
		ИзменилсяСоставРолейГруппыВнешнихПользователей = Ложь;

	Иначе
		ИзменилсяСоставРолейГруппыВнешнихПользователей =
			ПользователиСлужебный.РазличияЗначенийКолонки(
				"Роль",
				Роли.Выгрузить(),
				СтарыйСоставРолейГруппыВнешнихПользователей).Количество() <> 0;
	КонецЕсли;

	УчастникиИзменений = Новый Соответствие;
	ИзмененныеГруппы   = Новый Соответствие;

	Если Ссылка <> Справочники.ГруппыВнешнихПользователей.ВсеВнешниеПользователи Тогда

		Если ВсеОбъектыАвторизации
		 ИЛИ СтароеЗначениеВсеОбъектыАвторизации = Истина Тогда

			ПользователиСлужебный.ОбновитьСоставыГруппВнешнихПользователей(
				Ссылка, , УчастникиИзменений, ИзмененныеГруппы);
		Иначе
			ИзмененияСостава = ПользователиСлужебный.РазличияЗначенийКолонки(
				"ВнешнийПользователь",
				Состав.Выгрузить(),
				СтарыйСоставГруппыВнешнихПользователей);

			ПользователиСлужебный.ОбновитьСоставыГруппВнешнихПользователей(
				Ссылка, ИзмененияСостава, УчастникиИзменений, ИзмененныеГруппы);

			Если СтарыйРодитель <> Родитель Тогда

				Если ЗначениеЗаполнено(Родитель) Тогда
					ПользователиСлужебный.ОбновитьСоставыГруппВнешнихПользователей(
						Родитель, , УчастникиИзменений, ИзмененныеГруппы);
				КонецЕсли;

				Если ЗначениеЗаполнено(СтарыйРодитель) Тогда
					ПользователиСлужебный.ОбновитьСоставыГруппВнешнихПользователей(
						СтарыйРодитель, , УчастникиИзменений, ИзмененныеГруппы);
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;

		ПользователиСлужебный.ОбновитьИспользуемостьСоставовГруппПользователей(
			Ссылка, УчастникиИзменений, ИзмененныеГруппы);
	КонецЕсли;

	Если ИзменилсяСоставРолейГруппыВнешнихПользователей Тогда
		ПользователиСлужебный.ОбновитьРолиВнешнихПользователей(Ссылка);
	КонецЕсли;

	ПользователиСлужебный.ПослеОбновленияСоставовГруппВнешнихПользователей(
		УчастникиИзменений, ИзмененныеГруппы);

	ИнтеграцияПодсистемБСП.ПослеДобавленияИзмененияПользователяИлиГруппы(Ссылка, ЭтоНовый);

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

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

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

Процедура ЗаполнитьНазначениеВсемиТипамиВнешнихПользователей()

	Назначение.Очистить();

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

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


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

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

Функция ОбновитьГруппыДоступаПрофиля(Профиль, ОбновлятьГруппыДоступаСУстаревшимиНастройками = Ложь)
Экспорт

	ГруппаДоступаОбновлена = Ложь;

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

		Если СвойстваВидаДоступа = Неопределено Тогда
			ВидыДоступаПрофиля.Удалить(Строка);
		КонецЕсли;
		Индекс = Индекс - 1;
	КонецЦикла;

	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("ПрофильАдминистратор",        УправлениеДоступом.ПрофильАдминистратор());
	Запрос.УстановитьПараметр("ГруппаДоступаАдминистраторы", УправлениеДоступом.ГруппаДоступаАдминистраторы());
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ГруппыДоступа.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.ГруппыДоступа КАК ГруппыДоступа
	|ГДЕ
	|	НЕ(ГруппыДоступа.Профиль <> &Профиль
	|				И НЕ(&Профиль = &ПрофильАдминистратор
	|						И ГруппыДоступа.Ссылка = &ГруппаДоступаАдминистраторы))";

	Запрос.УстановитьПараметр("Профиль", Профиль);
	Выборка = Запрос.Выполнить().Выбрать();

	Пока Выборка.Следующий() Цикл
		// Проверка необходимости/возможности обновления группы доступа.
		ГруппаДоступа = Выборка.Ссылка.ПолучитьОбъект();

		Если ГруппаДоступа.Ссылка = УправлениеДоступом.ГруппаДоступаАдминистраторы()
		   И ГруппаДоступа.Профиль <> УправлениеДоступом.ПрофильАдминистратор() Тогда
			// Установка профиля Администратор, если не задан.
			ГруппаДоступа.Профиль = УправлениеДоступом.ПрофильАдминистратор();
		КонецЕсли;

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

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

[Assistant]
Функция ОбновитьГруппыДоступаПрофиля(Профиль, ОбновлятьГруппыДоступаСУстаревшимиНастройками = Ложь) Экспорт

	ГруппаДоступаОбновлена = Ложь;

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

		Если СвойстваВидаДоступа = Неопределено Тогда
			ВидыДоступаПрофиля.Удалить(Строка);
		КонецЕсли;
		Индекс = Индекс - 1;
	КонецЦикла;

	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("ПрофильАдминистратор",        УправлениеДоступом.ПрофильАдминистратор());
	Запрос.УстановитьПараметр("ГруппаДоступаАдминистраторы", УправлениеДоступом.ГруппаДоступаАдминистраторы());
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ГруппыДоступа.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.ГруппыДоступа КАК ГруппыДоступа
	|ГДЕ
	|	НЕ(ГруппыДоступа.Профиль <> &Профиль
	|				И НЕ(&Профиль = &ПрофильАдминистратор
	|						И ГруппыДоступа.Ссылка = &ГруппаДоступаАдминистраторы))";

	Запрос.УстановитьПараметр("Профиль", Профиль);
	Выборка = Запрос.Выполнить().Выбрать();

	Пока Выборка.Следующий() Цикл
		// Проверка необходимости/возможности обновления группы доступа.
		ГруппаДоступа = Выборка.Ссылка.ПолучитьОбъект();

		Если ГруппаДоступа.Ссылка = УправлениеДоступом.ГруппаДоступаАдминистраторы()
		   И ГруппаДоступа.Профиль <> УправлениеДоступом.ПрофильАдминистратор() Тогда
			// Установка профиля Администратор, если не задан.
			ГруппаДоступа.Профиль = УправлениеДоступом.ПрофильАдминистратор();
		КонецЕсли;

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

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

					НоваяСтрока = ГруппаДоступа.ВидыДоступа.Добавить();
					НоваяСтрока.ВидДоступа   = СтрокаВидаДоступа.ВидДоступа;
					НоваяСтрока.ВсеРазрешены = СтрокаВидаДоступа.ВсеРазрешены;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;

		Если ГруппаДоступа.Модифицированность() Тогда

			Если Не ОбновлениеИнформационнойБазы.ВыполняетсяОбновлениеИнформационнойБазы()
			   И Не ОбновлениеИнформационнойБазы.ЭтоВызовИзОбработчикаОбновления() Тогда

				ЗаблокироватьДанныеДляРедактирования(ГруппаДоступа.Ссылка, ГруппаДоступа.ВерсияДанных);
			КонецЕсли;

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

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

			Если Не ОбновлениеИнформационнойБазы.ВыполняетсяОбновлениеИнформационнойБазы()
			   И Не ОбновлениеИнформационнойБазы.ЭтоВызовИзОбработчикаОбновления() Тогда

				РазблокироватьДанныеДляРедактирования(ГруппаДоступа.Ссылка);
			КонецЕсли;

		КонецЕсли;
	КонецЦикла;

	Возврат ГруппаДоступаОбновлена;

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

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

Функция РодительПерсональныхГруппДоступа(Знач НеСоздавать = Ложь, НаименованиеГруппыЭлементов = "") Экспорт

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

	НаименованиеГруппыЭлементов = НСтр("ru = 'Персональные группы доступа'");

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

	Возврат ГруппаЭлементов;

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

Функция ИзменилисьВидыИлиЗначенияДоступа(СтарыеЗначения, ТекущийОбъект) Экспорт

	Если СтарыеЗначения.Ссылка <> ТекущийОбъект.Ссылка Тогда
		Возврат Истина;
	КонецЕсли;

	ВидыДоступа     = СтарыеЗначения.ВидыДоступа.Выгрузить();
	ЗначенияДоступа = СтарыеЗначения.ЗначенияДоступа.Выгрузить();

	Если ВидыДоступа.Количество()     <> ТекущийОбъект.ВидыДоступа.Количество()
	 Или ЗначенияДоступа.Количество() <> ТекущийОбъект.ЗначенияДоступа.Количество() Тогда

		Возврат Истина;
	КонецЕсли;

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

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

	Возврат Ложь;

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


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

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

	Если ОбщегоНазначения.РазделениеВключено() Тогда
		// В модели сервиса не поддерживается.
		Возврат;
	КонецЕсли;

	Если Не ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
		Возврат;
	КонецЕсли;

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

	Блокировка = Новый БлокировкаДанных;
	Блокировка.Добавить("Справочник.ИдентификаторыОбъектовМетаданных");

	НачатьТранзакцию();
	Попытка
		Блокировка.Заблокировать();

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

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

		Для каждого Объект Из Объекты Цикл
			СвойстваЗагружаемого = ТаблицаЗагружаемых.Добавить();
			СвойстваЗагружаемого.Объект = Объект;

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

			// Предварительная обработка.

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

				СвойстваЗагружаемого.ОбъектМетаданныхПоПолномуИмени =
					МетаданныеНайтиПоПолномуИмени(Объект.ПолноеИмя);

				Если СвойстваЗагружаемого.ОбъектМетаданныхПоКлючу = Неопределено
				   И СвойстваЗагружаемого.ОбъектМетаданныхПоПолномуИмени = Неопределено
				   И Объект.ПометкаУдаления <> Истина Тогда
					// Если по какой-то причине загружаемый объект не найден в метаданных,
					// его следует пометить на удаление.
					Объект.ПометкаУдаления = Истина;
				КонецЕсли;
			КонецЕсли;

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

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

				СвойстваЗагружаемого.Совпадает = Истина;
			КонецЕсли;

			Если Свойства <> Неопределено Тогда
				Выгрузка.Удалить(Свойства); // Загружаемые не нужно переименовывать.
			КонецЕсли;
		КонецЦикла;
		ТаблицаЗагружаемых.Индексы.Добавить("Ссылка");

		// Переименование существующих элементов (без загружаемых) для поиска дублей.

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

		// Подготовка загружаемых объектов и дублей в существующих.

		ОбъектыДляЗаписи = Новый Массив; // Массив из СправочникОбъект.ИдентификаторыОбъектовМетаданных -
		ПолныеИменаЗагружаемых = Новый Соответствие;
		КлючиЗагружаемых = Новый Соответствие;

		Для каждого СвойстваЗагружаемого Из ТаблицаЗагружаемых Цикл
			Объект = СвойстваЗагружаемого.Объект; // СправочникОбъект.ИдентификаторыОбъектовМетаданных
			Ссылка = СвойстваЗагружаемого.Ссылка;

			Если СвойстваЗагружаемого.Совпадает Тогда
				Продолжить; // Точно совпадающие объекты не требуется загружать.
			КонецЕсли;

			Если ЭтоКоллекция(Ссылка) Тогда
				ОбъектыДляЗаписи.Добавить(Объект);
				Продолжить;
			КонецЕсли;

			// Проверка отсутствия дублей среди загружаемых элементов.

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

			КлючОбъектаМетаданных = Объект.КлючОбъектаМетаданных.Получить();
			Если ТипЗнч(КлючОбъектаМетаданных) = Тип("Тип")
			   И КлючОбъектаМетаданных <> Тип("Неопределено") Тогда

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

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

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

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

			ОбъектыДляЗаписи.Добавить(Объект);
		КонецЦикла;

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

		ПодготовитьСписокНовыхПодсистемВПодчиненномУзле(ОбъектыДляЗаписи);

		// Загрузка объектов.
		Для каждого Объект Из ОбъектыДляЗаписи Цикл
			Объект.ОбменДанными.Загрузка = Истина;
			Объект.Записать();
		КонецЦикла;

		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;

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

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

[Assistant] Процедура ЗагрузитьДанныеВПодчиненныйУзел(Объекты)


[System] Ты анализируешь код 1С и подбираешь точные имена для процедур и функций.

[User]
Восстанови осмысленное имя процедуры или функции на 1С по её телу. Верни только полную сигнатуру первой строки.

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

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

		ВызватьИсключениеПоОшибке(Истина,
			ОписаниеОшибкиИдентификаторыОбъектовРасширенийНедоступныВНеразделенномРежиме());
	КонецЕсли;

	ПроверкаИспользования(ОбъектыРасширений);

	УстановитьОтключениеБезопасногоРежима(Истина);
	УстановитьПривилегированныйРежим(Истина);

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

	ОбновитьДанные(ЕстьТекущиеИзменения, ЕстьУдаленные, ТолькоПроверка,
		ЕстьКритичныеИзменения, СписокКритичныхИзменений, ОбъектыРасширений);

	Если ЕстьТекущиеИзменения Тогда
		ЕстьИзменения = Истина;
	КонецЕсли;

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

		СтандартныеПодсистемыСервер.ОбновитьПараметрРаботыПрограммы(
			"СтандартныеПодсистемы.БазоваяФункциональность.ИдентификаторыОбъектовМетаданных", Истина);
	КонецЕсли;

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

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

////////////////////////////////////////////////////////////////////////////////
// Реализация процедур, объявленных в других модулях.

// См. ОбщегоНазначения.ИдентификаторОбъектаМетаданных.

Функция ИдентификаторОбъектаМетаданных(ОписаниеОбъектаМетаданных, ВызыватьИсключение) Экспорт

	ТипОписанияОбъектаМетаданных = ТипЗнч(ОписаниеОбъектаМетаданных);
	Если ТипОписанияОбъектаМетаданных = Тип("Тип") Тогда

		ОбъектМетаданных = Метаданные.НайтиПоТипу(ОписаниеОбъектаМетаданных);

		Если ОбъектМетаданных <> Неопределено Тогда
			ПолноеИмяОбъектаМетаданных = ОбъектМетаданных.ПолноеИмя();

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

	ИначеЕсли ТипОписанияОбъектаМетаданных = Тип("Строка") Тогда
		ПолноеИмяОбъектаМетаданных = ОписаниеОбъектаМетаданных;

	ИначеЕсли ТипОписанияОбъектаМетаданных = Тип("ОбъектМетаданных") Тогда
		ПолноеИмяОбъектаМетаданных = ОписаниеОбъектаМетаданных.ПолноеИмя();

	ИначеЕсли Не ВызыватьИсключение Тогда
		Возврат Null;
	Иначе
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Некорректный тип параметра %1 в функции %2:
			           |""%3"".'"),
			"ОписаниеОбъектаМетаданных",
			"ОбщегоНазначения.ИдентификаторОбъектаМетаданных",
			ТипОписанияОбъектаМетаданных);
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

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

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

	Возврат Идентификатор;

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

// См. ОбщегоНазначения.ИдентификаторыОбъектовМетаданных.

Функция ИдентификаторыОбъектовМетаданных(ОписаниеОбъектовМетаданных, ВызыватьИсключение = Истина, ОдинЭлемент = Ложь) Экспорт

	УстановитьОтключениеБезопасногоРежима(Истина);
	УстановитьПривилегированныйРежим(Истина);
	ИдентификаторыПоПолнымИменам = КэшИдентификаторов().ИдентификаторыПоПолнымИменам;
	УстановитьПривилегированныйРежим(Ложь);
	УстановитьОтключениеБезопасногоРежима(Ложь);

	Результат = Новый Соответствие;
	ПолныеИменаБезКэша = Новый Массив;
	Для Каждого ОписаниеОбъектаМетаданных Из ОписаниеОбъектовМетаданных Цикл

		ТипОписанияОбъектаМетаданных = ТипЗнч(ОписаниеОбъектаМетаданных);
		Если ТипОписанияОбъектаМетаданных = Тип("Тип") Тогда

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

		ИначеЕсли ТипОписанияОбъектаМетаданных = Тип("Строка") Тогда
			ПолноеИмя = ОписаниеОбъектаМетаданных;

		ИначеЕсли ТипОписанияОбъектаМетаданных = Тип("ОбъектМетаданных") Тогда
			ПолноеИмя = ОписаниеОбъектаМетаданных.ПолноеИмя();

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

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

	Если ПолныеИменаБезКэша.Количество() = 0 Тогда
		Возврат Результат;
	КонецЕсли;

	Идентификаторы = ИдентификаторыОбъектовМетаданныхСПопыткойПовтора(ПолныеИменаБезКэша,
		ВызыватьИсключение, ОдинЭлемент);

	Для Каждого КлючИЗначение Из Идентификаторы Цикл
		Результат.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
		ИдентификаторыПоПолнымИменам.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
	КонецЦикла;

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

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

// См. ОбщегоНазначения.ОбъектМетаданныхПоИдентификатору.

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

	Идентификаторы = Новый Массив;
	Идентификаторы.Добавить(Идентификатор);

	ОбъектыМетаданных = ОбъектыМетаданныхПоИдентификаторам(Идентификаторы, ВызыватьИсключение);

	Если Идентификатор = Неопределено Тогда
		Возврат Null;
	КонецЕсли;

	Возврат ОбъектыМетаданных.Получить(Идентификатор);

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

// См. ОбщегоНазначения.ОбъектыМетаданныхПоИдентификаторам.

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