Бодаемся с отображением отборов на управляемых формах

30.05.18

Разработка - Работа с интерфейсом

Рассмотрим в статье, как настроить отображение пользовательских отборов на форме по своему желанию.

Как известно многим, дьявол всегда кроется в мелочах. Одной из таких мелочей всплыло замечание пользователей о том, что при добавлении отборов при настройке списка не всегда отображается вид сравнения.

Используя главный инструмент разработчика - а именно метод научного тыка, я определил, что вид сравнения не отображается, если он соответствует виду "Равно". Исправление этой прекрасной находки специалистов по юзабилити из 1С, казалось бы, находится на расстоянии вытянутой руки: вот и заветная галочка, доступная из настроек формы:

 

Казалось бы, дело за малым, перехватить момент, когда отборы попадают на форму, да пройтись по всем элементам группы пользовательских настроек и проставить видимость. 

Итак, первым делом нужно усвоить, что те отборы, которые мы используем через стандартную команду настройки списка, имеют отношение не к самой форме, а к динамическому списку, расположенному на ней, и являются ни чем иным, как пользовательскими настройками. 

Если смотреть свойства динамического списка через палитру, можно найти две зацепки для решения нашей задачи:

1) Во-первых, это свойство "Группа пользовательских настроек". В данном свойстве указывается группа формы, которая выступит родителем для всех добавляемых элементов с отображением отборов.

 

 

2) Во-вторых, это событие списка "ПриОбновленииСоставаПользовательскихНастроекНаСервере".

 

 

Именно сюда вы попадёте если будете грешить после нажатия кнопки "Завершить редактирование" в форме настройки списка. При создании процедуры у неё есть лишь один параметр - использовать стандартную обработку или нет. При стандартной обработке будет вызван метод расширения формы динамического списка (т.е. элемента) СоздатьЭлементыФормыПользовательскихНастроек, который формирует все поля отборов на форме. На этом моменте у нас есть два выбора: или сформировать все поля через Элементы.Список.СоздатьЭлементыФормыПользовательскихНастроек(), а потом проставить видимость элементов, или взять дело целиком в свои руки и отрисовать поля самим. Я выбрал второй вариант, хотя, думаю, вы сможете реализовать и первый, зная, что откуда растёт. В любом случае не забудьте, что стандартная обработка должна быть выключена!

Рассмотрим программное создание полей на примере рабочего кода:

 

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

 

Как видите, алгоритм не очень сложен, дольше всего я провозился с путём к данным с настройками - первый массив, в который мы попадаем (который жёстко прописан в пути) содержит информацию по отборам, а последующие массивы уже информацию ко конкретным настройкам отбора. 

В итоге мы имеем стройный ряд настроек, который можно поменять в любой момент:

 

См. также

Богатый редактор картинок, хранимых в базе, с возможностью РИСОВАНИЯ. Редактор внешних файлов картинок. Объект, расширяющий возможности работы с картинками из встроенного языка (Три в одном) + Обработка «Стандартизация картинок»

Работа с интерфейсом Рабочее место Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Обработка предназначена для редактирования картинок в режиме «Предприятие», с возможностью РИСОВАТЬ на них. Поддерживается работа как в обычных формах (толстый клиент) так и на управляемых формах (тонкий клиент). Обработка позволяет редактировать как картинки, хранимые в базе, так и графические файлы с диска на файловой системе. Помимо базовых функций (изменение размеров, преобразование формата, обрезание картинки, повороты и т.п.) – редактор имеет богатый набор инструментов для рисования. Доступна функция вставки изображения из буфера обмена. Также обработка может быть использована из встроенного языка как объект для редактирования картинок. Объект может быть использован: на стороне клиента, на стороне сервера, из внешнего соединения. Данная обработка будет особенно полезна тем, кто вносит картинки в базу (изображения номенклатуры, фотографии физических лиц и т.п.). Функционал реализуется с использованием JavaScript и бесплатного ПО ImageMagick (без использования внешних компонент).

6000 руб.

16.01.2015    61794    43    59    

80

[Расширения] Динамическое управление видимостью и доступностью элементов форм (УФ) (8.3.6+)

