gifts2017

Изменить внешний вид обычных форм "на лету"? Сделано!

Опубликовал Николай Беляев (freez1301) в раздел Программирование - Практика программирования

Как-то раз очередная группа пользователей захотела видеть свои АРМ "в своем свете". Каждый хотел свой размер шрифта, его тип, цвет и прочую ерундистику. Все бы ничего, но формы были обычными, и тогда в голову пришла следующая идея

1. Что понадобится

Релиз платформы 8.2 и выше

Возможность изменять конфигурацию

Немного желания Wink

2. "Поехали!"


Условимся, что форму, внешний вид которой хотим настроить, будем называть АРМ, а форму, в которой будем делать настройки, - ФормаНастроек


2.1. Для начала создадим непериодический, независимый регистр сведений.  Должно получиться следующее

Регистр сведений 

2.2. Создадим общую форму - ФормаНастроек. Поместим на нее ТабличноеПоле, укажем ТипЗначения - ТаблицаЗначений, добавим колонки в количестве, равном сумме измерений только что созданного РС + количество ресурсов, т.е. 5. Тип значений колонок установим аналогично измерениям, кроме колонки, которая соответствует ресурсу - у нее выберим составной тип данных - Булево, Цвет, Шрифт. Также добавим командую панель и свяжем ее с созданной Таблицой значений, не забыв про галочку Автозаполнение. Также настроим элементы управления колонок, опять же не забыв снять галочку РедактированиеТекста в колонках ЭлементФормы и ИмяСвойства.

 Общая форма

2.3. Добавим в любую форму конфигурации место вызова нашей ФормыНастроеек.  На всякий случай код

Форма = ПолучитьОбщуюФорму(<ИмяОбщейФормы>, ЭтаФорма);
Форма.ОткрытьМодально();

2.4. В процедуре ПередОткрытием ФормыНастроек сформируем список элементов, для которых будет возможность редактирования внешнего вида. Список может быть произвольным, в моем случае настраивать можно Табличные поля и Командные панели

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

2.5. В процедуру обработчика ПриИзменении элемента управления колонки  ЭлементФормы поместим следующий код

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

где Процедура ЗаполнитьСписокВыбора имеет следующий код. В зависимости от выбранного значения в колонке ЭлементФормы - СписокВыбора колонки ИмяСвойства - может быть различным. Оговорюсь, что в моем варианте задействовано 2 типа элемента - ТабПоле и КоманднаяПанель.

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

КонецПроцедуры // ЗаполнитьСписокВыбора()

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

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

Немного поясню (знаю, что многим и так понятно, но есть и те, которые только начинают). Создаем набор записей созданного нами регистра сведений, ищем все записи, касающиеся текущего пользователя и АРМ, которую настраиваем в данный момент и затираем их. Далее в цикле обходим ТаблицуЗначений, добавляя ее строки в набор записей. В конце все записываем и закрываем ФормуНастроек.

2.7. После сохранения записей в РС отладчик вернет нас в модуль формы, из которой открывали ФормуНастроек. Теперь необходимо как то обработать результат настроек. Для этого в модуле формы АРМ поместим следующую процедуру и добавим ее вызов сразу после Форма.ОткрытьМодально()

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

Запрос.УстановитьПараметр("Пользователь", ПараметрыСеанса.ТекущийПользователь);
Запрос.УстановитьПараметр("РабочееМесто", Строка(ЭтаФорма.ЭтотОбъект));

