новое событие
Информационный поток
Задания вакансии материалы разработки сообщения форума

Оптимизация отбора в управляемой форме динамического списка

  • Добавить свою публикацию
  • для этого требуется регистрация

Рис.1Изображение

 

 

 

Постановка задач.

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

 

Реализация.

1. Начинаем работать на закладке «Форма» управляемой формы списка, основной реквизит которой называется «Список».

Свойству формы АвтоматическоеСохранениеДанныхВНастройках задаем значение «Использовать».

Добавляем элемент формы поле ТекстОтбора, устанавливаем для него: путь к данным = «Список.Отбор» и вид = «Поле надписи».

Добавляем реквизиты формы: реквизит СписокОтборов тип СписокЗначений, реквизит ТекущийОтбор тип Произвольный. Устанавливаем для них флаг «Сохранение». В командную панель формы добавляем элементы: группу подменю ФормаГруппаБыстрыеОтборы, в эту группу добавляем кнопки ФормаКнопкаДобавитьВБыстрыеОтборы и ФормаКнопкаДобавитьВБыстрыеОтборыСНаименованием . В это же новое подменю добавляем группу кнопок ПереченьОтборов. (см рис. 1)

Для новых кнопок добавляем соответствующие команды: ДобавитьВБыстрыеОтборы - с обработчиком ДобавитьВБыстрыеОтборы(), и ДобавитьВБыстрыеОтборыСНаименованием - с обработчиком ДобавитьВБыстрыеОтборыСНаименованием().

  

2. В модуль формы добавляем код, необходимый для реализации поставленных задач. 

Начнём с обработчиков уже имеющихся команд:

&НаКлиенте 
Процедура ДобавитьВБыстрыеОтборы(Команда) 
	ДобавитьОтборВСписок(""); 
КонецПроцедуры 
 
 
&НаКлиенте 
Процедура ДобавитьВБыстрыеОтборыСНаименованием(Команда) 
	Згл=""; 
	Если ВвестиСтроку(Згл,"Введите наименование для текущего отбора") Тогда 
		ДобавитьОтборВСписок(СокрЛП(Згл)); 
	КонецЕсли; 
КонецПроцедуры 
 

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

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

(Эта процедура корректно работает только на сервере. Если вызывать её на клиенте, то впоследствии при очистке текущего отбора, очищается и отбор, добавленный в список.)  

Из данной процедуры вызываются в свою очередь: процедура, определяющая наименование отбора по умолчанию – ЗаполнитьСтрокуОтбора(…), и процедура добавляющая отбор непосредственно в интерфейс - ДобавитьОтборВИнтерфейс(…).

Процедура ЗаполнитьСтрокуОтбора(…) по сути выполняет действие аналогичное: «Згл=Строка(ТекОтбор)», и нужна для придания лучшей читаемости наименованию отбора.  

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

 Процедура ДобавитьОтборВИнтерфейс(…) добавляет в группу кнопок ПереченьОтборов подменю с наименованием отбора, подменю в свою очередь содержащее кнопки «Установить» и «Удалить». Кроме того, эта процедура добавляет и команды для обработки нажатий на кнопки «Установить» и «Удалить». Имена команд и кнопок отличаются последними символами, получаемыми из порядкового номера отбора в списке отборов.

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

Как видим, в процедуре ДобавитьОтборВИнтерфейс(…)  добавляемым командам устанавливаются действия, обрабатываемые  процедурами:

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

 Собственно, в процедуре УдалитьОтборИзСписка(...) ничего не удаляется, а только ставятся пометки для элементов, которые нужно удалить, т.к. если удалить сразу, то номера команд не будут уже соответствовать порядковому номеру в списке отборов.

Из процедуры УстановитьОтборИзСписка(…) вызывается рекурсивная процедура выстраивающая отбор динамического списка из отбора, сохраненного ранее в списке отборов.

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

 

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

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

 

  

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

 

 

 

 

 
0
Читайте также
Полезные мелочи
У программистов, занимающихся разработкой программного кода есть свой набор заготовок и решений, которые используются им и значительно облегчают дальнейшую работу
Ведение журнала регистрации 1С 8.1 в отдельной базе MSSQL.
Ваша база занимает десятки гигабайт, то ожидание просмотра журнала регистрации может занять много времени. Почему это происходит?
[СКД] Организация простейшего отчета с помощью схемы компоновки данных
Схема компоновки данных представляет большие возможности по отборам, группировкам и оформлению выходного макета
Разработки
Нумератор документов 7.7
Как установить нумерацию документов? Можно использовать во всех конфигурациях.
IBridges бесплатный сервис обмена первичными документами
Сервис обмена первичными документами для торговых предприятий
Удаленное управление с помощью нашего сервиса
Возможность удаленного управления
Еще от автора
≡ к списку статей