Работа с интерфейсом Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Механизм «Динамическое управление доступом к элементам форм объектов 1С8» предназначен для обеспечения возможности оперативного управления видимостью и доступностью элементов форм документов и справочников продуктов фирмы «1С» «1С:Предприятие 8». Решение универсальное, встраивается в любую конфигурацию с минимальными доработками, что позволяет без проблем обновлять типовые решения.

5000 руб.

14.01.2016    54401    16    21    

42

Управление дашбордами

Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Обработка предназначена для создания и управления дашбордами.

2400 руб.

29.06.2020    16696    21    4    

35

Новогоднее оформление для 1С

Работа с интерфейсом Платформа 1С v8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 Бесплатно (free)

Добавьте новогоднего настроения! Расширение создает декорацию в виде гирлянды на некоторых формах объектов.

27.12.2023    10735    750    elcoan    45    

106

Конструктор HTML, CSS и javascript

Инструментарий разработчика Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

2 стартмани

10.04.2023    9611    151    acces969    31    

118

Модель состояния для MVC

Работа с интерфейсом Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

"MVC плохо применима в 1С" - познакомьтесь с моделью состояния и, возможно, ваше мнение поменяется! Представленное решение является эволюционным развитием идеи реализации MVC для 1С. В новой версии добавлены DSL для описания модели состояния, а также параметризация свойств параметров и элементов формы.

1 стартмани

05.07.2022    3665    kalyaka    2    

27

Табло очереди заказов на экран телевизора

WEB-интеграция Работа с интерфейсом Платформа 1С v8.3 1С:Розница 2 Платные (руб)

Связка из веб-приложения и расширения для 1С: Розница 2.3.

3600 руб.

29.04.2022    12080    1    5    

10
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. пользователь 31.05.18 05:17
Сообщение было скрыто модератором.
...
2. Fragster 1138 31.05.18 16:06 Сейчас в теме
Либо отказаться от указания группы пользовательских настроек в свойствах формы и создать их в две колонки в нужной группе одной строкой кода указав третий параметр процедуры
Расширение таблицы формы для динамического списка (Form table extension for dynamic list)
СоздатьЭлементыФормыПользовательскихНастроек (CreateUserSettingsFormItems)
Синтаксис:

СоздатьЭлементыФормыПользовательскихНастроек(<ГруппаПользовательскихНастроек>, <Режим>, <КоличествоКолонок>)
Параметры:

<ГруппаПользовательскихНастроек> (необязательный)

Тип: ГруппаФормы.
Группа, внутри которой требуется создать элементы для редактирования пользовательских настроек динамического списка.
Значение по умолчанию: Неопределено.
<Режим> (необязательный)

Тип: РежимОтображенияНастроекКомпоновкиДанных.
Указывает, нужно ли в группе создавать элементы для всех пользовательских настроек динамического списка или только для быстрых.
Значение по умолчанию: Неопределено.
<КоличествоКолонок> (необязательный)

Тип: Число.
Задает количество колонок, в которых размещаются элементы формы в группе редактирования пользовательских настроек.
Если параметр не задан, то элементы группы размещаются в двух колонках.
Описание:

Создает элементы формы для редактирования пользовательских настроек динамического списка.
Показать
ЧИА; ЧерныйКот; +2 Ответить
3. lemz 123 31.05.18 16:23 Сейчас в теме
(2)
Либо отказаться от указания группы пользовательских настроек в свойствах формы и создать их в две колонки в нужной группе одной строкой кода указав третий параметр процедуры


Да, про этот вариант я упомянул, но после него для решения поставленной задачи (всегда отображать вид сравнения) вам нужно обходить эти созданные элементы чтобы проставить видимость. Огород начинается в тот момент, когда вам необходимо определить уровень вложенности элемента (если отбор только один, то колонки не создаются). Но в целом рабочий вариант с этим методом слепить можно.
4. Fragster 1138 31.05.18 16:48 Сейчас в теме
(3) ну, простейшая рекурсивная функция справится с обходом, получается в разы меньше кода. Единственный нюанс - у группы для настроек нужно убрать флажок "Разрешить пользовательское изменение состава группы, РазрешитьИзменениеСостава, EnableContentChange"

Примерный код такой:
&НаСервере
Процедура Реквизит1ПриОбновленииСоставаПользовательскихНастроекНаСерве­ре(СтандартнаяОбработка)
	Элементы.Реквизит1.СоздатьЭлементыФормыПользовательскихНастроек(Элементы.Настройки, , 2);
	УстановитьВидимостьНастроек(Элементы.Настройки);
