Отображение и редактирование в дереве большого количества настроек/параметров/опций программы, конфигурации, документа, справочника - без программного создания элементов формы

03.01.21

Разработка - Механизмы платформы 1С

Очень много реквизитов (настроечные опции, параметры) у справочника или документа, и их все необходимо разместить на управляемую форму - лень! Хочется - добавил в метаданные и всё! В публикации отличное, простое и олдскульное решение с открытым кодом, научимся работать с ДанныеФормыДерево, ДеревомЗначений, сделаем быстрый поиск, создадим универсальный инструмент.

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

 

Как же подобное организовано в типовых? Например, в типовой Розница, редакция 2.3 для подобного используется - ПланВидовХарактеристик: НастройкиПользователей, Справочник: Пользователей и регистр сведений: НастройкиПользователей. Там это обусловлено тем, что необходимо для пересечения Магазин, Пользователь определить его настройки. Однако, в случае, если у Вас настройки только для пользователя или только для магазина, то смысла использовать ПВХ нет, оно только усложняет запросы (в предлагаемом решении вся информация хранится в одном справочнике/документе, следовательно и запрос выполняется только к одной таблице). 
 

Итак, сразу покажем результат универсального механизма из нашей подсистемы EDIbot (быстрое создание реактивных веб приложений/B2B-порталов/сайтов/Dashboard), который достигнем кодом публикации:

 

Рассмотрим по шагам, как такое Вам сделать в конфигурации:

1. Вы как обычно создаете/добавляете реквизиты метаданных к Вашему объекту, НО в стандартном поле "Комментарий" указываете Имя группы реквизита. Причем для создания подгрупп имя группы можно указать с точкой,  например, "Общие.Масштабирование", вот пример:

 

2. Далее, добавляем Дерево значений в реквизиты формы и размещаем его на форме

 

3. Заполняем наше дерево на клиенте, в процедуре при открытии:

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	ЗаполнитьДеревоПараметров(_ВебАппСеанса.ПолучитьСписокРеквизитовДереваПараметров("Справочники._ВебАппСтраницы"));

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

 

4. Как видно, мы передаем нашей функции по заполнению реквизиты для построения дерева, опишем эту функцию: ПолучитьСписокРеквизитовДереваПараметров и как раз именно здесь мы будем использовать наш комментарий к реквизиту метаданных как структуру дерева (группы/подгруппы).

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

 

5. Теперь все готово, чтобы описать нашу процедуру по заполнению дерева:

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

 

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

	Возврат НоваяСтрока;
КонецФункции

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

 

Итак, мы с Вами сделали вывод всех наших реквизитов на управляемую форму, у которых заполнено поле "Комментарий" (т.е. реквизит отнесен к какой-либо группе дерева настроек).

 

Теперь возникает вопрос, а как редактировать особо сложные реквизиты, как сделать сохранение реквизитов в базу данных?

Для сохранения изменений, сделанных на форме, в объект мы с Вами добавим обработку события ПриИзменении значения параметра:

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

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

 

Как видно, в процедуре мы устанавливаем ЦельМасштабирования, равное пустому значению при значении СпособМасштабирования="font-size" с помощью функции УстановитьЗначениеПараметра, вот ее код:

&НаКлиенте
Процедура УстановитьЗначениеПараметра(ИмяПараметра, ЗначениеПараметра)
		
	СтрокаДерева = ИндексДереваПараметров.Получить(ИмяПараметра);
	
	Если СтрокаДерева=Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	СтрокаДерева.ЗначениеПараметра 	= ЗначениеПараметра;
	Объект[ИмяПараметра] 			= ЗначениеПараметра;

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

Обратите внимание, как это было реализовано: здесь мы опять использовали быстрый поиск строки дерева формы по имени параметра.

 

А для обработки каких-то специфических реквизитов, например, выбор каталога добавляем обработку события НачалоВыбора

&НаКлиенте
Процедура ДеревоПараметровФормаЗначениеПараметраНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	
	СтрокаТЧ = Элементы.ДеревоПараметровФорма.ТекущиеДанные;
	
	Если СтрокаТЧ=Неопределено Тогда
		Возврат;
	КонецЕсли;

	Если СтрокаТЧ.ИмяПараметра="РабочийКаталог" Тогда
		
		ВыборКаталога(Элемент, СтрокаТЧ.ИмяПараметра);		
		
	КонецЕсли;
	
