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

22.03.18

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

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

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

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

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

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

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

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

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

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

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

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

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

См. также

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

Обмен между базами 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. leosoft 165 22.03.18 10:45 Сейчас в теме
"Если кому-нибудь нужен будет пример того, как в управляемых формах сделать зависимые друг от друга табличные части либо таблицы значений - прошу указать в комментариях" -тоже интересно.
Еще интересно - через расширение нельзя это все сделать?
2. KAV2 156 22.03.18 11:23 Сейчас в теме
(1) В расширении можно всю форму поменять, поэтому да, можно.
3. Vortigaunt 96 24.03.18 01:12 Сейчас в теме
Из-за отличия в одну букву (которое сразу и не заметил) я уже подумал было, что наткнулся на новый прием программирования. Думаю, ну ничего себе, если передать в квадратные скобки после ссылки массив, то вернет структуру. А потом прокрутил ниже и расстроился. А было бы так прикольно(
KoC_one; zadoy; arshanskiyav; MaxTolya; slavikss; jura_b; +6 Ответить
4. Kuna1 05.10.18 12:20 Сейчас в теме
Предлагаю более простое решение данной задачи:

СтруктураПоиска = Новый Структура;
СтруктураПоиска.Вставить("Номенклатура", "Ябло");
Элементы.СписокВалют.ОтборСтрок = Новый ФиксированнаяСтруктура(СтруктураПоиска);
KoC_one; dammit666; Alex17; cleaner_it; Rozuriya; cheki; marku; anuar_medeup; alexandrmishinn; Dkh; baracuda; +11 Ответить
5. baracuda 2 26.10.18 10:04 Сейчас в теме
(4) спасибо большое за ваш совет.
Интересно почему автор не сделал так же.
6. Kim1C 178 26.10.18 14:05 Сейчас в теме
(5)Согласен, вышеописанная структура сработает. По наименованию данная структура сработает. Но если мы хотим сделать отбор по коду, хотим сделать отбор по любому другому реквизиту такая структура не сработает (по крайней у меня не сработала). Если нам достаточно отбора по наименованию - то да, можно использовать вышеописанную структуру. Если мы говорим о других реквизитах или о нескольких - то я считаю лучше уже 1 раз делать универсально
7. baracuda 2 26.10.18 16:20 Сейчас в теме
(6) вас понял, спасибо за пояснение.
23. ybatiaev 58 17.04.22 20:00 Сейчас в теме
(4) как раз в этом-то и проблемы. Нельзя именно так просто использовать
	ТД = Элементы.ТЗ_Верх.ТекущиеДанные;
	Отбор = Новый Структура("НомерСЧФ, ПокупательФайл", ТД.НомерСЧФ, ТД.ПокупательФайл);
	Элементы.ТоварФайл.ОтборСтрок = Новый ФиксированнаяСтруктура(Отбор);


Применение 2,3 и пр. полей может улучшить ситуацию.
А в Вашем примере попадают все строки, к примеру 58775/1, 58775/10, 58775/11, 58775/12....
8. den_vrn 12 14.01.19 13:57 Сейчас в теме
Спасибо за статью, очень пригодилась! Но колонку с наименованием номенклатуры не добавлял, хорошо работает и с ссылочным типом.
9. Azim_burkhanov 01.03.20 11:54 Сейчас в теме
у новичков нифига не работает((. на фото выше показана что добавлена ТЗ как таблица товаров. но в посте нету для чего она создана. и потом сам поиск вообще не пашет((
10. ixijixi 1777 11.06.20 17:27 Сейчас в теме
Столкнулся с тем, что метод ОтборСтрок очень затратный для сервера по ресурсам. Просто скрин для сравнения. В нижнем замере выполняется одна дополнительная строка кода ТаблицаФормы.ОтборСтрок = ФиксированнаяСтруктураОтборСтрок, а по времени код выполняется на порядок дольше. Ощутите накал: в коде выполнется запрос в цикле (там реально так) - время = 0.7, стоит установить отбор строк - время = 5.7!

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

Это все не очень заметно, пока в ТЧ пара десятков строк, но когда в ней будет 1.000, 10.000 строк - начнутся реальные тормоза.
Прикрепленные файлы:
11. Sashares 34 11.06.20 18:15 Сейчас в теме
(10)Т.к. данные табличной части подгружаются на клиент частями, чтобы не было тормозов, можно в ПриОткрытии выполнить обход всех строк ТЧ в цикле:

Для Каждого СтрТЧ Из МояТЧ Цикл КонецЦикла;


Тогда работа с данной таблицей на форме выполняется значительно быстрее.
kuzev; Barmi; ixijixi; +3 Ответить
12. ixijixi 1777 11.06.20 18:20 Сейчас в теме
(11) Так себе метод, если честно)
13. Sashares 34 11.06.20 18:22 Сейчас в теме
(12)Если альтернатива - чтобы пользователь по 6 сек ждал результат при интерактивной работе, вполне себе рабочий вариант.
14. ixijixi 1777 11.06.20 18:27 Сейчас в теме
(13) Ну нормально же сидели, чо вы начинаете))
При случае проверю
15. Sashares 34 11.06.20 18:31 Сейчас в теме
(14)Да просто такая же проблема была.
Форма группового редактирования, на форме несколько таблиц.
При активизации строки в таблице 1 - ставится отбор на другие.
Таблицы заполняются при создании на сервере.

И без чтения на клиенте данных таблицы 1, все сильно подвисало.
Сейчас значительно лучше.
Altez50; ixijixi; +2 Ответить
16. ixijixi 1777 11.06.20 18:33 Сейчас в теме
(15) Ну что ж, раз случай из реальной практики, тогда обязательно проверю!
17. ixijixi 1777 11.06.20 22:17 Сейчас в теме
(15) Проверил. Реально работает! Прочитал все строки всех ТЧ (это ~3.500 строк) при открытии, и отбор строк залетал! Как раз на порядок сократилось время установки отбора. Причем затраты на открытие формы выросли незначительно, с 0.4 сек до 2.1, что вполне терпимо для разовой операции. Спасибо за совет!
Прикрепленные файлы:
18. Sashares 34 12.06.20 22:17 Сейчас в теме
19. user1067759 04.09.20 06:37 Сейчас в теме
20. kinlex 10.12.20 11:38 Сейчас в теме
Добрый день.
Есть более элегантный способ поиска в таблице значений по всем столбцам, без программирования.
Необходимо использовать "Дополнение элемента формы".
Как выглядит этот элемент и результат применения его - на скрине.
Прикрепленные файлы:
gerandy; Izumov; dammit666; klaus38; Maxanamoon; AZel84; SimpleYa; Barmi; ixijixi; 1Снег; +10 Ответить
22. 1Снег 11 30.04.21 12:10 Сейчас в теме
(20) Оооо! Это я и искал, работает и без танцев с бубном!
21. lev6975 16.02.21 19:22 Сейчас в теме
Недостаток такого отбора строк - он ищет нежестко, поэтому, для отображения строк в списке по какому - то строковому критерию его использовать не выйдет... Он ищет вхождения а не точное совпадение, и, соответственно, "захватывает" и другие данные. Чем еще можно отобрать список на вьюшке? Без горождения огорода - делания дополнительной таблицы значений для показа...
Нужен отбор по текстовому параметру, который может быть длиной в 1 символ. Если это "а" или "о", то вообще всю таблицу показывает
mpvrus21; +1 Ответить
24. vechiy 35 10.03.23 10:27 Сейчас в теме
а если отбор нужен по ссылке?

Новый ФиксированнаяСтруктура("Контрагент" , Справочники.Контрагенты.НайтиПоКоду("").Ссылка); - работает
Новый ФиксированнаяСтруктура("Контрагент" , СписокЗначений); - не работает

почему?
25. Kim1C 178 10.03.23 13:12 Сейчас в теме
(24)
Насколько я знаю работает отбор только по равенству либо частичному совпадению. Список не работает - надо по другому как-то думать
27. denkaz 26.09.23 15:09 Сейчас в теме
(25)
не работает по списку значений

Я добавляю служебное поле типа Булево. Далее в процедуре вместо заполнения списка с отбором обхожу таблицу и устанавливаю Истина в нужные строки. Потом уже использую ОтборСтрок по служебному полю по равенству на Истина.
26. codent 31.03.23 13:28 Сейчас в теме
(24)

Новый ФиксированнаяСтруктура("Контрагент" , Справочники.Контрагенты.НайтиПоКоду("").Ссылка); - работает


А зачем ссылку от ссылки получать? Метод НайтиПоКоду возвращает ссылку. У тебя получилось КонтрагентСсылка = Ссылка.Ссылка;
Этим ты создаёшь полный объект в объектном кэше; Т.е. сначала у тебя выполняется запрос для получение ссылки(НайтиПоКоду), а следом летит еще один запрос на получение целого объекта по ссылке (Ссылка.Ссылка), который сохраняется в объектном кэше. При чем со всеми реквизитами, табличными частями, если есть реквизит с типом хранилище значений, то и двоичные данные загрузятся. А потом удивляемся, что это у нас 1с такая тормозная.
28. user1432326 63 11.01.24 03:44 Сейчас в теме
Использовал поиск в ТаблицеЗначений на Форме по Колонке1 все работает
1) Добавил реквизит "ПоискПоКолонке1" тип строка
2) Использовал событие "ИзменениеТекстаРедактирования"

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

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