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