Каталог решений - Полезные процедуры по работе с СКД и динамическими списками (часть 3)

Полезные процедуры по работе с СКД и динамическими списками (часть 3)

Полезные процедуры по работе с СКД и динамическими списками (часть 3)

В наличии

Еще пара приемов в копилку разработчика.

Категория:

Описание

1. Копирование настроек СКД и динамических списков

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

Варианты использования:

  • Вариант 1. На форме есть динамический список с отбором. Необходимо при открытии этой формы восстанавливать отборы, настроенные пользователем ранее.
  • Вариант 2. Необходимо полностью или частично перенести настройки между схемами компоновки, компоновщиками настроек, динамическими списками.

Пример сохранения отборов для динамического списка.
— Создадим на форме динамический список СписокКонтрагенты.
— Выведем отбор списка в виде поля
— Создадим реквизит формы СписокКонтрагентыОтборСохранение с типом Произвольный

 

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

&НаКлиенте
Процедура СписокКонтрагентыОтборПриИзменении(Элемент)
	СписокКонтрагентыОтборСохранение = СписокКонтрагенты.Отбор;
КонецПроцедуры

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

 

Это демонстрация использования функции копирования на примере отборов динамических списков. Но она универсальна и применялась мною для программной работы с настройками СКД.

 

2. Предопределенные отборы динамических списков

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

Пример решения.
— Все предопределенные условия помещаем в группу "И". 
— У этой группы задаем некое предопределенное представление
— Перед установкой отбора ищем предопределенную группу и удаляем ее
— Затем создааем ее снова и помещаем в нее все необходимые условия

&НаКлиенте
Процедура СписокКонтрагентыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	СписокКонтрагентыВыборНаСервере(ВыбраннаяСтрока);
КонецПроцедуры

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

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

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

 

Применение метода рассматривается на примере отборов динамических списков, но этот же принцип можно использовать для работы с настройками СКД.

 

Заключение

Тестировалось на платформе 8.3.8+, режим совместимости 8.2.13+. Но описанные приемы должны работать и на более ранних версиях 1С 8.
 

has been added to your cart:
Оформление заказа