КонецПроцедуры

 

Однако, бывает, что нужно решить еще одну задачку - ограничить те типы, которые пользователь может выбирать при редактировании значения параметра. 

Например, выбор из определенного списка или ограничение доступности изменения реквизитов при определенных условиях.

Будем реализовывать это с помощью обработки события ПередНачаломИзменения:

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

	Реквизиты = _ВебАппСеанса.ПолучитьСписокРеквизитовДереваПараметров("Справочники._ВебАппСтраницы");
	Элемент.ТекущийЭлемент.ОграничениеТипа = Реквизиты[СтрокаТЧ.ИмяПараметра].Тип; 
	
	Элемент.ТекущийЭлемент.РежимВыбораИзСписка 	= Ложь;
	Элемент.ТекущийЭлемент.КнопкаВыбора		   	= Истина;
	
	Элемент.ТекущийЭлемент.СписокВыбора.Очистить();		
	
	Если СтрокаТЧ.ИмяПараметра="СпособМасштабирования" Тогда
		
		Элемент.ТекущийЭлемент.РежимВыбораИзСписка = Истина;
	
		Элемент.ТекущийЭлемент.СписокВыбора.Добавить("scale");
		Элемент.ТекущийЭлемент.СписокВыбора.Добавить("font-size");
		
	ИначеЕсли СтрокаТЧ.ИмяПараметра="ЦельМасштабирования" Тогда	
		
		Отказ = НЕ (Объект.СпособМасштабирования="scale");		
		
	ИначеЕсли СтрокаТЧ.ИмяПараметра="Актуальность" Тогда	
		
		Отказ = Истина;
		
	ИначеЕсли СтрокаТЧ.ИмяПараметра="ВывестиНаРабочийСтол" Тогда	
		
		Элемент.ТекущийЭлемент.РежимВыбораИзСписка = Истина;
		_ОбщегоНазначенияКлиентСервер.СкопироватьСписок(Элемент.ТекущийЭлемент.СписокВыбора, _ВебАппДанныеСеанса.СписокСтраницРабочегоСтола());
		
	КонецЕсли;
		
КонецПроцедуры

 

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

 

Надеюсь, моя публикация была Вам полезна и сэкономит Ваше время, ссылка на все публикации SizovE.

Подписывайтесь на мой канал (наверху), будет много интересного бесплатного контента :)

См. также

Поинтегрируем: сервисы интеграции – новый стандарт или просто коннектор?

Обмен между базами 1C Администрирование СУБД Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.17 появился замечательный механизм «Сервисы интеграции». Многие считают, что это просто коннектор 1С:Шины. Так ли это?

11.03.2024    4625    dsdred    53    

73

Как готовить и есть массивы

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    5312    YA_418728146    25    

64

Планы обмена VS История данных

Обмен между базами 1C Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    6440    dsdred    36    

112

1С-ная магия

Механизмы платформы 1С Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    18508    SeiOkami    46    

118

Дефрагментация и реиндексация после перехода на платформу 8.3.22

Механизмы платформы 1С Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    12113    human_new    27    

74

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    8850    YA_418728146    6    

141

Внешние компоненты Native API на языке Rust - Просто!

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Внешние компоненты для 1С можно разработывать очень просто, пользуясь всеми преимуществами языка Rust - от безопасности и кроссплатформенности до удобного менеджера библиотек.

20.08.2023    6290    sebekerga    54    

94

Все скопируем и вставим! (Буфер обмена в 1С 8.3.24)

Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    16021    SeiOkami    31    

