Одним из неприятных моментов при работе с динамическими списками управляемого приложения является невозможность использования такой привычной для обычного приложения опции, как «поиск по строке». Предлагаю один из вариантов реализации поиска по первым буквам в динамическом списке на основе общей Формы Подбора из типовой конфигурации УНФ.
В описанном ниже примере поиск вместе с сортировкой по полю реализован для колонок Код, Артикул, Наименование.
Добавляем Реквизиты формы ПоискКод, ПоискАртикул, ПоискНаименование с типом «Строка».Вносим их в Группу Поиск на форме.
Программируем события поля ввода АвтоПодбор:
&НаКлиенте
Процедура ПоискАртикулАвтоПодбор(Элемент, Текст, ДанныеВыбора, Ожидание, СтандартнаяОбработка)
// Вставить содержимое обработчика.
ПоискКод = «»;
ПоискНаименование = «»;
Если СокрЛП(Текст) = «» Тогда
СписокЗапасов.Отбор.Элементы.Очистить();
возврат;
КонецЕсли;
Установитьпорядок(«Артикул»);
УстановитьПоискПоСтрокеНаСервере(Текст, «Артикул»);
КонецПроцедуры
процедура Установитьпорядок(ИмяПоля)
Если НЕ (СписокЗапасов.Порядок.элементы.количество() = 1 и СписокЗапасов.Порядок.элементы[0].поле = Новый ПолеКомпоновкиДанных(ИмяПоля)) тогда
СписокЗапасов.Порядок.элементы.очистить();
НЭлемент = СписокЗапасов.Порядок.Элементы.Добавить(Тип(«ЭлементПорядкаКомпоновкиДанных»));
НЭлемент.Использование = Истина;
НЭлемент.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
НЭлемент.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
НЭлемент.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Обычный;
конецЕсли;
КонецПроцедуры
&НаСервере
Процедура УстановитьПоискПоСтрокеНаСервере(Текст, ИмяКолонки)
ПостроительЗапроса = новый построительЗапроса;
ПостроительЗапроса.Текст = «ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| ПОДСТРОКА(Номенклатура.» + ИмяКолонки + » , 1, &Длина) = &Зн
|{ГДЕ
| Номенклатура.Ссылка.*}»;
ПостроительЗапроса.Параметры.Вставить(«Длина», СтрДлина(Текст));
ПостроительЗапроса.Параметры.Вставить(«Зн», Текст);
Если Не СписокЗапасов.Параметры.элементы[2].Значение = Справочники.Номенклатура.ПустаяСсылка() тогда
НЭлемент = ПостроительЗапроса.Отбор.Добавить(«Ссылка»);
НЭлемент.ВидСравнения = ВидСравнения.ВИерархии;
НЭлемент.Значение = СписокЗапасов.Параметры.элементы[2].Значение;
НЭлемент.Использование = Истина;
КонецЕсли;
ПостроительЗапроса.Выполнить();
ТЗ = Построительзапроса.Результат.Выгрузить();
Сп = новый СписокЗначений;
Сп.ЗагрузитьЗначения(ТЗ.ВыгрузитьКолонку(«Ссылка»));
СписокЗапасов.Отбор.Элементы.Очистить();
НЭлемент = СписокЗапасов.Отбор.Элементы.добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
Нэлемент.левоеЗначение = новый ПолекомпоновкиДанных(«Номенклатура»);
НЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
НЭлемент.ПравоеЗначение = Сп;
НЭлемент.Использование = истина;
КонецПроцедуры
&НаКлиенте
Процедура ПоискАртикулОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, СтандартнаяОбработка)
// Вставить содержимое обработчика.
Этаформа.ТекущийЭлемент = Элементы.СписокЗапасов;
КонецПроцедуры
Таким образом получаем , что при наборе первых букв искомого варианта в поле «по артикулу» , например, группы поиска, происходит сортировка списка по колонке Артикул и отбор тех строк, артикул которых начинается с набранных символов.
Тут , конечно, был бы удачнее не отбор, а позиционирование на первом найденном в списке элементе . Т.е. мне бы хотелось в тексте запроса Построителя добавить «Первые 1» и дальше просто позиционироваться на найденной ссылке, но как найти позицию в динамическом списке ? Ответа на этот вопрос не нашла.
Буду рада любым предложениям по оптимизации этого варианта решения вопроса или ссылкам на другой вариант решения.
AlenaSa,благодарю Вас! Я воспользовался Вашей разработкой функционала «Поиск по строке».
Не знаю,может не правильно,но сделал так. В УФ добавил группу Поиск с симвоьным полем для ввода фрагмента наименования.
В обработке события при изменении поля поиска так:
&НаКлиенте
Процедура ПоискПоНаименованиюПриИзменении(Элемент)
// Вставить содержимое обработчика.
Если СокрЛП(Элемент.ТекстРедактирования) = «» Тогда
Список.Отбор.Элементы.Очистить();
возврат;
КонецЕсли;
//Установитьпорядок(«Артикул»);
УстановитьПоискПоСтрокеНаСервере(Элемент.ТекстРедактирования, «Наименование»);
КонецПроцедуры
&НаСервере
Процедура УстановитьПоискПоСтрокеНаСервере(Текст, ИмяКолонки)
ПостроительЗапроса = новый построительЗапроса;
ПостроительЗапроса.Текст =
«ВЫБРАТЬ
| Контрагенты.Ссылка
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.Наименование ПОДОБНО &Зн»
;
ПостроительЗапроса.Параметры.Вставить(«Зн», «%»+Текст+»%»);
ПостроительЗапроса.Выполнить();
ТЗ = Построительзапроса.Результат.Выгрузить();
Сп = новый СписокЗначений;
Сп.ЗагрузитьЗначения(ТЗ.ВыгрузитьКолонку(«Ссылка»));
Список.Отбор.Элементы.Очистить();
НЭлемент = Список.Отбор.Элементы.добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
Нэлемент.левоеЗначение = новый ПолекомпоновкиДанных(«Контрагент»);
НЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
НЭлемент.ПравоеЗначение = Сп;
НЭлемент.Использование = истина;
КонецПроцедуры
Вроде бы работает. Учитывая,что УФ только начинаю изучать,то рад и этому. Спасибо.
Спасибо всем за комментарии. Рада, что пригодилась публикация и есть развитие идеи.
Сама сейчас вернулась к УПП, которое ещё на обычном приложении.
УНФ не пользуется пока что на Украине популярностью, хотя мне очень понравилась, когда изучала и предлагала клиентам.