Копирование настроек пользователей в УПП

04 декабря 2013

Файлы для загрузки

Настройки пользователей

В прошлой статье "Настройки пользователей УПП" был рассмотрен механизм настройки пользователей в конфигураторе, а также его использование в режиме 1С:Предприятие. Напомню, что используется он, например, для автозаполнения форм значениями, определенными в настройках конкретного пользователя.

При создании новых пользователей в информационной базе часто приходится устанавливать для каждого из них настройки, при этом во многих случаях удобнее было бы просто скопировать уже существующие настройки другого пользователя и присвоить их только что созданному.

Форма создаваемой обработки копирования настроек пользователей

Удобный средств для копирования настроек пользователей в типовой конфигурации УПП нет. Исправим эту ситуацию создав внешнюю обработку с необходимым функционалом.

Создание обработки

Структура метаданных внешней обработки следующая:

Структура метаданных обработки копирования настроек пользователей

Реквизит обработки "Пользователь", также как и одноименный реквизит табличной части, ссылаются на справочник "Пользователи". Соответственно, в реквизите обработки содержится ссылка на пользователя, настройки которого надо скопировать. В табличной части - пользователи, которым нужно присвоить скопированные настройки.

На форме нас интересуют две команды: "Подбор" и "Скопировать настройки".

Команды на форме обработки

Подбор организован типовыми средствами (типовая форма выбора), нам лишь нужно написать обработчик выбора формы обработки. Вот листинги обработчиков кнопки "Подбор" и события "ОбработкаВыбора".

Процедура КоманднаяПанель1Подбор(Кнопка)
 
 ФормаПодбора = Справочники.Пользователи.
                        ПолучитьФормуВыбора(,ЭтаФорма);

 ФормаПодбора.ЗакрыватьПриВыборе = Ложь;
 
 ФормаПодбора.Открыть();
 
КонецПроцедуры

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

то касается команды "Скопировать настройки", то весь программный код для выполнения копирования настроек приведен на следующем листинге:

// Константы типов
Перем ТипПользователи;

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

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

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

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

ТипПользователи = Тип("СправочникСсылка.Пользователи");

comments powered by Disqus