При работе с управляемыми формами программисты часто сталкиваются с ситуацией, когда стандартная строка поиска над таблицей ведет себя непредсказуемо. В одном случае она мгновенно находит данные по любой части слова, а в другом — упорно игнорирует вхождения, срабатывая только при вводе текста с начала строки. Особенно остро эта проблема проявляется, когда таблица связана не с динамическим списком, а с реквизитом формы типа ТаблицаЗначений, где данные хранятся в оперативной памяти.
В этой статье мы подробно разберем, почему штатный механизм поиска может ограничивать свои возможности, как правильно настроить свойства таблицы для активации полнотекстового поиска и какие скрытые механизмы платформы 1С влияют на этот процесс. Мы пройдем путь от простой настройки командной панели до глубокого понимания алгоритмов индексации данных.
Рассмотрим ситуацию: на управляемой форме расположена таблица, данные которой загружены в реквизит с типом ТаблицаЗначений. Колонки имеют тип Строка (неограниченной длины). Пользователь вводит текст в поисковое поле, но платформа фильтрует строки только в том случае, если значение начинается с введенных символов. При этом на другой форме та же самая логика работает «как надо» — поиск находит подстроку в середине предложения.
Проанализируем ситуацию. Первое, на что стоит обратить внимание — это доступные команды в контекстном меню и командной панели таблицы. Платформа 1С разделяет «простой поиск» и «расширенный поиск». Если в свойствах таблицы отключен функционал расширенного поиска, стандартное поле ввода над таблицей может переходить в упрощенный режим работы.
Для того чтобы штатный поиск по Alt+F (или через интерфейс) позволял искать по части строки, необходимо проверить настройки состава команд элемента формы. Выполним следующие действия:
Как только мы включаем Расширенный поиск, пользователю становится доступен диалог, в котором можно явно указать способ сопоставления: «Часть строки», «По началу строки» или «Вся строка». Если же этот пункт выключен, платформа часто ограничивает и возможности «быстрого» поиска в строке над таблицей, переводя его в режим «По началу» для экономии ресурсов.
Почему на одной форме ищет по части строки, а на другой — нет, если настройки кажутся одинаковыми? Разберем по шагам логику работы платформы 8.3. Система 1С применяет адаптивные стратегии поиска в зависимости от количества строк в ТаблицаЗначений:
Проанализируем тип данных. Хотя на первый взгляд Строка неограниченной длины кажется универсальной, для целей поиска она менее эффективна. Если бизнес-логика позволяет, ограничьте длину строки (например, до 250 или 1000 символов). Это позволит платформе более эффективно строить внутренние индексы в памяти.
Иногда требуется принудительно заставить поиск работать определенным образом. Мы можем управлять поведением строки поиска через свойства элемента формы. Рассмотрим свойство ПоложениеСтрокиПоиска. Посмотрим на программный пример настройки таблицы при создании формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Устанавливаем отображение строки поиска всегда сверху таблицы
Элементы.ТаблицаДанных.ПоложениеСтрокиПоиска = ПоложениеСтрокиПоискаЭлементаФормы.Верх;
// Включаем отображение состояния поиска (сколько найдено)
Элементы.ТаблицаДанных.ПоложениеСостоянияПросмотра = ПоложениеСостоянияПросмотраЭлементаФормы.Верх;
КонецПроцедуры
Важно помнить, что если стандартный поиск все же не удовлетворяет вашим требованиям (например, нужна сложная логика поиска по нескольким условиям «ИЛИ» в разных колонках), придется реализовать собственный механизм фильтрации.
Если штатный поиск работает нестабильно из-за ограничений платформы, мы можем реализовать свой поиск с использованием отбора. Рассмотрим, как это сделать для реквизита формы ТаблицаЗначений. Создадим на форме поле ввода СтрокаПоиска и при его изменении будем фильтровать данные.
Разберем пример кода для ручной фильтрации:
&НаКлиенте
Процедура СтрокаПоискаПриИзменении(Элемент)
ВыполнитьПоискНаСервере(СтрокаПоиска);
КонецПроцедуры
&НаСервере
Процедура ВыполнитьПоискНаСервере(ТекстПоиска)
// Предположим, у нас есть основной массив данных в объекте или другом реквизите
// Так как штатный отбор ТаблицыЗначений на форме не поддерживает "Содержит",
// мы можем перезаполнить таблицу из "эталонного" источника.
ТЗДанные = РеквизитФормыВЗначение("ТаблицаНаФорме");
Если Не ПустаяСтрока(ТекстПоиска) Тогда
ПараметрыОтбора = Новый Структура;
// Стандартный НайтиСтроки не умеет в "По вхождению",
// поэтому используем ручной перебор или построитель
Индекс = ТЗДанные.Количество() - 1;
Пока Индекс >= 0 Цикл
СтрокаТЗ = ТЗДанные[Индекс];
// Ищем вхождение в нужных колонках
Если Найти(ВРег(СтрокаТЗ.Наименование), ВРег(ТекстПоиска)) = 0
И Найти(ВРег(СтрокаТЗ.Комментарий), ВРег(ТекстПоиска)) = 0 Тогда
ТЗДанные.Удалить(СтрокаТЗ);
КонецЕсли;
Индекс = Индекс - 1;
КонецЦикла;
КонецЕсли;
ЗначениеВРеквизитФормы(ТЗДанные, "ТаблицаНаФорме");
КонецПроцедуры
Обратите внимание: При таком подходе крайне важно иметь копию исходных данных, чтобы при очистке строки поиска можно было восстановить таблицу целиком. Использование Найти() в сочетании с ВРег() (перевод в верхний регистр) гарантирует нам поиск по вхождению без учета регистра символов.
Чтобы штатный поиск в 1С по ТаблицаЗначений работал по части строки, необходимо:
Таким образом, чаще всего проблема решается простой установкой «галочки» в конфигураторе, но понимание внутренней логики оптимизации 1С позволяет избежать трудноуловимых ошибок на больших объемах данных.