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

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой
← К списку

Мы столкнулись с распространенной ситуацией в 1С:Предприятие, особенно в управляемых формах, когда стандартный механизм поиска в табличной части (ТЧ) документа не обеспечивает динамического обновления отображения строк после изменения данных. Представьте: пользователь применяет отбор по определенному значению (например, "Цена = 1000 руб."), изменяет эту цену в одной из отфильтрованных строк на "700 руб.", но строка при этом не исчезает из списка, хотя уже не соответствует условиям отбора. Давайте разберем, почему это происходит и как решить эту проблему.

Почему стандартный "Найти" не работает так, как мы ожидаем?

Прежде чем перейти к решению, выясним причину такого поведения. Стандартный механизм "Найти", который вызывается щелчком правой кнопкой мыши по полю табличной части и выбором соответствующей команды, по своей сути является поиском, а не динамическим отбором. Это ключевое различие:

  1. Поиск (стандартный "Найти"): Когда мы используем "Найти", система однократно просматривает данные табличной части и отображает те строки, которые соответствуют заданному критерию. Это своего рода "снимок" данных на момент поиска. После того как строки отображены, их связь с условием поиска прерывается. Если мы изменим данные в одной из этих строк, система не перепроверит условие поиска для всех строк, и, следовательно, строка не исчезнет, даже если она перестала соответствовать критерию. Методы Обновить(), ОбновитьФорму() или ОбновитьОтображениеДанных() в данном случае не помогут, поскольку они обновляют данные или элементы формы, но не переприменяют условия ранее выполненного поиска.
  2. Отбор (программный): В отличие от поиска, программный отбор, реализованный через свойство ОтборСтрок табличного поля, устанавливает постоянное условие для отображения данных. Это условие активно до тех пор, пока оно не будет сброшено или изменено. При изменении данных в табличной части, система автоматически перепроверяет строки на соответствие условиям отбора и динамически скрывает или показывает их.

Таким образом, наша задача заключается в том, чтобы заменить или дополнить стандартный механизм поиска на полноценный программный отбор, который будет реагировать на изменения данных.

Решение 1: Реализация собственного динамического отбора строк с помощью свойства "ОтборСтрок"

Наиболее эффективным и правильным способом решения данной проблемы является программное управление отбором строк табличного поля. Для этого мы будем использовать свойство ОтборСтрок элемента формы типа "ТабличноеПоле", связанного с нашей табличной частью.

Рассмотрим подробнее шаги по реализации такого отбора:

  1. Определение момента для установки отбора: Нам необходимо решить, в какой момент пользователь будет задавать условия отбора. Это может быть отдельная кнопка "Применить отбор", поле ввода для значения отбора или даже перехват события, имитирующего стандартный "Найти". Для простоты, давайте представим, что у нас есть кнопка или другое управляющее действие, которое инициирует процесс отбора.

  2. Формирование структуры отбора: Для установки отбора программно в управляемых формах мы используем объект ФиксированнаяСтруктура. Этот объект позволяет нам указать имя поля табличной части и значение, по которому будет производиться отбор.

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

    
    // Допустим, мы хотим отбирать строки по полю "Номенклатура"
    // и у нас есть переменная "ВыбраннаяНоменклатура" с нужным значением
            
    // Создаем структуру отбора
    СтруктураОтбора = Новый Структура;
    СтруктураОтбора.Вставить("Номенклатура", ВыбраннаяНоменклатура);
            
    // Преобразуем ее в ФиксированнуюСтруктуру для свойства ОтборСтрок
    ОтборДляТЧ = Новый ФиксированнаяСтруктура(СтруктураОтбора);
            
    // Применяем отбор к табличному полю
    // Замените "Элементы.НашаТабличнаяЧасть" на имя вашего табличного поля на форме
    Элементы.НашаТабличнаяЧасть.ОтборСтрок = ОтборДляТЧ;
    

    Если нам нужно отбирать строки по нескольким полям, мы просто добавляем их в структуру:

    
    // Отбор по "Номенклатура" и "Цена"
    СтруктураОтбора = Новый Структура;
    СтруктураОтбора.Вставить("Номенклатура", ВыбраннаяНоменклатура);
    СтруктураОтбора.Вставить("Цена", 1000); // Например, числовое значение
            
    ОтборДляТЧ = Новый ФиксированнаяСтруктура(СтруктураОтбора);
    Элементы.НашаТабличнаяЧасть.ОтборСтрок = ОтборДляТЧ;
    

    Важный момент: Имена полей в структуре должны точно соответствовать именам реквизитов табличной части, по которым мы хотим производить отбор.

  3. Размещение кода для установки отбора: Этот код следует размещать в обработчиках событий, которые должны инициировать отбор. Например:

    • В обработчике команды на форме (например, кнопка "Применить отбор").
    • В обработчике события ПриИзменении для поля, которое используется для задания условий отбора.
    • В обработчике события ПослеЗаписи или ПриЗаписиНаСервере документа, если отбор должен быть применен после сохранения изменений.

    Если мы хотим, чтобы отбор применялся сразу после изменения данных в строке, то код установки отбора (или его части) можно разместить в обработчике события ПриИзменении для колонки табличной части, по которой производится отбор. Однако, это может быть не всегда оптимально с точки зрения производительности, если табличная часть очень большая.

  4. Сброс отбора: Пользователю может понадобиться сбросить отбор и снова увидеть все строки табличной части. Для этого мы просто присваиваем свойству ОтборСтрок значение Неопределено или пустую ФиксированнаяСтруктура:

    
    Элементы.НашаТабличнаяЧасть.ОтборСтрок = Неопределено;
    // или
    // Элементы.НашаТабличнаяЧасть.ОтборСтрок = Новый ФиксированнаяСтруктура; 
    

    Это действие также можно привязать к отдельной кнопке "Сбросить отбор".

Дополнительные соображения и подводные камни

Таким образом, для достижения желаемого поведения – динамического обновления отображения строк табличной части после изменения данных – мы настоятельно рекомендуем использовать программное управление свойством Элементы.ТабличноеПоле.ОтборСтрок. Этот подход обеспечивает гибкость, надежность и предсказуемость в работе с данными на управляемых формах.

← К списку