КонецПроцедуры


&НаСервере
Процедура УстановитьВидимостьНастроек(ГруппаНастроек)
	Для каждого ПодчиненныйЭлемент Из ГруппаНастроек.ПодчиненныеЭлементы Цикл
		Если ТипЗнч(ПодчиненныйЭлемент) = Тип("ГруппаФормы") Тогда
			УстановитьВидимостьНастроек(ПодчиненныйЭлемент);
		Иначе
			ПодчиненныйЭлемент.Видимость = Истина;
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры
Показать
Danil.Potapov; Il; lemz; +3 Ответить
5. Fragster 1138 31.05.18 17:33 Сейчас в теме
(4) Нашел у себя косяк - поскольку видмость устанавливается пользовательскими настройками формы, а мы к ним не имеем прямого доступа, нужно не устанавливать видимость, а все-таки клонировать элементы. Вот рабочий вариант (кода также не очень много):
&НаСервере
Процедура УстановитьВидимостьНастроек(ГруппаНастроек)
	МассивКлонируемыхЭлементов = Новый Массив;
	Для каждого ПодчиненныйЭлемент Из ГруппаНастроек.ПодчиненныеЭлементы Цикл
		Если ТипЗнч(ПодчиненныйЭлемент) = Тип("ГруппаФормы") Тогда
			УстановитьВидимостьНастроек(ПодчиненныйЭлемент);
		Иначе
			Если СтрНайти(ПодчиненныйЭлемент.Имя, "ВидСравнения") <> 0 Тогда
				МассивКлонируемыхЭлементов.Добавить(ПодчиненныйЭлемент);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	Для каждого КлонируемыйЭлемент Из МассивКлонируемыхЭлементов Цикл
		Клон = ЭтаФорма.Элементы.Вставить(КлонируемыйЭлемент.Имя + "Клон", ТипЗнч(КлонируемыйЭлемент), КлонируемыйЭлемент.Родитель, КлонируемыйЭлемент);
		ЗаполнитьЗначенияСвойств(Клон, КлонируемыйЭлемент, "Вид, ПоложениеЗаголовка, РастягиватьПоГоризонтали, ПутьКДанным");
		КлонируемыйЭлемент.Видимость = Ложь;
	КонецЦикла;
КонецПроцедуры
Показать
7OH; Danil.Potapov; Il; Поручик; +4 Ответить
8. пользователь 02.06.18 06:16
Сообщение было скрыто модератором.
...
9. пользователь 02.06.18 17:31
Сообщение было скрыто модератором.
...
6. allgorhythm 01.06.18 03:48 Сейчас в теме
Кручу верчу сравнить хочу!
7. Поручик 4670 01.06.18 10:07 Сейчас в теме
Плохо, что для исправления косяка от 1С, приходится добавлять форму для отчёта на СКД.
10. Montirey 11.02.19 09:31 Сейчас в теме
Автору спасибо большое за идею!

Реализовал у себя, буду теперь использовать.

Нашел в коде ошибку (видимо осталось от реализации предыдущих вариантов), облегчу реализацию тем, кто воспользуется этим способом:

ПолеЗначение.ПутьКДанным = "Список.КомпоновщикНастроек.ПользовательскиеНастройки[0]["+НомерЭлемента+"].Значение";

это работать не будет, так как в результате получится конструкция Список.КомпоновщикНастроек.ПользовательскиеНастройки[0][0].Значение

правильно так:

ПолеЗначение.ПутьКДанным = "Список.КомпоновщикНастроек.ПользовательскиеНастройки[" + НомерЭлемента + "].Значение";

Соответственно это справедливо для Использование и ВидСравнения
11. lemz 123 11.02.19 17:21 Сейчас в теме
(10) Странно что у вас сработал именно такой вариант, так как в моём случае жёстко прописать первый массив пришлось из-за того, что в нём лежит информация по всем отборам, а уже внутри него проходя по номерам мы получаем конкретные значения этих отборов
13. ward_ed 02.07.19 07:54 Сейчас в теме
Правильно будет определить индекс элемента, следующим образом
НомерЭлемента = Настройки.Отбор.Элементы.Индекс(ЭлОтбора);.
Это в том случае если что-то нужно исключить при создании.
И еще в пользовательские настройки могут попадать и параметры, в данном варианте кода они не выводятся в форму, так как элементы хранятся отдельно.
12. anig99 2843 01.03.19 15:59 Сейчас в теме
Спасибо за указание направления. Написал свой более сложный и универсальный вариант.
14. AzagTot 40 25.09.19 15:26 Сейчас в теме
Автору спасибо за идею!

