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

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

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

Анализ проблемы: Почему не работает фильтрация через точку

Рассмотрим типичную ситуацию. Разработчик программно добавляет колонку в таблицу формы и связывает ее с данными через длинный путь, например: Объект.Состав.БанковскийСчет.СчетТретьегоЛица. Визуально в таблице данные отображаются корректно. Но при попытке применить фильтр кодом:

Элементы.Состав.ОтборСтрок = Новый ФиксированнаяСтруктура("ТретьеЛицо", Истина);

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

Решение 1: Добавление реквизита в расширении (Рекомендуемый способ)

Если нам необходимо фильтровать строки стандартной табличной части документа (например, в конфигурации ЗУП 3.1), самым надежным и производительным способом будет добавление физического реквизита в эту ТЧ через расширение. Разберем этот процесс по шагам:

  1. Создание реквизита: В расширении конфигурации найдите нужный документ и его табличную часть Состав. Добавьте новый реквизит с именем ТретьеЛицо и типом Булево.
  2. Заполнение данных: Поскольку это новый реквизит, его нужно заполнять. Лучше всего это сделать в обработчике события ПриИзменении банковского счета в строке таблицы. Таким образом, при выборе счета значение признака СчетТретьегоЛица будет копироваться непосредственно в строку ТЧ.
  3. Настройка формы: Теперь путь к данным для вашей колонки на форме будет выглядеть просто: Объект.Состав.ТретьеЛицо.

После этого программный отбор заработает мгновенно, так как условие будет проверяться по локальному значению строки. Рассмотрим пример кода для обработчика переключателя:


&НаКлиенте
Процедура Расш2_ТретьиЛицаПриИзмененииПосле(Элемент)
    
    // Предположим, переключатель имеет значения: 1 - Все, 2 - Только третьи лица, 3 - Без третьих лиц
    Если Объект.ТретьиЛица = 2 Тогда
        Элементы.Состав.ОтборСтрок = Новый ФиксированнаяСтруктура("ТретьеЛицо", Истина);
    ИначеЕсли Объект.ТретьиЛица = 3 Тогда
        Элементы.Состав.ОтборСтрок = Новый ФиксированнаяСтруктура("ТретьеЛицо", Ложь);
    Иначе  
        // Сброс отбора: передаем пустую структуру или Неопределено
        Элементы.Состав.ОтборСтрок = Новый ФиксированнаяСтруктура();
    КонецЕсли;
    
КонецПроцедуры

Решение 2: Использование вспомогательного реквизита формы (ТаблицаЗначений)

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

Мы создаем реквизит формы с типом ТаблицаЗначений, который полностью дублирует структуру ТЧ Состав, но с добавлением колонки ТретьеЛицо. При создании формы или при чтении данных на сервере мы выгружаем данные из объекта в эту таблицу, программно вычисляя значение для новой колонки.


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

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

Особенности работы с «ОтборСтрок»

Рассмотрим подробнее важные технические моменты, которые помогут избежать ошибок в будущем:

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

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


&НаСервере
Процедура Расш2_ПриСозданииНаСервереПеред(Отказ, СтандартнаяОбработка)
    
    // Добавляем элемент формы - поле
    ИмяКолонки = "ТретьеЛицо";
    НоваяКолонка = Элементы.Добавить(ИмяКолонки, Тип("ПолеФормы"), Элементы.Состав);
    НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
    
    // Путь должен быть к существующему реквизиту данных коллекции!
    НоваяКолонка.ПутьКДанным = "Объект.Состав.ТретьеЛицо"; 
    НоваяКолонка.Заголовок = "Счет 3-го лица";
    НоваяКолонка.Видимость = Истина;
    
КонецПроцедуры

Резюмируем: Для успешной фильтрации строк через переключатель необходимо обеспечить наличие реквизита непосредственно в источнике данных таблицы. Отбор по «пути через точку» не поддерживается стандартным свойством ОтборСтрок. Используйте расширение для добавления нужных полей в табличную часть — это наиболее «чистый» и эффективный метод с точки зрения архитектуры 1С:Предприятия 8.3.

← На главную