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

Программирование - Практика программирования

Табличная часть Таблица значений отбор поиск поиск на форме

14
В управляемых формах для нас доступен мощный ресурс работы с динамическими списками посредством СКД - отборы, сортировки и далее. Но вот табличная часть (таблица значений) на управляемой форме не позволяет работать так гибко. Мы можем научить пользователей пользоваться комбинацией клавиш "Ctrl+F", но давайте немного упростим жизнь и позволим нашим пользователям настраивать отборы (осуществлять поиск) по табличной части прямо в нашем окне.

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

Но вот мне понадобилась сделать "такой же поиск" в документе по табличной части. На мое предложение "заходим, нажимаем "Ctrl+F", вводим данные и получаем результат" мне был дан четкий ответ: "а поменьше нажимать можно? как вон там [в динамическом списке]?"

Победив желание сказать: "в 1С в этом случае можно работать только так!!", я задумался - а почему бы и нет? Ведь так будет удобнее большинству.

С мыслью: "Ну кто-то же уже должен был сделать что-то..." полез я искать в любимом нашем гугле. И, к удивлению, понял я, что именно в такой формулировке ничего не найти. Но на просторах интернета встретил я упоминание волшебных слов "ОтборСтрок". Когда-то с помощью данного расширения формы для отображения пользователям двух табличных частей, когда одна из них зависела от того, какая строка выбрана в другой (Если кому будет интересно - пишите. Поделюсь решением или напишу небольшую статью).

Почитав в конфигураторе справку, я обратил внимание на примечание и понял, это то, что нужно.

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

Для удобства создал небольшую демо конфигурацию для отображения примера настройки. Структура конфигурации простейшая: справочник "Номенклатура" и документ "Поступление товаров".

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

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

Для этого в форме в табличной части добавим пользовательские колонки реквизита табличной части с типом строка.

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

Теперь надо, чтобы данные колонки заполнялись. Для этого надо обработать события изменения номенклатуры в строке табличной части и события "ПриЧтенииНаСервере" и "ПослеЗаписиНаСервере".

Код, отвечающий за пересчет колонок при изменении номенклатуры следующий:

&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
	ТекДанные = Элементы.Товары.ТекущиеДанные;
	МассивПараметров = Новый Массив;
	МассивПараметров.Добавить("Код");
	МассивПараметров.Добавить("Наименование");
	
	Результат = ПолучитьПараметрыПоСсылка(ТекДанные.Номенклатура,МассивПараметров);
	
	ТекДанные.КодНоменклатуры = Результат.Код;
	ТекДанные.НаименованиеНоменклатуры = Результат.Наименование;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьПараметрПоСсылке(СсылкаНаОбъект,Параметр)
	Возврат СсылкаНаОбъект[Параметр];
КонецФункции

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

При чтении же уже записанного документа в базу нам надо так же не забыть заполнить данные колонки. В этом нам поможет код:

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
	ПеречитатьТабЧасть();
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
	ПеречитатьТабЧасть();
КонецПроцедуры

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

Для того, чтобы пользователь мог задать, а что же ему искать, добавим два реквизита формы с типом "Строка" и разместим их на форме:

 

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

Код, позволяющий установить отборы:

&НаКлиенте
Процедура ОтборКодОчистка(Элемент, СтандартнаяОбработка)
	УстановитьОтбор("КодНоменклатуры","");
КонецПроцедуры

&НаКлиенте
Процедура ОтборНаименованиеОчистка(Элемент, СтандартнаяОбработка)
	УстановитьОтбор("НаименованиеНоменклатуры","");
КонецПроцедуры

&НаКлиенте
Процедура ОтборКодИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка)
	УстановитьОтбор("КодНоменклатуры",Текст);
КонецПроцедуры

&НаКлиенте
Процедура ОтборНаименованиеИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка)
	УстановитьОтбор("НаименованиеНоменклатуры",Текст);
КонецПроцедуры

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

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

Поиск по таблице значений, размещенной на форме производится абсолютно аналогичным образом - "ОтборСтрок" доступен также для расширения управляемой формы для таблицы значений.

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

P.S. Если кому-нибудь нужен будет пример того, как в управляемых формах сделать зависимые друг от друга табличные части либо таблицы значений - прошу указать в комментариях

14

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

Наименование Файл Версия Размер
Отбор в табличной части (демо конфигурация)
.cf 11,50Kb
22.03.18
5
.cf 1.0.1 11,50Kb 5 Скачать

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. leosoft 128 22.03.18 10:45 Сейчас в теме
"Если кому-нибудь нужен будет пример того, как в управляемых формах сделать зависимые друг от друга табличные части либо таблицы значений - прошу указать в комментариях" -тоже интересно.
Еще интересно - через расширение нельзя это все сделать?
2. KAV2 22.03.18 11:23 Сейчас в теме
(1) В расширении можно всю форму поменять, поэтому да, можно.
3. Vortigaunt 23 24.03.18 01:12 Сейчас в теме
Из-за отличия в одну букву (которое сразу и не заметил) я уже подумал было, что наткнулся на новый прием программирования. Думаю, ну ничего себе, если передать в квадратные скобки после ссылки массив, то вернет структуру. А потом прокрутил ниже и расстроился. А было бы так прикольно(
4. Kuna1 05.10.18 12:20 Сейчас в теме
Предлагаю более простое решение данной задачи:

СтруктураПоиска = Новый Структура;
СтруктураПоиска.Вставить("Номенклатура", "Ябло");
Элементы.СписокВалют.ОтборСтрок = Новый ФиксированнаяСтруктура(СтруктураПоиска);
baracuda; +1 Ответить
5. baracuda 3 26.10.18 10:04 Сейчас в теме
(4) спасибо большое за ваш совет.
Интересно почему автор не сделал так же.
6. Kim1C 61 26.10.18 14:05 Сейчас в теме
(5)Согласен, вышеописанная структура сработает. По наименованию данная структура сработает. Но если мы хотим сделать отбор по коду, хотим сделать отбор по любому другому реквизиту такая структура не сработает (по крайней у меня не сработала). Если нам достаточно отбора по наименованию - то да, можно использовать вышеописанную структуру. Если мы говорим о других реквизитах или о нескольких - то я считаю лучше уже 1 раз делать универсально
7. baracuda 3 26.10.18 16:20 Сейчас в теме
(6) вас понял, спасибо за пояснение.
8. den_vrn 7 14.01.19 13:57 Сейчас в теме
Спасибо за статью, очень пригодилась! Но колонку с наименованием номенклатуры не добавлял, хорошо работает и с ссылочным типом.
Оставьте свое сообщение