103
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Cyberhawk 135 03.01.21 17:37 Сейчас в теме
Чем это все лучше предопределенных элементов ПВХ? Древовидная структура из коробки, возможность ограничивать типы каждого элемента - все это вроде и там есть.
2. SizovE 262 03.01.21 18:54 Сейчас в теме
(1) Если как Вы предлагаете, то чтобы организовать, например, настройки пользователей (в типовой именно так) делается отдельный регистр, который хранит значения настроек этого пользователя и чтобы вывести дерево типовая использует тоже некий алгоритм его заполнения.
Иными словами используется такая структура - Справочник Пользователи, ПВХ, РегистрСведений. А тут все хранится в одном месте (справочнике Пользователи). В чем плюс моего решения? - В обращениях из запросов, Вы делаете запрос, который обращается к одной таблице и сразу оттуда получает нужное. Да и если честно прозрачнее с точки зрения кода, по крайне мере мне ) Гляньте их модули в типовой Рознице например, как организовано заполнение ФормаНастроекПользователя регистра сведений НастройкиПользователей - тиражировать в свой код такое не сильно хочется )

А ещё как оно бывает: Есть некий справочник, в котором было 5 реквизитов опций, сначала добавляешь их на форму, потом клиент просит еще парочку опцией, потом еще парочку, и тут уже на ПВХ переходить не комильфо, а вот внедрить подобный инструмент за пару минут отличное решение
3. Cyberhawk 135 03.01.21 19:06 Сейчас в теме
(2)
чтобы вывести дерево типовая использует тоже некий алгоритм его заполнения. Иными словами используется такая структура - Справочник Пользователи, ПВХ, РегистрСведений
Я про один ПВХ, без какого-либо кода и форм. В статье предлагается добавлять реквизиты в метаданные и иерархию по заполненным в комментарии значениям выстраивать и обмазывать отрисовку прикладным кодом, а в случае с ПВХ добавление предопределенных происходит сразу в нужную папку (нужную иерархию) и никаких форм и код можно не писать.
4. SizovE 262 03.01.21 19:29 Сейчас в теме
(3) Возможно, я плохо описал зачем это всё )
Я думал, что эта фраза позволяет понять, чем ПВХ не подходит -
Очень много реквизитов (настроечные опции, параметры) у справочника или документа, и их все необходимо разместить на управляемую форму - лень!

Добавлю в статью, чем не подходит ПВХ для этой задачи.
8. PLAstic 295 18.07.22 09:45 Сейчас в теме
(4) Да, добавьте, плз, чем это лучше, потому что когда вы полезли в дебри зависимостей между реквизитами, ограничение выбора и пр., то явно приходили к мысли, что обычная форма администрирования, как это рекомендуется в БСП, будет намного лучше за счёт наглядности и универсальности.
https://its.1c.ru/db/bsp315doc#content:4:1:issogl1_%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%­B8_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B

Я встречал подобие вашего механизма, который использовался примерно 2 года. Там было множество дублирующихся настроек, потому что новые программисты просто добавляли новые параметры объясняя "я не знаю, как работает существующий элемент". И верно, ведь никакой справки по ним нет. В коде была раскидистая ёлка с ветками Если-ИначеЕсли для навешивания кода на начало выбора из списка и пр.

Для адресации используются строковые наименования в коде. Чем это лучше табуированного НайтиПоНаименованию()?

Есть такой термин - TCO. Он включает в себя лёгкую поддерживаемость и обслуживание тоже. Конечно, он не совместим с термином "лень", который вы используете.
11. SizovE 262 18.07.22 12:19 Сейчас в теме
(8) Так добавлено, цитата
"Как же подобное организовано в типовых? Например, в типовой Розница, редакция 2.3 для подобного используется - ПланВидовХарактеристик: НастройкиПользователей, Справочник: Пользователей и регистр сведений: НастройкиПользователей. Там это обусловлено тем, что необходимо для пересечения Магазин, Пользователь определить его настройки. Однако, в случае, если у Вас настройки только для пользователя или только для магазина, то смысла использовать ПВХ нет, оно только усложняет запросы (в предлагаемом решении вся информация хранится в одном справочнике/документе, следовательно и запрос выполняется только к одной таблице). "

Одно дело в запросе обращаться к типа
ВЫБРАТЬ
Спр.ИмяОпции
ИЗ
Справочник.Номенклатура КАК Спр