РезультатЗапроса       = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл 
Попытка
ЭлементыФормы[ВыборкаДетальныеЗаписи.ЭлементФормы][ВыборкаДетальныеЗаписи.ИмяСвойства] = ВыборкаДетальныеЗаписи.Значение.Получить();
Исключение
Сообщить("Для свойства """ + ВыборкаДетальныеЗаписи.ИмяСвойства + """ элемента формы """ + ВыборкаДетальныеЗаписи.ЭлементФормы + """ не верно выбран тип данных!"); 
КонецПопытки;
КонецЦикла;
ЭтаФорма.Обновить();
КонецПроцедуры // ЗагрузитьНастройки()

Теперь после закрытия ФормыНастроек - в форме АРМ  сразу же будут видны результаты наших манипуляций с настройками.


2.8 Все бы хорошо, но осталась еще пара моментов. Хотелось бы, чтобы при открытии АРМ - пользователь сразу видел привычный ему фон списка документа, размер текста на кнопках и т.д. Для этого вызовем процедуру ЗагрузитьНастройки() в процедуре ПриОткрытии формы АРМ. Также и при открытии ФормыНастроек пользователь видел, какие настройки у него уже установлены. Для этого в процедуру ПередОткрытием ФормыНастроек поместим вызов следующей процедуры

 

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

Ну, и напоследок. Теперь при октрытии ФормыНастроек видны уже сделанные настройки, но вспомним, что СписокВыбора элемента управления колонки ИмяСвойства у нас до этого заполнялся только при изменении значения в колонке ЭлементУправления, т.е. если попробовать выбрать что либо сразу после октрытия формы - список выбора будет пустой. Поэтому поместим следующий код в событии ПриАктивизацииСтроки элемента ФормыНастроек -  ТабличноеПоле  

 

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

Теперь точно все готово.  Так выглядит результат

Результат

UPD 04.12.15: выложил простенькую конфу, с поправками на формы списков

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
ИзменениеВнешнегоВидаОбычныхФорм
.cf 32,04Kb
04.12.15
1
.cf 32,04Kb 1 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Роман Ложкин (webester) 20.11.15 15:22
Вы несомненно молодец. Делаете интересное дело. Я вам завидую. У меня список того, что надо сделать в 1С расписан на полгода вперед и продолжает расти а у вас:
Как-то раз очередная группа пользователей захотела видеть свои АРМ "в своем свете". Каждый хотел свой размер шрифта, его тип, цвет и прочую ерундистику

Вспоминается
- Доктор, когда я кончиком языка дотрагиваюсь до комочка фольги, в котором до этого пекли картошку, у меня покалывает за ухом. Что это значит?
- Что у Вас слишком много свободного времени!
Kirill_K; papami; jan27; +3 1 Ответить
2. Иван Петров (dgolovanov) 20.11.15 20:03
Ну, не проблема автора, что у вас работы на пол-года вперед. Вы так медленно ее делаете? (шутка)
Хорошо, когда свободное время тратится на самообразование, а не классический админ-стайл - пока не трогают - смотрю фильмы на работе.
so-quest; Uncore; Brawler; +3 Ответить
3. Ivan Khorkov (vano-ekt) 22.11.15 11:45
хорошо, что за красили название регистра, ведь не каждый запросы читать будет
РегистрСведений.алг_НастройкиРабочихМест КАК НастройкиРабочихМест
DrAku1a; dgolovanov; freez1301; +3 Ответить
4. Евгения Карук (ekaruk) 24.11.15 22:01
Идея классная.
Хотя вообще-то все эти извращения это зло и лучше такого не делать.
HiKS; sorb; +2 Ответить 1
5. Игорь Дайнеко (Dnki) 25.11.15 00:50
(4) ekaruk, "все эти извращения это зло".
Чем более глупым и несерьезным занятие выглядит для женщины, тем более азартно мужики им займутся. Да на такую "глупость" намного быстрее найдется время, чем на программирование декларации и прочей мути!

Мое мнение: замечательно! автор задумался, что программы могут быть не одноцветными. И догадался, что все пользователи в детстве увлекались раскрашками.

Мои замечания:
- статью надо было построить по схеме: 1) в чем задача 2) как я решу визуально и концептуально 3) посмотрите мой код.
- насколько я понял, настройке подлежат только элементы формы. Из шрифт, размер, цвет. А как же сама форма? Хочу цвет не желтый!
- как не сразу понял, "РабочееМесто" это не стул пользователя (в смысле не имя компа, не имя сеанса и т.п.), а имя настраиваемого документа, элемента справочника. Тогда не понятно, как-же с формами списков и отчетами. Вызовы из них сбойнут на фразе:
= Строка(ЭтаФорма.ВладелецФормы.ЭтотОбъект);
6. Николай Беляев (freez1301) 25.11.15 09:01
(5) Dnki,
Спасибо за отзыв. Попробовал поменять отчет - все работает, сбоя нет. Вообще не совсем понятно - почему сбой должен был быть? Владелец то будет в любом случае у формы
7. Xer shi (Xershi) 25.11.15 09:14
У нас точно так же пользователи воют после того как их с 1с7 пересадили.
Т.к. работы на такую глупость вагон, то этот вопрос отложили.
Благодаря статье, если придется решать этот вопрос сокращу время на разработку!
8. Александр Отр (ИНТЕГРА) 25.11.15 09:41
Есть гораздо более удобный и простой вариант решения проблемы. Поражаюсь с каким упорством некоторые берутся решать банальные задачи кучей кода, когда можно немного подумать и решить красиво. Решал подобную задачу следующим образом:
1. Создавал копированием из исходной общую форму (текст модуля очищаешь при этом)
2. Менял ВИЗУЛЬАНО на нем элементы формы как надо (сдвигал, менял размер и тп... с цветами конечно не заморачивался как автор)
3. Делаешь обход по элементам своей формы и копируешь свойства в одноименную типовую.

Преимущества моего подхода:
- Кода - минимум (реализуется за пару часов. Под 1С все подобные задачи надо решать за пару часов, иначе выкидывайте свое решение на помойку и ищите другое).
- Возможность визуального редактирования.
- Возможность создавать новые элементы формы
... и тп.

У меня цель более естественная была - обновление конфигурации без редактирования форм, в результате изменения в формах генерировались программно.
9. Xer shi (Xershi) 25.11.15 09:47
(8) ИНТЕГРА, так а смысл. Пользователь хочет видеть форму в нужном ему цвете, а чем вы ему помогли?
10. Сергей (avasl) 25.11.15 10:15
в п. 2.6 это можно убрать из кода

НаборЗаписей.Прочитать();
НаборЗаписей.Очистить();
11. Николай Беляев (freez1301) 25.11.15 10:18
(8) ИНТЕГРА, может я чего не понял, но как в режиме Предприятие Вы копировали форму, очищали модуль и при этом еще и визуально двигали элементы? Покажите?
12. Евгения Карук (ekaruk) 25.11.15 10:56
(8) ИНТЕГРА, Это не то. Тут вы вцелом меняли для всех.
А автор дал возможность каждому пользователю настроить вид формы для себя именно так, как он хочет.
13. Александр Отр (ИНТЕГРА) 25.11.15 12:20
(9) Xershi, Свойства формы тоже надо переносить из своей общей.
14. Александр Отр (ИНТЕГРА) 25.11.15 12:23
(11) freez1301, В конфигураторе конечно-же.
У автора, я не понял как визуализация процесса редактирования реализована.
15. Александр Отр (ИНТЕГРА) 25.11.15 12:34
(12) ekaruk, по его подходу не весь вид, а только пару свойств как я заметил.
16. Николай Беляев (freez1301) 25.11.15 12:57
(14) ИНТЕГРА, нет никакой визуализации редактирования. Есть возможность открыть общую форму из любой другой, самому определить список элементов и свойств, которые надо изменить (в конфигураторе, хоть все элементы формы). А пользователь уже из "предопределнных тобой в конфигураторе" выбирает элемент, его свойство и значение. Все настройки применяются без закрытия настраиваемой формы и тем более Предприятия.
Как вы заметили правильно - "пару свойств" - но так же легко было догадаться, что список может быть любым. Для своего конкретного случая мне нужно было "пара свойств", о чем я неоднократно упоминал по ходу статьи.
17. Игорь Дайнеко (Dnki) 25.11.15 13:08
(6) freez1301,
= Строка(ЭтаФорма.ВладелецФормы.ЭтотОбъект);
"Владелец то будет в любом случае у формы"

Суть не в "ВладелецФормы", а "ЭтотОбъект". Он есть у формы Документа, элемента спр-ка, отчета. И нет у формы списка.
ИНТЕГРА; +1 Ответить 1
18. Xer shi (Xershi) 25.11.15 15:16
(14) ИНТЕГРА, при открытии формы, можно каждому элементу назначит нужные нам параметры, чем автор и занимался. Список этих параметров он предоставил каждому пользователю. И теперь, если Вася захочет видеть синюю кнопку и рыжий фон, то у себя в 1С он это сможет сделать без программиста.
19. Равиль Каримов (karaw) 03.12.15 20:16
20. Николай Беляев (freez1301) 04.12.15 10:25
(17) Спасибо! да, как то упустил этот момент. выложил конфу с поправками.
(19) готово
21. Иван Иванов (kosmo0) 20.01.16 12:40
Конфигурация никак не связана с какой-либо типовой? А если связана, то тот кто занимается обновлением не начинает выть?
А когда у вас будет сотрудников 50 и большая часть настроит под себя формы не начнутся поиски нужного реквизита на "соседнем" компе - у меня он большой и зеленый в этом углу, а здесь фиг найдешь.

Ну это все лирика. Какие аспекты стоит учитывать.

1. Чем больше отклонения от типовой конфигурации, тем больше затрат времени на обновление и больше шанс словить баги при очередном обновлении.
То есть. Придумают очередное изменение законодательство и начнут типовые конфигурации вылетать через 4-5 дней. Причем законодательство применяется с 1 января, а изменения в конфигурации появляются в феврале-марте. К тому же, обновлять типовой документ - поставить одну галочку. Правленый документ - смотреть логику документа. А если таких документов пара десятков?
2. Чем больше штат сотрудников, тем чаще в голову лезут мысли о единообразии (так гораздо проще, поверьте на слово). В нормальном случае сотрудники начинают помогать друг другу. А если у каждого свой собственный зоопарк, то объяснить (особенно по телефону) где находится нужная кнопочка и КАК ОНА ВЫГЛЯДИТ очень непросто.
3. ОБЯЗАТЕЛЬНО ДОЛЖЕН БЫТЬ механизм возврата к типовой форме. А то наколбасит какая-нибудь деятельная натура до такой степени что элементы перестанут помещаться на форме и как откатывать? Или после обновления что-то станет не видно - опять же как откатывать.

Помню тетеньке одной в Windows размер шрифта поменяли на крупный и то в некоторых местах тупо заголовки не стало видно. А с вашими изменениями только предполагаю куда может унести.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа