gifts2017

Быстрый подбор по вхождению слова в наименование

Опубликовал Олег Пономаренко (O-Planet) в раздел Программирование - Инструментарий

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

И чего не сделаешь ради клиента!

Говоришь: "Нельзя этого! Не предусмотрели разрабы 1С!"

А он: "Хоцца!"

И ведь не приемлют отказа... А может, это только тогда, когда со мной работают? Умеют же другие говорить "нет", и им охотно верят! Помнится, какой-то новый клиент на полном серьезе уверял меня, что нельзя в отчет 1С вывести одновременно сумму из шапки и из табличной части одного документа по строкам, чтобы сумма в шапке не умножилась на количество строк. Так программист сказал... И сделал поэтому дублирующий табличную часть и шапку регистр, чтобы данные в отчеты выводить. Разумеется, взял за свою работу оплату...

Но в моем случае, ситуация хуже, хотя проблему начинаешь понимать только в процессе реализации. На первый взгляд, кажется, что все просто, ведь выпадающий список заполнить по вхождению не сложно. Используем ПОДОБНО и - вуаля: список есть!

З=Новый Запрос(

"ВЫБРАТЬ

| Контрагенты.Наименование КАК Наименование

|ИЗ

| Справочник.Контрагенты КАК Контрагенты

|ГДЕ

| Контрагенты.Наименование ПОДОБНО &Наименование

| И НЕ Контрагенты.ПометкаУдаления

| И НЕ Контрагенты.ЭтоГруппа

|

|УПОРЯДОЧИТЬ ПО

| Наименование");

З.УстановитьПараметр("Наименование","%"+Текст+"%");

Рез=З.Выполнить().Выгрузить();

СписокКА.ЗагрузитьЗначения(Рез.ВыгрузитьКолонку("Наименование"));

Осталось решить вопрос, как присоединенный к полю ввода список открыть. Казалось бы, простая функция: изменить программно видимость существующего списка, привязанного к элементу формы. А нету!

Но решение вроде как дает метод "ВыбратьИзСписка". Он позволяет открыть сформированный список и что-то из него выбрать. Правда, список в этом случае уже не будет списком поля ввода, а должен быть создан программно. Но разве это проблема? 

...

СписокКА = Новый СписокЗначений;

СписокКА.ЗагрузитьЗначения(Рез.ВыгрузитьКолонку("Наименование"));

ВыбратьИзСписка(СписокКА, ЭлементыФормы.ПолеКА);

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

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

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

И так,  решение:

  • - Делаем список на форме, видимость = false
  • - Заполнение вешаем на обработчик автоподбора текста
  • - Заполнили - делаем видимым

И - фишка! Привязываем к форме обработчик ожидания: если список выбора открыт и фокус на поле ввода или этом списке - все ок. Как только фокус ушел на что-то еще - список закрываем.

Работает! Можно скачать в прилагаемом архиве и использовать.

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

Наименование Файл Версия Размер
Быстрый подбор по вхождению слова 127
.zip 4,64Kb
19.09.16
127
.zip 4,64Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Андрей (andru_dv) 10.01.13 13:31
А если список справочника содержит десятки тысяч наименований, какая будет производительность у этого решения?
И ещё. Можно ли сделать распознавание регистра верхний/нижний.
2. qweasd qweasdzc (serega3333) 10.01.13 16:30
З.УстановитьПараметр("Наименование","%"+Текст+"%") - если искать товары с % и другими спецсимволами - не прокатит, будь мужиком, прокачай до конца =)
3. Maxim Kolkin (the1) 10.01.13 17:01
(1)ВЫБРАТЬ ПЕРВЫЕ 100 подойдет?
4. Олег Пономаренко (O-Planet) 10.01.13 18:17
(2) За наименования со спецсимволами нужно отрывать мышку...
5. TMV 10.01.13 21:17
(3) the1, в ЗУП при подборе сотрудников стандартом идет 50, (1) еще можно начинать искать только после набора 3 букв и более..
(4) O-Planet, интересно можно ли подобную феньку прикрутить к табличной части?
И еще, мне ж все-таки иногда нужно из списка выбрать значение, а не просто его видеть..
6. Олег Пономаренко (O-Planet) 11.01.13 00:50
У меня там тоже есть параметр, после скольки символов в слове начинать искать. А по поводу ТЧ, если очень захотеть, то можно.
7. TMV 11.01.13 11:57
(6) O-Planet, предлагаете двигать по форме список?
8. al petrov (petrov_al) 14.01.13 08:54
А полнотекстовый поиск не пробовали, потестите...думаю по скорости он опередит ваш механизм
9. Eugeneer (Eugeneer) 19.02.13 19:36
Я это уже года 4 использую в своих решениях.
Например подборе номенклатуры
http://infostart.ru/public/81688/
Работает изумительно.
http://infostart.ru/upload/iblock/28d/consol_saler2.png

