Как реализовать живой поиск по таблице значений в мобильном приложении 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке мобильных и настольных приложений на платформе 1С часто возникает задача: сформировать сложную выборку данных с помощью тяжелого запроса (объединения нескольких регистров, временные таблицы, сложные группировки), вывести результат в таблицу на форме и предоставить пользователю возможность удобного «живого» поиска по мере ввода текста.

Штатный механизм полнотекстового живого поиска встроен в элемент ДинамическийСписок, однако динамический список накладывает жесткие ограничения на текст запроса и не поддерживает произвольные таблицы значений в качестве прямого источника данных. Разберем основные архитектурные подходы к реализации живого поиска по сложным наборам данных на мобильной платформе.

Почему условное оформление не решает задачу скрытия строк

Проанализируем популярное заблуждение: попытку скрыть неподходящие строки через свойство Видимость в условном оформлении формы. В управляемых формах и мобильной платформе условное оформление не умеет физически исключать строки из отображения. Свойство Видимость применяется к элементам формы в целом, а свойство Отображать управляет только флажками и переключателями. Попытка замаскировать несовпадающие строки через оформление оставляет пустые полосы в таблице, что делает интерфейс непригодным для работы на мобильном устройстве.

Способ 1. Буферизация через универсальный регистр сведений и динамический список

Рассмотрим подход, при котором результат сложного запроса временно записывается во вспомогательный регистр сведений, а на форме отображается ДинамическийСписок с источником данных из этого регистра. Это позволяет использовать стандартную строку поиска платформы 1С без написания собственного движка фильтрации.

Для реализации создадим универсальный регистр сведений ДанныеДляДинамическихСписков со следующей структурой:

  1. Измерения: ИмяДанных (Строка), Измерение1, Измерение2 (произвольный тип или ссылки).
  2. Ресурсы: Ресурс1, Ресурс2, Ресурс3, Ресурс4, Ресурс5.

Посмотрим на пример процедуры серверной записи данных из таблицы значений в служебный регистр:


&НаСервере
Процедура ЗаписатьДанныеДляДинамическогоСписка(ИмяДанных, Таб, Измерения, Ресурсы)
    
    Измерения = СтрЗаменить(Измерения, ",", Символы.ПС);
    Ресурсы = СтрЗаменить(Ресурсы, ",", Символы.ПС);
    
    Набор = РегистрыСведений.ДанныеДляДинамическихСписков.СоздатьНаборЗаписей();
    Набор.Отбор.ИмяДанных.Установить(ИмяДанных);
    
    Для Каждого Стр Из Таб Цикл
        НоваяЗапись = Набор.Добавить();
        НоваяЗапись.ИмяДанных = ИмяДанных;
        
        Для П = 1 По СтрЧислоСтрок(Измерения) Цикл
            ИмяКолонки = СтрПолучитьСтроку(Измерения, П);
            НоваяЗапись["Измерение" + П] = Стр[ИмяКолонки];
        КонецЦикла;
        
        Для П = 1 По СтрЧислоСтрок(Ресурсы) Цикл
            ИмяКолонки = СтрПолучитьСтроку(Ресурсы, П);
            НоваяЗапись["Ресурс" + П] = Стр[ИмяКолонки];
        КонецЦикла;
    КонецЦикла;
    
    Набор.Записать();
    
КонецПроцедуры

Разберем вызов этой процедуры при подготовке данных формы:


ЗаписатьДанныеДляДинамическогоСписка("СписокЗаказов", ТабЗн, "Контрагент,ДоговорКонтрагента", "ТипЗаказа,Количество,Вес,Закрыт");

После записи на форме настраивается ДинамическийСписок с произвольным запросом к регистру сведений с отбором по полю ИмяДанных = &ИмяДанных. Пользователь получает полноценное поле поиска с серверной фильтрацией и стандартным поведением динамического списка.

Способ 2. Фильтрация таблицы значений в оперативной памяти (без записи в базу)

Если создание промежуточных записей в базе данных нежелательно из-за объема или накладных расходов на мобильном накопителе, организуем поиск целиком в оперативной памяти формы.

Разберем архитектуру решения по шагам:

  1. В реквизитах формы создаем строковое поле СтрокаПоиска и привязываем его к элементу ввода на форме.
  2. Создаем две коллекции: скрытую полную таблицу (хранится во временном хранилище по адресу или в скрытом реквизите формы) и отображаемую таблицу ТаблицаОтображения типа ДанныеФормыКоллекция.
  3. Для перехвата каждого введенного символа используем событие поля ввода АвтоПодборТекста.
  4. Чтобы избежать зависания мобильного устройства при быстром наборе текста, фильтрацию запускаем через обработчик ожидания (паттерн Debounce с задержкой 0.3–0.5 секунды).

Посмотрим на пример клиентского кода обработки ввода текста:


&НаКлиенте
Процедура СтрокаПоискаАвтоПодборТекста(Элемент, Текст, ДанныеВыбора, ПараметрыИзвлечения, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ЭтаФорма.СтрокаПоиска = Текст;
    
    // Перезапускаем обработчик ожидания при каждом нажатии клавиши
    ОтключитьОбработчикОжидания("ВыполнитьЖивойПоиск");
    ПодключитьОбработчикОжидания("ВыполнитьЖивойПоиск", 0.4, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьЖивойПоиск()
    ОтфильтроватьТаблицуНаСервере(ЭтаФорма.СтрокаПоиска);
КонецПроцедуры

На сервере для быстрого отбора по подстроке воспользуемся объектом ПостроительЗапроса, который умеет выполнять фильтрацию прямо по объекту ТаблицаЗначений без обращений к таблицам базы данных:


&НаСервере
Процедура ОтфильтроватьТаблицуНаСервере(Знач ТекстПоиска)
    
    ПолнаяТаблица = ПолучитьИзВременногоХранилища(АдресПолнойТаблицы);
    
    Если ПустаяСтрока(ТекстПоиска) Тогда
        ЗначениеВРеквизитФормы(ПолнаяТаблица, "ТаблицаОтображения");
        Возврат;
    КонецЕсли;
    
    Построитель = Новый ПостроительЗапроса;
    Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ПолнаяТаблица);
    
    // Добавляем условие поиска по нужной колонке
    Отбор = Построитель.Отбор.Добавить("Наименование");
    Отбор.ВидСравнения = ВидСравнения.Содержит;
    Отбор.Значение = СокрЛП(ТекстПоиска);
    Отбор.Использование = Истина;
    
    Результат = Построитель.Выполнить().Выгрузить();
    ЗначениеВРеквизитФормы(Результат, "ТаблицаОтображения");
    
КонецПроцедуры

Способ 3. Отображение и мгновенный поиск через ПолеHTMLДокумента

Проанализируем еще один высокопроизводительный вариант для мобильной платформы — вывод сформированной таблицы в элемент ПолеHTMLДокумента. В этом сценарии таблица преобразуется в HTML-разметку или передается в виде массива JSON на клиентскую сторону. Фильтрация строк по вводу в строку поиска выполняется на чистом JavaScript внутри веб-компонента.

Главное преимущество этого способа — полное отсутствие вызовов сервера и контекстных трансформаций данных формы при вводе каждого символа, что дает максимальную плавность интерфейса даже на бюджетных мобильных устройствах.

← На главную