Реализовал в точности так, как указано в теме, однако поля отбора недоступны для редактирования. Попробовал для каждого элемента явно указать доступность - все равно та же ситуация. Использование стоит везде. У группы с отборами свойство "Только просмотр" Ложь.

Ума не приложу, куда еще копать... Может сталкивался кто?

Платформа 8.3.14, такое же поведение на 8.3.15.
Прикрепленные файлы:
15. AzagTot 40 25.09.19 16:26 Сейчас в теме
(14) Причина была найдена. Оказывается, если задать предопределенный отбор в конфигураторе и включить ему галочку (включить в пользовательские настройки), то этот отбор сделает недоступными и пользовательские отборы, и сам себя.
Есть ли возможность полечить это?
17. lemz 123 25.09.19 17:15 Сейчас в теме
(15) Действительно, есть такое. Могу только приметить, что если предопределённый отбор не помечать включенным в пользовательские настройки, в данной реализации он выведется на форму всё равно, при этом ничего не ломая ни со своей доступностью, ни с пользовательскими настройками
20. western0508 16.06.22 13:23 Сейчас в теме
(15) Не подскажите как решили? Тоже поля недоступны ничего не спасает :с
22. vlad3190 20.10.22 14:07 Сейчас в теме
(20) Подскажите, Вам удалось решить данную проблему?
25. AndreyVD 08.06.23 10:11 Сейчас в теме
(23)
(20)
Всем доброго дня.

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

ПутьКДанным = ИмяСписка + ".КомпоновщикНастроек.ПользовательскиеНастройки[0].Отбор[" + ИндексЭлементаОтбора+ "].Использование";
ПутьКДанным = ИмяСписка + ".КомпоновщикНастроек.ПользовательскиеНастройки[0].Отбор[" + ИндексЭлементаОтбора+ "].Значение";
21. vlad3190 20.10.22 14:06 Сейчас в теме
(15) Подскажите, как вы побороли данную проблему?
16. lemz 123 25.09.19 16:48 Сейчас в теме
(14) Группой пользовательских настроек для списка у вас выставлен стандартный для форм списка элемент "СписокКомпоновщикНастроекПользовательскиеНастройки"? У него по доступности ничего не залочено?
18. Alexeibv87 21.01.22 00:02 Сейчас в теме
Спасибо большое, давно искал, как исправить это стандартное поведение на более привычное\удобное для меня.
19. 7OH 69 13.02.22 00:05 Сейчас в теме
Спасибо. Забрал в обычное приложение.
Там пользовательские настройки вообще не отображались.
Теперь красота
23. Hans 2 28.11.22 17:29 Сейчас в теме
Как решить проблему с недоступностью полей? Динамический список не используется. На форме есть только компоновщик настроек.
24. CeHbKA 300 25.01.23 10:35 Сейчас в теме
Зачем программно генерировать все эти поля, когда можно просто вызвать Элементы.Список.СоздатьЭлементыФормыПользовательскихНастроек() ? И уже после обойти все созданные элементы и настроить так, как хочется.

&НаСервере
Процедура СписокОбращенийПриОбновленииСоставаПользовательскихНастроекН­аСервере(СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	Элементы.Список.СоздатьЭлементыФормыПользовательскихНастроек();
	// теперь все элементы на форме доступны, их можно обойти, настроить отображение и повесить обработчики "ПриИзменении" и т.д.
КонецПроцедуры


А за статью спасибо! :)
totchaz; ЧИА; fravol; +3 Ответить
27. totchaz 139 23.01.24 09:54 Сейчас в теме
(24) Дельный коммент. Метод "СоздатьЭлементыФормыПользовательскихНастроек" не знал, помог решить мою задачу, спасибо

Автору статьи спасибо за труд!
26. starik-2005 3033 17.08.23 15:32 Сейчас в теме
Афтор, ты мне нанес неисправимую пользу )))
Teut_Vlad; ЧИА; +2 Ответить
Оставьте свое сообщение