А другое дело связывать через соединения с регистром сведений.
5. user1503726 03.01.21 20:24 Сейчас в теме
Это похоже на подсистемы конфигуратора, только в любом месте, где захотите, в интерфейсе.
Можно в любом справочнике/документе по любому текстовому полю организовать еще одну(2-3..) иерархии и выбирать какая нужна в конкретный момент.
6. SizovE 262 03.01.21 23:12 Сейчас в теме
7. kalyaka 1053 18.07.22 08:36 Сейчас в теме
Правильно ли я понял, что данное решение вы предлагаете использовать для пользовательского ввода данных?
9. PLAstic 295 18.07.22 09:47 Сейчас в теме
(7) Видно, что нет. Потому что пользователи будут в крайней степени изумления из-за отсутствия описания.
10. kalyaka 1053 18.07.22 10:02 Сейчас в теме
(9) Ну если такой интерфейс применять для любых пользовательских данных, то наверное оценка пользователей в модели Кано будет в нижнем правом квадранте. Но похоже это решение подходит для отдельных настроек, типа констант. Т.е. имеются 100500 настроек, никак не связанных между собой и их можно быстро организовать в виде иерархической структуры
12. SizovE 262 18.07.22 12:20 Сейчас в теме
(10) Примерно так, в публикации приведен скрин реального использования
13. PLAstic 295 18.07.22 14:29 Сейчас в теме
(12) Это был сарказм. В той диаграмме это означает "требования заказчика выполнены, но реализация вызывает отвращение".
14. SizovE 262 18.07.22 17:44 Сейчас в теме
(13) В чем у Вас вызывает отвращение скрин (закладка "Параметры") публикации?
Для каждого случая свой вариант реализации, где-то удобнее размещать вручную поля ввода, где-то динамически создавая, где-то так как описано в публикации.
15. PLAstic 295 18.07.22 23:30 Сейчас в теме
(14) Я лишь пояснил. Смотри на автора.
16. SizovE 262 19.07.22 06:46 Сейчас в теме
(15) ) А зачем Вы за автора поясняете? ) Если он захочет, он прокомментирует, он не писал, что это сарказм,
а, написал:
Но похоже это решение подходит для отдельных настроек, типа констант. Т.е. имеются 100500 настроек, никак не связанных между собой и их можно быстро организовать в виде иерархической структуры
, именно с этим я и согласился.

Использованный пример в публикации достаточно популярен для десктопа, олдскульный и многие системы его используют, где много различных параметров. Например, gpedit.msc, MS SQL
Прикрепленные файлы:
17. PLAstic 295 19.07.22 09:49 Сейчас в теме
(16) Тогда, я думаю, вы будете не против добавить в статью жирный нюанс, что это подходит для технических специалистов, которым комментарии не нужны. В пользовательском интерфейсе это выглядело бы весьма экспрессивно.

Помню, учили нас в 1ом УЦ и рассказывают на новой (тогда) платформе, что вот, есть новая возможность у реквизитов - параметры выбора... Преподу кто-то из зала: - А почему в типовых это не используют тогда?
Не помню точно, как он ответил, но с его парадигмой я пришёл потом в конфигуратор УТ, сижу и смотрю - а тут можно было бы вот так чисто свойствами сделать, а тут - вот так. А там везде куча строк типового кода.

Я к тому, что не стоит вам прибегать к аргументации вроде "а вот в Рознице я видел, там тоже сделали как в каменном веке".
Что вы кладёте в копилку собственного опыта? Кто оценит это потом? Допустим, я следующий ваш работодатель. Что я скажу? А где документирование? А где параметры выбора? А где определённые по ПВХ типы для конкретных свойств? Где лёгкость дальнейшей поддержки и обслуживания? Я не хочу, чтобы вы такое делали в нашей КИС. Садись - два.
18. SizovE 262 19.07.22 14:42 Сейчас в теме
(17)
Мной в публикации изложен подход для определенного жизненного сценария.
Читатель вполне адекватен, чтобы без моих жирных комментариев понимать, нужно или нет ему это использовать у себя в конфигурациях.
Я не навязываю использование этого подхода, ни Вам, ни кому-либо.

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

Вы в комментариях выразили свое личное субъективное мнение, спасибо, другие пользователи его прочитают.

П.С. В публикации используется стандартное Дерево значений и его стандартное отображение 1С, возможно, когда-нибудь, 1С сделает его отображение более приближенное к современному дизайну.
Оставьте свое сообщение