При работе в 1С версии 7.7 пользователи часто сталкиваются с ограничением стандартного механизма поиска в справочниках: поиск по умолчанию осуществляется только по первым символам наименования. Однако в современных реалиях, когда справочники товаров могут насчитывать десятки тысяч позиций, критически важной становится возможность поиска по подстроке. Например, при вводе слова «Витаминный» система должна отображать не только «Витаминный комплекс», но и «Комплекс витаминный», и «Салат витаминный».
В данной статье мы подробно разберем несколько способов реализации этой задачи, начиная от штатных возможностей типовых конфигураций и заканчивая использованием мощных внешних библиотек для ускорения работы интерфейса.
В типовом решении «Торговля и Склад» (TiS) разработчиками предусмотрена специальная обработка ПоискПоПодстроке.ert. Рассмотрим принцип её работы. Основная идея заключается в том, чтобы не ограничивать выборку стандартными фильтрами платформы, а сформировать список элементов, удовлетворяющих условию, и «навязать» его форме подбора.
Разберем алгоритм по шагам:
Найти().СписокЗначений.ИспользоватьСписокЭлементов().Проанализируем пример кода, который реализует подобную логику:
// Пример формирования списка найденных элементов
СписокНайденных = СоздатьОбъект("СписокЗначений");
Спр = СоздатьОбъект("Справочник.Номенклатура");
Спр.ВыбратьЭлементы();
Пока Спр.ПолучитьЭлемент() = 1 Цикл
Если Найти(Врег(Спр.Наименование), Врег(СтрокаПоиска)) > 0 Тогда
СписокНайденных.ДобавитьЗначение(Спр.ТекущийЭлемент());
КонецЕсли;
КонецЦикла;
// Передача списка в форму подбора
ИспользоватьСписокЭлементов(СписокНайденных);
Важно помнить, что этот метод имеет существенный недостаток — низкую производительность на больших объемах данных. Если в справочнике 50 000 позиций, полный перебор будет занимать заметное время при каждом поиске.
Если ваша база данных работает на MS SQL Server, наиболее эффективным решением будет использование внешней компоненты 1С++. Она позволяет выполнять прямые SQL-запросы к таблицам базы данных, минуя объектную модель 1С, что ускоряет поиск в десятки и сотни раз.
Рассмотрим ситуацию: нам нужно найти товары, в наименовании которых встречается фрагмент текста. На языке SQL это решается оператором LIKE. Проанализируем пример использования класса ODBCRecordset:
ТекстЗапроса = "
|SELECT
| Спр.ID as [Элемент $Справочник.Номенклатура]
|FROM
| $Справочник.Номенклатура as Спр
|WHERE
| Спр.DESCR LIKE :ТекстПоиска
|";
Запрос = СоздатьОбъект("ODBCRecordset");
Запрос.УстановитьТекстовыйПараметр("ТекстПоиска", "%" + СокрЛП(ПоисковаяСтрока) + "%");
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
Использование знака процента % в параметре запроса указывает SQL-серверу на необходимость поиска вхождения в любой части строки. Полученную таблицу значений можно быстро превратить в СписокЗначений и использовать уже знакомый нам метод ИспользоватьСписокЭлементов().
Для того чтобы сделать поиск максимально удобным для пользователя, можно реализовать так называемый инкрементальный поиск (результаты обновляются сразу при нажатии клавиш, без нажатия кнопки «ОК» или Enter). Для этого потребуется библиотека FormEx.
С помощью FormEx мы можем перехватывать событие ПриНажатииКнопкиКлавиатуры. Это позволяет при каждом вводе символа в текстовое поле запускать процедуру фильтрации списка. Кроме того, данная библиотека позволяет раскрашивать найденные строки или выделять жирным шрифтом те части текста, которые совпали с запросом.
Рассмотрим преимущества использования FormEx совместно с 1С++:
ТабличноеПоле можно отображать данные SQL-запроса мгновенно. Система подгружает только те строки, которые видны пользователю на экране.Часто пользователь вводит не одно слово, а несколько, например: «Витамин Комплекс». Хороший алгоритм поиска должен найти все товары, где присутствуют оба этих слова в любом порядке. Для этого поисковую строку необходимо предварительно обработать.
Выясним причину, почему простой Найти() здесь не сработает: он ищет точное совпадение всей фразы. Для решения задачи разберем следующий алгоритм:
// Разбиваем строку поиска на массив слов
СписокСлов = СоздатьОбъект("СписокЗначений");
Стр = СтрЗаменить(СокрЛП(ПоисковаяСтрока), " ", РазделительСтрок);
Для н = 1 По СтрКоличествоСтрок(Стр) Цикл
СписокСлов.ДобавитьЗначение(Врег(СтрПолучитьСтроку(Стр, н)));
КонецЦикла;
// При проверке элемента справочника проверяем вхождение КАЖДОГО слова
Подходит = 1;
Для н = 1 По СписокСлов.РазмерСписка() Цикл
Если Найти(Врег(Спр.Наименование), СписокСлов.ПолучитьЗначение(н)) = 0 Тогда
Подходит = 0; Прервать;
КонецЕсли;
КонецЦикла;
Этот подход значительно повышает релевантность поиска и делает подбор товаров в 7.7 более современным и удобным.
Если ваша база 1С 7.7 работает в формате DBF, прямые SQL-запросы будут недоступны. В этом случае программисты часто прибегают к использованию библиотеки svcsvc.dll или созданию вспомогательных индексированных файлов.
Проанализируем ситуацию с производительностью в DBF:
Подводя итог, можно сказать, что реализация качественного поиска в форме подбора 1С 7.7 требует выхода за рамки стандартных возможностей платформы. Оптимальным «джентльменским набором» для решения этой задачи сегодня является связка библиотек 1С++ и FormEx, которая позволяет превратить старый интерфейс в быстрый и отзывчивый инструмент.