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