Полнотекстовый типовой и рядом не стоял.
10. Eugeneer (Eugeneer) 19.02.13 19:36
Только у меня по любым слогам любых слов в любом порядке. Включая сразу артикул, код, штрихкод, краткое и полное наименование. Вот люди попросили еще и сделать по доп реквизитам.
11. Eugeneer (Eugeneer) 19.02.13 19:39
Вот кстати в бухгалтерии вообще пипец. в справонике контрагентов даже поиск не сделали нормальный.
Пришлось рмм написать целое для поиском и подбором номенклатуры, поиска контрагента и отображения по нему всех доков в журналах и тп.
Иначе вообще работать не реально!
12. Maxim k (maxis33) 11.03.13 10:56
1Совцы об этом тоже подумали...
http://v8.1c.ru/o7/201302ss/
mumilkin; a-novoselov; +2 Ответить 3
13. Алексей (ADirks) 30.04.13 09:13
(12) Круто! И всего то каких-то шесть - семь лет понадобилось :)
Интересно, сколько лет понадобится, чтобы к этому ещё произвольные фильтры прикрутить?

По хорошему, надо выделить поставщика данных для такого поля ввода, и дать им рулить как хочешь. Фильтруй по чём и как хочешь, показывай что хочешь (например, остатки товара полезно показывать). Хорошо бы ещё иконками в списке рулить, и строки раскрашивать. Но этого конечно 1С никогда не сделает.

А в семёрке это реализовано :)
14. Михаил Ражиков (tango) 30.04.13 10:13
(12) maxis33, подумали: ...а-а-а! - не нам обновлять!..
15. Михаил Ражиков (tango) 30.04.13 10:23
чё-та не пойму, обещалово не работает
http://v8.1c.ru/o7/201304rl/index.htm
платформа 8.3.2.172 - ни областей, ни ссылок
16. Alexander Shvets (Alexander.Shvets) 30.04.13 16:57
Спасибо! Натолкнуло на мысль =)))
Буду пробовать в упр. приложении реализовать... А вот это будет очень интересно =))
17. Павел Александрович (oslokot) 24.06.13 15:01
O-Planet Добрый день! можно у Вас попросить обработку.
Сам автоподбор у меня работает, все хорошо, но не могу победить перехват фокуса.
Идея с дополнительным списком на форме понравилась, но застрял с ее реализацией. Как то корявенько получается.
Можно поглядеть? если не трудно, скиньте на oslokot(собака)mail.ru
18. Геннадий Зимин (kenza) 22.07.13 12:14
(12) maxis33, чет не могу найти у себя подобных свойств.
19. Павел Александрович (oslokot) 23.07.13 09:20
20. Тимур Иванов (stepman3) 28.08.13 13:17
а в тонком клиенте будет работать? ;-)
21. Alexandr Kuritsyn (hibico) 12.03.14 13:54
Столкнулся с подобной проблемой. Решил несколько по другому. Поле списка создается программно.
Перем мПолеПодбора, мЭлементПодбора;

Процедура ВыборВПоле(Элемент, ЭлементСписка)
	мЭлементПодбора.Значение = ЭлементСписка.Значение;
	ЭлементыФормы.Удалить(Элемент);
КонецПроцедуры

Процедура ПолеВводаАвтоПодборТекста(Элемент, Текст, ТекстАвтоПодбора, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	СписокВыбора = ЭлементыФормы.Найти("ПолеПодбора");
	Если СписокВыбора = Неопределено Тогда
		СписокВыбора = ЭлементыФормы.Добавить(Тип("ПолеСписка"),"ПолеПодбора");
		СписокВыбора.Верх = Элемент.Верх+Элемент.Высота;
		СписокВыбора.Лево = Элемент.Лево;
		СписокВыбора.Ширина = Элемент.Ширина;
		СписокВыбора.УстановитьДействие("Выбор",Новый Действие("ВыборВПоле"));
		СписокВыбора.ПорядокОбхода = Элемент.ПорядокОбхода+1;
	КонецЕсли;
	
	мЭлементПодбора = Элемент;
	мПолеПодбора = СписокВыбора;
	
	СписокОтбора = ОтобратьЗначения(Текст); // отдельная процедура подбора по первым символам
	                                        // здесь не привожу
	Если СписокОтбора.Количество()<2 Тогда
		ЭлементыФормы.Удалить(СписокВыбора);
		мПолеПодбора = Неопределено;
	Иначе
		СписокВыбора.Значение = СписокОтбора;
		СписокВыбора.Высота = 20*СписокОтбора.Количество();
	КонецЕсли;
	
	Если СписокОтбора.Количество()=1 Тогда
		ТекстАвтоПодбора = СписокОтбора[0].Значение;
	КонецЕсли;
	
КонецПроцедуры

Процедура ОбновлениеОтображения()
	Если мПолеПодбора <> Неопределено И ТекущийЭлемент <> мПолеПодбора И ТекущийЭлемент <> мЭлементПодбора Тогда
		ЭлементыФормы.Удалить(мПолеПодбора);
	КонецЕсли;	
КонецПроцедуры

...Показать Скрыть

Пример прикрепил.
Прикрепленные файлы:
Автоподбор.epf
kare; vsozansky; +2 Ответить 1
23. Ерофеев Юрий (luic) 17.08.14 10:03
Класс!!! Жаль что у меня 8.1 Очень нужная вещь!!!
24. Adapter Бахтыреев (adapter) 05.06.15 12:27
зачем изобретать велосипеды? В 8.2 все работает через процедуру

ОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Значение = ОтобратьЗначения(Текст);

25. Dima (sokir) 19.08.16 18:13
(21) hibico, это нормально работает с полем ввода, но не работает с табличным полем, а ведь именно в табличном поле пользователи и набирают товар.