Как реализовать автоматическое обновление фильтра в табличной части 1С при изменении данных?

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

В процессе разработки на платформе 1С:Предприятие 8.3 (управляемые формы) программисты часто сталкиваются с особенностью работы стандартного поиска. Когда пользователь применяет команду «Найти» в контекстном меню табличной части (ТЧ), платформа фильтрует строки по выбранному значению. Однако, если пользователь изменяет данные в отфильтрованной строке так, что они больше не соответствуют условию поиска, строка не исчезает мгновенно. Это происходит из-за того, что стандартный механизм поиска фиксирует визуальное состояние в момент вызова команды и не следит за динамическим изменением каждой ячейки ради экономии ресурсов производительности.

В данной статье мы разберем, почему методы Обновить() или ОбновитьОтображениеДанных() не всегда помогают в этой ситуации, и проанализируем альтернативные способы реализации «живого» фильтра, который будет мгновенно реагировать на правки пользователя.

Выясняем причину: Поиск против Отбора

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

  1. Стандартный поиск (команда «Найти»): Это чисто визуальный механизм. Платформа создает временный индекс и отображает только подходящие строки. При изменении значения в текущей строке платформа намеренно не «выбрасывает» пользователя из этой строки, чтобы не нарушать процесс ввода данных. Представьте, если бы вы начали вводить число, ошиблись в одном знаке, и строка тут же исчезла — это создало бы крайне негативный пользовательский опыт (UX).
  2. Программный отбор (свойство ОтборСтрок): Этот механизм работает на уровне связи данных и элемента управления. Когда вы устанавливаете ОтборСтрок, таблица начинает жестко следовать заданным правилам.

Именно поэтому стандартный поиск невозможно заставить «пересчитаться» простыми командами обновления — он не предназначен для динамического отслеживания правок в реальном времени.

Способ 1: Подмена поиска через свойство ОтборСтрок

Наиболее надежный вариант решения задачи — это программная установка отбора. Если мы хотим, чтобы строки исчезали сразу после изменения значения, нам нужно использовать свойство элемента формы ОтборСтрок. Рассмотрим подробнее, как это реализовать.

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


// Пример установки фиксированного отбора для табличной части
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("Цена", 1000);

// Применяем отбор к элементу формы
Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура(СтруктураОтбора);

Важно помнить, что свойство ОтборСтрок принимает только объект типа ФиксированнаяСтруктура. Если вы попытаетесь передать обычную структуру, платформа выдаст ошибку. Преимущество этого метода в том, что как только значение в колонке «Цена» изменится (и фокус покинет ячейку), строка автоматически скроется, так как она перестанет соответствовать условиям ФиксированнойСтруктуры.

Способ 2: Создание пользовательского поля фильтрации

Поскольку стандартный поиск «Найти» трудно контролировать программно (мы не можем легко считать, какое именно значение пользователь ввел в окно поиска), рекомендуется заменить его на пользовательское поле ввода над таблицей. Рассмотрим, как это сделать:

  1. Добавим на форму реквизит с именем ФильтрПоЦене (тип: Число или Строка).
  2. Вынесем этот реквизит на форму в виде поля ввода.
  3. В событии ПриИзменении этого поля пропишем логику обновления таблицы.

Проанализируем пример кода для обработки ввода пользователя:


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

Теперь, чтобы строка исчезала при редактировании самой ТЧ, нам нужно вызвать этот же механизм в событии ПриИзменении ячейки таблицы. Это заставит таблицу «пересчитать» свою видимость.

Способ 3: Принудительное обновление через «встряску» формы

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

Иногда помогает программное переключение фокуса. Посмотрим на пример хака:


&НаКлиенте
Процедура ТоварыЦенаПриИзменении(Элемент)
    
    // Сохраняем текущий элемент
    ТекущийКонтрол = ЭтаФорма.ТекущийЭлемент;
    
    // На мгновение переключаем фокус на другой элемент формы
    ЭтаФорма.ТекущийЭлемент = Элементы.ГруппаКоманднаяПанель;
    
    // Возвращаем фокус обратно
    ЭтаФорма.ТекущийЭлемент = ТекущийКонтрол;
    
КонецПроцедуры

Важное замечание: Этот метод является «костылем» и не гарантирует 100% срабатывания во всех версиях платформы (например, в 8.3.25 поведение может отличаться). Платформа старается оптимизировать отрисовку и может проигнорировать быструю смену фокуса.

Почему ОбновитьОтображениеДанных() не работает?

Разберем этот вопрос подробнее. Метод ОбновитьОтображениеДанных() предназначен для того, чтобы форма пересчитала видимость и доступность элементов, зависящих от параметров, или обновила условное оформление. Однако стандартный поиск по правому клику мыши («Найти: [Значение]») — это внутренняя процедура клиентского приложения, которая работает «поверх» данных таблицы. Она не меняет коллекцию ОтборСтрок. Следовательно, с точки зрения системы отображения данных, фильтр поиска не является «изменением данных», требующим обновления.

Рекомендации по реализации в современных конфигурациях

Если вы работаете в 1С:УНФ или любой другой современной конфигурации на базе БСП, лучшим решением будет использование встроенных механизмов поиска (динамических списков или специализированных функций БСП). Однако для табличных частей документов (которые не являются динамическими списками) лучшим алгоритмом будет следующий:

Подводя итог, можно сказать, что прямого способа «обновить» стандартный поиск после изменения ячейки без сброса самого поиска в платформе не предусмотрено. Наиболее профессиональным решением будет внедрение собственного интерфейса фильтрации, который дает разработчику полный контроль над поведением строк в табличной части.

← На главную