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

22.03.18

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

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Отбор в табличной части (демо конфигурация)
.cf 11,50Kb ver:1.0.1
32
32 Скачать (1 SM) Купить за 1 850 руб.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

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

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

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

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

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

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

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

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

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

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

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

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

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    7522    bayselonarrend    20    

154

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5970    dsdred    16    

80

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    17837    YA_418728146    26    

71

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23789    SeiOkami    48    

135

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14788    YA_418728146    7    

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

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


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

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

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

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


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

И без чтения на клиенте данных таблицы 1, все сильно подвисало.
Сейчас значительно лучше.
Altez50; ixijixi; +2 Ответить
16. ixijixi 1913 11.06.20 18:33 Сейчас в теме
(15) Ну что ж, раз случай из реальной практики, тогда обязательно проверю!
17. ixijixi 1913 11.06.20 22:17 Сейчас в теме
(15) Проверил. Реально работает! Прочитал все строки всех ТЧ (это ~3.500 строк) при открытии, и отбор строк залетал! Как раз на порядок сократилось время установки отбора. Причем затраты на открытие формы выросли незначительно, с 0.4 сек до 2.1, что вполне терпимо для разовой операции. Спасибо за совет!
Прикрепленные файлы:
18. Sashares 35 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 188 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 74 11.01.24 03:44 Сейчас в теме
Использовал поиск в ТаблицеЗначений на Форме по Колонке1 все работает
1) Добавил реквизит "ПоискПоКолонке1" тип строка
2) Использовал событие "ИзменениеТекстаРедактирования"

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

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