Не так давно, общаясь с пользователем, услышал жалобу на то, что новые сотрудники компании совершенно не ориентируются в номенклатуре предприятия (ТиС), что при работе с клиентами «в голос» и справочнике в 10 тыс. позиций – достаточно критично. Да и мне самому частенько приходилось «играть» с поисковой строкой, дабы обнаружить позицию, с которой «что-то не то».
Упоминание библиотеки нечеткого поиска было еще свежо в памяти (strmatch.dll от Александра Ракунова (skorp)) – потому и решил ее опробовать.
Хотелось, чтобы наиболее похожие позиции отображались во время набора (здесь, вероятно, виноват openconf+телепат+intellisence).
Для быстроты заполнения КЭШа strmatch (внутренне хранилище строк с быстрым последовательным доступом) было решено использовать 1sqlite (Александр Орефков), т.к. он уже использовался в системе, а для отслеживания начала/окончания изменения поисковой строки – Formex (Алексей Фёдоров aka АЛьФ), по той же причине.
Нужно сказать, что организовать подобный поиск можно и иными средствами, например: можно не использовать прямые запросы и обойтись strmatch + Formex (либо 1cpp) / не использовать strmatch, а просто искать по вхождениям, используя 1cpp + sqlite/vfpoledb/MSSQL и т.д.
Что делает обработка: при открытии обработки и изменении флага учета неактуальных позиций происходит заполнение/перезаполнение КЭШа strmatch. В качестве хэшей используются id справочника. При начале/продолжении ввода печатных символов с клавиатуры, либо удалении обработка начинает считать паузы между нажатиями на клавиши. При длительности паузы более определенного лимита (н-р 500 мс) запускается консольная утилитка (GetTextFrom1cedit 0.0.1 (Jill)), перехватывающая, через win api содержимое указанного окна и возвращающая текст в текстовый файл. Далее происходит сравнение строк и заполнение/перезаполнение списка похожих строк. Фокус со строки ввода, при этом, не уходит. Для навигации по списку и выбора значения используется перехват нажатий на клавиши (U93;/U95;/enter), при помощи FormEx.
Описание параметров GetTextFrom1cedit:
1 – дескриптор окна (handle) в десятиричном виде (либо «0» - если не известен)
2 – заголовок искомого окна (игнорируется, при наличии хэндла)
3 – номер 1cedit’а
4 – полный путь к текстовому файлу (файл будет создан/перезаписан)
Что делает утилита: при наличии хэндла окна находит дочернее окно класса 1cedit тем, или иным способом, в зависимости от способа вызова обработки (в модальном и не модальном режимах структура дерева дочерних окон 1с различна) и получает текст поля. При отсутствии хэндла (указан 0) ищет окно по наименованию, далее действует аналогичным образом.
Внимание: при поиске по наименованию и множестве одновременно открытых обработок (в т.ч. в нескольких 1с) с одинаковым заголовком возможны ошибки.
Зачем нужно было сочинять какие-то утилитки, если можно просто обойтись активацией поля при ложном закрытии и использовании WScript.Shell + sendkey, или просто, тем же Formex, перехватывать символы: как уже было сказано поведение поля ввода поисковой строки кажется более адекватным. Например: в модальном режиме конструкция с ложным закрытием работать откажется, а при перехвате символов довольно проблемно реализовать незамудренный (если хорошенько постараться, конечно, можно разродиться каким-нибудь монстриком, но решение с win api показалось мне более простым и менее времязатратным) алгоритм, обрабатывающий выделение части строки и ввод поверх и т.п. ситуации.
Подключение:
В «ПриНачалеРаботыСистемы»:
Попытка
ЗагрузитьВнешнююКомпоненту("1sqlite.dll");
Исключение
Предупреждение("Ошибка! Загрузить внешнюю компоненту ""1sqlite.dll"" не удалось! Обратитесь к специалисту.");
КонецПопытки;
Попытка
ЗагрузитьВнешнююКомпоненту("FormEx.dll");
Исключение
Предупреждение("Ошибка! Загрузить внешнюю компоненту ""FormEx.dll"" не удалось! Обратитесь к специалисту.");
КонецПопытки;
Попытка
ЗагрузитьВнешнююКомпоненту("StrMatch.dll");
Исключение
Предупреждение("Ошибка! Загрузить внешнюю компоненту ""StrMatch.dll"" не удалось! Обратитесь к специалисту.");
КонецПопытки;
Кнопка вызова:
ОткрытьФормуМодально("Отчет", Контекст, КаталогИБ()+"\EXTFORMS\QuicktFuzzySearch\FastSearch.ert").
P.S. не рекомендуется использовать базу, в строке пути к которой, имеются кириллические символы и пробелы.