В современных конфигурациях на платформе 1С 8.х пользователи давно привыкли к удобному механизму «ввода по строке» и автоподбора. Пользователь начинает вводить первые буквы наименования товара или контрагента, и система мгновенно раскрывает список подходящих вариантов прямо под полем ввода. В старой, но все еще широко используемой платформе 1С:Предприятие 7.7 стандартный функционал заставляет пользователя открывать форму списка или форму подбора, что существенно замедляет ежедневную рутинную работу операторов.
В рамках этой статьи мы подробно разберем, как преодолеть ограничения платформы 1С 7.7 и реализовать полноценный, быстрый полнотекстовый поиск по одному полю в реальном времени. Мы проанализируем технический стек необходимых библиотек, изучим архитектуру решения, детально разберем особенности работы алгоритма на DBF-базах и приведем практические примеры кода.
Поскольку штатные механизмы 1С 7.7 не позволяют перехватывать ввод каждого отдельного символа на лету и выполнять сверхбыструю фильтрацию, нам потребуется задействовать мощный арсенал внешних компонент, разработанных сообществом (в первую очередь разработчиками форума 1С++).
Для реализации полноценного автоподбора нам понадобятся три технологических компонента:
ПриНажатииКнопкиКлавиатуры или использовать механизм Перехватчик, чтобы реагировать на ввод каждого нового символа пользователем в режиме реального времени.svcsvc.dll (метод SvsSvc.FilterValue()) либо специализированные ActiveX-компоненты (например, списки из библиотеки MSComctlLib) или встроенный класс «Табличное поле» от 1С++.Давайте по шагам разберем, как функционирует этот механизм изнутри:
FormEx перехватывает нажатия клавиш. При изменении текста в поле ввода запускается процедура-обработчик.svcsvc.dll), которая генерирует под полем ввода выпадающее меню с перечнем найденных элементов.Рассмотрим подробнее, как именно связываются эти компоненты на программном уровне.
Если ваша конфигурация 1С 7.7 работает на SQL-версии базы данных, проблем с быстродействием прямых запросов обычно не возникает. Однако при работе с DBF-базой разработчики часто сталкиваются с тем, что стандартные классы автоподбора «из коробки» отказываются работать или выдают синтаксические ошибки SQL.
Выясним главные причины этой проблемы и пути их решения:
_1SJourn для журнала документов, _1SCARD для справочника). В файловых базах DBF этот символ отсутствует (таблицы именуются как 1SJourn, 1SCARD). Прямой запрос, написанный жестко под SQL, упадет на DBF-базе. Для универсальности в коде необходимо динамически определять тип базы и подставлять префиксы.UPPER) или поиск подстроки, могут незначительно отличаться в синтаксисе T-SQL и FoxPro. Это нужно учитывать при написании тела запроса внутри класса.Проанализируем пример кода, который демонстрирует перехват ввода символов и выполнение быстрого прямого запроса к базе данных через 1С++.
Для начала рассмотрим, как с помощью FormEx перехватить нажатие клавиш в модуле формы:
Процедура ПриНажатииКнопкиКлавиатуры(Контекст, Клавиша, Состояние, Флаги, СтандартнаяОбработка)
// Проверяем, что фокус находится на нужном реквизите автоподбора
Если НазваниеАктивногоРеквизита() = "ВыбНоменклатура" Тогда
// Получаем текущее текстовое значение поля ввода до окончания ввода
ТекущийТекст = СокрЛП(Контекст.ПолучитьАтрибут("ВыбНоменклатура").К TEXT);
// Игнорируем управляющие клавиши (Tab, Esc, Enter)
Если (Клавиша <> 9) И (Клавиша <> 27) И (Клавиша <> 13) Тогда
// Запускаем процедуру динамического поиска вариантов
ВыполнитьДинамическийПоиск(ТекущийТекст);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Теперь разберем по шагам создание универсального прямого запроса через объект ODBCRecordset компоненты 1С++, учитывающий разницу между SQL и DBF структурами:
Процедура ВыполнитьДинамическийПоиск(СтрокаПоиска)
Если ПустаяСтрока(СтрокаПоиска) = 1 Тогда
Возврат;
КонецЕсли;
// Инициализируем объект прямых запросов 1С++
Запрос = СоздатьОбъект("ODBCRecordset");
// Определяем префикс таблиц в зависимости от формата базы данных
// В реальном классе флаг БазаНаSQL определяется один раз при старте системы
Префикс = ?(Константа.БазаНаSQL.Получить() = 1, "_", "");
// Формируем безопасный текст запроса с использованием LIKE
// Для оптимизации поиска по началу строки лучше использовать "СтрокаПоиска%"
ТекстЗапроса = "
|SELECT
| Ref.ID as [Элемент $Справочник.Номенклатура],
| Ref.DESCR as Наименование
|FROM
| " + Префикс + "1SCARD Ref
|WHERE
| Ref.DESCR LIKE :ТекстПоиска
| AND Ref.ISFOLDER = 2 -- Исключаем группы, ищем только элементы
|";
Запрос.УстановитьТекстовыйПараметр("ТекстПоиска", "%" + СтрокаПоиска + "%");
// Выполняем запрос и выгружаем результаты в Таблицу Значений
ТЗРезультаты = СоздатьОбъект("ТаблицаЗначений");
Запрос.Открыть(ТекстЗапроса);
Запрос.Выгрузить(ТЗРезультаты);
Если ТЗРезультаты.КоличествоСтрок() > 0 Тогда
// Здесь вызывается метод svcsvc.dll или ActiveX-компонента
// для визуального отображения выпадающего списка вариантов под полем
ПоказатьВыпадающийСписок(ТЗРезультаты);
КонецЕсли;
КонецПроцедуры
Несмотря на то, что данное решение приближает интерфейс 1С 7.7 к современным стандартам эргономики, оно имеет ряд технологических ограничений, о которых необходимо знать заранее:
FormEx (например, для раскраски таблиц или работы со сканерами штрихкодов), внедрение тяжелых классов автоподбора может вызвать конфликты событий клавиатуры и потребовать глубокого рефакторинга общего кода конфигурации.Подведем итог: Реализация полнотекстового динамического поиска по одному полю в 1С 7.7 — это технически сложная, но вполне решаемая задача. Использование связки из компонент FormEx и 1С++ позволяет обойти ограничения старой платформы и подарить пользователям комфортную работу, аналогичную современным веб-интерфейсам и базам данных на платформе 1С 8.х.