gifts2017

Организация универсальной формы подбора (платформа 8.3)

Опубликовал Александр Честикин (cheiser1982) в раздел Программирование - Практика программирования

Организация процедуры подбора из произвольной таблицы.

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

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

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

Текст кода из формы документа, откуда вызываем форму выбора:

&НаКлиенте
Процедура КнопкаПодбор(Команда)
	ПараметрыПодбора = Новый Структура;
	ПараметрыПодбора.Вставить("ЗакрыватьПриВыборе", Ложь);
	ПараметрыПодбора.Вставить("РежимВыбора", Истина);
	ПараметрыПодбора.Вставить("АдресТаблицыВыбранныхДанных", АдресСпискаПодобранныхПоказаний());		
	ПараметрыПодбора.Вставить("АдресТаблицыИсходныхДанных",  ФормированиеТаблицыПодбора(ДобавитьМесяц(ТекущаяДата(), -18*12)));//Выберем совершеннолетних
	ОткрытьФорму("ОбщаяФорма.ОбщаяФормаПодбора", ПараметрыПодбора, Элементы.ФизическиеЛица);
КонецПроцедуры

&НаСервере
Функция АдресСпискаПодобранныхПоказаний()
	Возврат ПоместитьВоВременноеХранилище(Объект.ФизическиеЛица.Выгрузить(,"ФизическоеЛицо"), УникальныйИдентификатор);
КонецФункции

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

&НаКлиенте
Процедура ФизическиеЛицаОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)	
	Объект.ФизическиеЛица.Очистить();	
	ВыбранныеДанныеВТаблицуДокумента(ВыбранноеЗначение);
КонецПроцедуры

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

Далее работаем с формой подбора.

После вызова формы, считываем входные параметры, формируем таблицы на форме и переносим в них данные для подбора:

#Область НачалоРаботыСФормой

//Считываем входные параметры и формируем таблицы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)			
	ФормированиеТаблицы("ТалицаИсходныхДанных",		Параметры.АдресТаблицыИсходныхДанных);
	ФормированиеТаблицы("ТаблицаВыбранныхДанных",	Параметры.АдресТаблицыВыбранныхДанных);
КонецПроцедуры

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

#КонецОбласти

Для обработки выбранных данных использую следующие процедуры и функции:

#Область ОбъектыДляОбработкиВыбора

&НаКлиенте
Процедура ТалицаИсходныхДанныхВыборЗначения(Элемент, Значение, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	ВыборСтроки(Элемент.ТекущиеДанные);
	ЭтотОбъект.ТалицаИсходныхДанных.Удалить(Элемент.ТекущиеДанные);
КонецПроцедуры

&НаКлиенте
Процедура ВыбратьВсе(Команда)
	Для Каждого СтрокаТаблицы Из ЭтотОбъект.ТалицаИсходныхДанных Цикл
		ВыборСтроки(СтрокаТаблицы);
	КонецЦикла;
	ЭтотОбъект.ТалицаИсходныхДанных.Очистить();
КонецПроцедуры

&НаКлиенте
Функция ВыборСтроки(ВыбраннаяСтрока)
	НоваяСтрока = ЭтотОбъект.ТаблицаВыбранныхДанных.Добавить();
	ЗаполнитьЗначенияСвойств(НоваяСтрока, ВыбраннаяСтрока);
КонецФункции

#КонецОбласти

Следующая функция из имени колонки формирует синоним для заголовка колонки таблицы на форме:

&НаСервереБезКонтекста
// Формирует синоним переменной.
// Пример: на входе "ИмяПеременнойАБВГ", на выходе "Имя переменной АБВГ"
//
// Параметры
// ИмяРеквизита - Строка. Имя переменной, имя колонки таблицы
//
// Возвращаемое значение:
// Строка - Представление переменной
//
Функция СформироватьСиноним(ИмяРеквизита)
Перем Синоним, НомерСимвола, Символ, ПредСимвол, СледСимвол, Прописная, ПредПрописная, СледПрописная, ДлинаСтроки;
	Синоним = ВРег(Сред(ИмяРеквизита, 1, 1));
	ДлинаСтроки = СтрДлина(ИмяРеквизита);
	Для НомерСимвола = 2 По ДлинаСтроки Цикл
		Символ = Сред(ИмяРеквизита, НомерСимвола, 1);
		ПредСимвол = Сред(ИмяРеквизита, НомерСимвола - 1, 1);
		СледСимвол = Сред(ИмяРеквизита, НомерСимвола + 1, 1);
		Прописная = Символ = ВРег(Символ);
		ПредПрописная = ПредСимвол = ВРег(ПредСимвол);
		СледПрописная = СледСимвол = ВРег(СледСимвол);

		// Варианты:
		Если НЕ ПредПрописная И Прописная Тогда
			Синоним = Синоним + " " + НРег(Символ);
		ИначеЕсли Прописная И НЕ СледПрописная Тогда
			Синоним = Синоним + " " + НРег(Символ);
		Иначе
			Синоним = Синоним + НРег(Символ);
		Конецесли;
	КонецЦикла;

	Возврат Синоним;

КонецФункции // СформироватьСиноним(ИмяРеквизита)

После завершения работы, форма поместит таблицу выбранных значений во временное хранилище и вернет в вызвавший ее объект адрес этой таблицы в хранилище.

Фрагмент текста кода из формы подбора:

&НаКлиенте
Процедура ПеренестиДанные(Команда)
	ОповеститьОВыборе(АдресТаблицыВыбранныхДанных());
	ЭтаФорма.Закрыть();
КонецПроцедуры

//Перед отправкой результата в вызвавший ее объект, поместим таблицу выбранных данных в хранилище.
&НаСервере
Функция АдресТаблицыВыбранныхДанных()
	Возврат ПоместитьВоВременноеХранилище(ЭтотОбъект.ТаблицаВыбранныхДанных.Выгрузить(), УникальныйИдентификатор);
КонецФункции

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

Наименование Файл Версия Размер
Конфигурация с формой подбора и небольшим примером 12
.rar 35,58Kb
17.04.15
12
.rar 35,58Kb Скачать

См. также

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