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