В типовых конфигурациях 1С, таких как 1С:Комплексная автоматизация 2 или 1С:ERP, пользователи часто сталкиваются с тем, что стандартный поиск в поле ввода или в форме подбора работает только по началу строки. Это создает неудобства, когда нужно найти товар по фрагменту наименования, находящемуся в середине. В этой статье мы подробно разберем, как изменить это поведение и реализовать поиск по любой части слова.
Прежде чем приступать к написанию кода, проанализируем, почему стандартный поиск может работать не так, как ожидается. В платформе 1С 8.3 поведение поиска во многом зависит от настроек Полнотекстового поиска (ППС).
Разберем основные моменты:
Номенклатура в конфигураторе есть свойство «Способ поиска при вводе по строке». Оно может иметь значения «Начало строки» или «Любая часть». Если установлено первое, система будет ограничивать выборку.Если стандартные настройки не помогают, переходим к программному решению задачи.
Один из эффективных способов — подменить стандартный алгоритм поиска в момент ввода текста пользователем. Для этого мы будем использовать событие элемента формы ИзменениеТекстаРедактирования. Рассмотрим пошагово, как это реализовать.
Нам необходимо создать два метода: один на стороне клиента для перехвата ввода, другой на сервере для выполнения поискового запроса в базе данных. Проанализируем пример кода:
&НаКлиенте
Процедура ТоварыНоменклатураИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка)
// Отключаем стандартный механизм поиска 1С
СтандартнаяОбработка = Ложь;
// Вызываем серверную функцию для поиска данных
СписокДанных = ПолучитьДанныеВыбораНаСервере(Текст);
// Выводим список пользователю
Элемент.ВыбратьИзСписка(СписокДанных);
КонецПроцедуры
Теперь разберем серверную часть, где происходит основной поиск с использованием оператора ПОДОБНО. Важно помнить, что для поиска по любой части слова текст должен быть обрамлен символами процента %.
&НаСервереБезКонтекста
Функция ПолучитьДанныеВыбораНаСервере(Знач Текст)
ДанныеВыбора = Новый СписокЗначений;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 50
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| (Номенклатура.Наименование ПОДОБНО &Текст
| ИЛИ Номенклатура.Артикул ПОДОБНО &Текст)
| И НЕ Номенклатура.ЭтоГруппа";
Запрос.УстановитьПараметр("Текст", "%" + Текст + "%");
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
ДанныеВыбора.Добавить(Выборка.Ссылка, Выборка.Наименование);
КонецЦикла;
Возврат ДанныеВыбора;
КонецФункции
Рассмотрим важный технический нюанс. Использование конструкции ПОДОБНО "%Текст%" приводит к тому, что СУБД не может использовать индексы по полю Наименование. Это означает, что при каждом вводе символа сервер будет выполнять полное сканирование (Full Scan) таблицы номенклатуры.
Последствия: если в вашей базе данных более 50-100 тысяч позиций номенклатуры, интерфейс пользователя начнет «замирать» при вводе каждой буквы. Проанализируем альтернативы:
ПолнотекстовыйПоиск.Найти(). Это работает значительно быстрее, так как поиск идет по заранее подготовленному индексу.ПЕРВЫЕ... в запросе, чтобы не перегружать память сервера и клиента.Для более «нативной» работы выпадающего списка лучше использовать событие АвтоПодбор. Основное отличие заключается в параметре ДанныеВыбора, который система ожидает получить для автоматического отображения списка под полем ввода.
Разберем пример реализации через АвтоПодбор:
&НаКлиенте
Процедура ТоварыНоменклатураАвтоПодбор(Элемент, Текст, ДанныеВыбора, Параметры, СтандартнаяОбработка)
Если СтрДлина(Текст) < 3 Тогда
Возврат;
КонецЕсли;
СтандартнаяОбработка = Ложь;
ДанныеВыбора = НайтиНоменклатуруПоПодстроке(Текст);
КонецПроцедуры
В этом случае ДанныеВыбора — это СписокЗначений, который платформа сама отрисует в удобном для пользователя виде.
Поскольку 1С:Комплексная автоматизация 2 является типовым решением, крайне не рекомендуется вносить изменения напрямую в код основной конфигурации. Это затруднит дальнейшие обновления системы.
Выясним, как правильно применить расширение:
КоммерческоеПредложениеКлиенту) и его форму.Номенклатура создаем обработчик события, используя метод «Вместо» или «После».РежимВыбораИзСписка или АвтоОтметкаНезаполненного, не затрагивая основную конфигурацию.Для удобства пользователей часто требуется искать не только по наименованию, но и по артикулу или коду товара. В нашем запросе мы уже добавили условие ИЛИ Номенклатура.Артикул ПОДОБНО &Текст. Посмотрим, как можно улучшить этот механизм:
Пользователи часто вводят артикул не полностью или с ошибками. Проанализируем ситуацию, когда нужно искать по вхождению в любое из полей. В таких случаях можно объединить поля поиска в одну виртуальную строку в запросе, но это еще сильнее замедлит работу базы. Поэтому лучшим решением остается использование ППС или четкое разделение логики: если введены только цифры — ищем по артикулу, если буквы — по наименованию.
Мы рассмотрели несколько способов реализации поиска по любой части слова. Наиболее простым и быстрым в реализации является использование события ИзменениеТекстаРедактирования с прямым запросом к БД. Однако для высоконагруженных систем с огромными справочниками номенклатуры обязательным условием является использование Полнотекстового поиска и механизмов Расширений для сохранения поддержки программного продукта.
Выбирайте метод в зависимости от объема ваших данных и требований к скорости работы интерфейса. Помните о комфорте пользователя: быстрый поиск по 50 позициям лучше, чем медленное ожидание полной выборки из всей базы данных.