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

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

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

Если перед нами стоит задача отобрать строки, входящие в определенный список значений, или соответствующие условиям «Больше», «Меньше», «Содержит», нам придется использовать обходные пути. В этой статье мы подробно разберем, как реализовать такой функционал, сохранив при этом производительность и чистоту кода.

Проблема: Почему стандартный ОтборСтрок не работает со списками?

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

Решение №1: Использование вспомогательного реквизита «Флаг видимости»

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

Шаг 1. Добавление реквизита.

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

Шаг 2. Программная разметка строк.

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


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

Шаг 3. Установка отбора.

Теперь, когда строки размечены, мы можем использовать стандартный механизм платформы, который работает мгновенно:


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

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

Решение №2: Использование расширений для минимизации изменений

Выясним, как сделать решение максимально «чистым» для типовых конфигураций. Если бухгалтер просит добавить поиск по полям, которых нет в ТЧ (как в нашем примере с Направлением деятельности), лучше всего использовать Расширение конфигурации.

  1. Добавляем форму документа в расширение.
  2. В расширении добавляем в ТЧ реквизит ВидимВФильтре.
  3. В модуле формы перехватываем события ПриЧтенииНаСервере и ПослеЗаписиНаСервере, чтобы актуализировать значения в этой колонке при загрузке данных.
  4. Добавляем на форму поле ввода для пользователя (например, Список значений или Поле выбора), при изменении которого будет запускаться цикл пересчета флагов.

Преимущество этого подхода: основная конфигурация остается на поддержке, а логика фильтрации полностью изолирована в расширении.

Решение №3: Динамический список как альтернатива (для сложных случаев)

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

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

Однако помните, что при таком подходе редактирование строк становится сложнее: вам придется синхронизировать изменения в динамическом списке с реальным объектом документа вручную.

Метод поиска через НайтиСтроки()

Выясним, помогает ли метод НайтиСтроки() решить задачу визуального отбора. Этот метод объекта ТабличнаяЧасть позволяет получить массив строк, подходящих под условия.


Параметры = Новый Структура("Склад", СкладОтбора);
НайденныеСтроки = Объект.Товары.НайтиСтроки(Параметры);

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

Резюме и рекомендации

Рассмотрев все варианты, мы приходим к выводу, что наиболее эффективным и «человечным» способом реализации отбора по списку значений в 1С 8.3 является комбинация нехранимого булевского реквизита и программного цикла.

Основные выводы:

  1. Стандартный ОтборСтрок не умеет работать со списками напрямую.
  2. Создавайте вспомогательную колонку ЭтоВидимаяСтрока (тип Булево).
  3. Пробегайте по ТЧ, проверяйте свои условия (вхождение в список, наличие подстроки и т.д.) и заполняйте эту колонку.
  4. Устанавливайте Элементы.ИмяТЧ.ОтборСтрок = Новый Структура("ЭтоВидимаяСтрока", Истина);.
  5. Для сброса фильтра просто установите ОтборСтрок = Неопределено;.

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

← На главную