Как отфильтровать строки табличной части в управляемой форме 1С 8.3
Содержание
Чтобы установить отбор в табличной части 1С 8.3, присвойте свойству ОтборСтрок элемента формы фиксированную структуру: Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", Значение). Снять отбор — присвоить Неопределено. Данные при этом не меняются: строки только скрываются из вида.
Типичная ситуация: в накладной 300 строк, кладовщик ищет все позиции одного поставщика или строки без цены. Листать долго, поиск по Ctrl+F прыгает по одной строке. Нужен фильтр прямо в форме документа. Отбор решает это за секунду, и его можно повесить на поле в шапке или на кнопку. Речь об управляемых формах (интерфейс «Такси»), в обычных формах объектная модель другая.
Три разных механизма отбора в формах 1С
Под словом «отбор» в 1С скрываются три механизма. Их путают, поэтому код из одного примера не работает в другом.
| Что фильтруем | Чем | Какие условия | Где задать |
|---|---|---|---|
| Строки табличной части документа или справочника, таблицу значений на форме | Свойство ОтборСтрок у элемента «Таблица формы» | Только равенство, несколько полей через «И» | Кодом |
| Динамический список (журнал, список справочника, подбор) | Отбор компоновки данных: Список.Отбор | Равно, не равно, больше, в списке, в иерархии, содержит, заполнено и др. | Конструктор и код |
| Значения, которые можно выбрать в колонку табличной части | Параметры выбора и связи параметров выбора | Отбор по реквизитам выбираемого объекта | Конфигуратор и код |
📌 Главное различие:
- 🔹
ОтборСтрокработает с данными, которые уже лежат в форме. Сервер не участвует, отбор применяется мгновенно. - 🔹 Отбор динамического списка превращается в условие запроса к базе. Список читает с сервера только подходящие записи.
- 🔹 Параметры выбора ничего не скрывают в самой таблице. Они ограничивают форму выбора, которая открывается из ячейки.
Табличная часть документа на форме — это коллекция данных формы (Объект.Товары). У неё нет отбора компоновки, поэтому конструкция Объект.Товары.Отбор не существует, а Элементы.Товары.ОтборСтрок — существует.
Что настраивается в конструкторе формы без кода
Без программирования в конструкторе форм можно задать отбор для двух случаев из трёх.
Отбор динамического списка
- Откройте форму в Конфигураторе, вкладка «Реквизиты».
- Дважды щёлкните реквизит типа «Динамический список» (обычно он называется
Список). - В окне свойств найдите пункт «Настройки списка» и откройте его.
- На закладке «Отбор» добавьте поле, выберите вид сравнения и значение.
- Сохраните форму и обновите конфигурацию.
Такой отбор работает всегда, пользователь его не снимает. Подходит для «вечных» условий: например, показывать только непомеченные на удаление элементы.
Отбор значений при выборе в колонку
Здесь фильтруется не таблица, а то, что пользователь выбирает в ячейку. Пример: в колонке «Номенклатура» должны выбираться только услуги, а в колонке «Характеристика» — только характеристики выбранной в строке номенклатуры.
- В дереве элементов формы раскройте таблицу и выделите поле-колонку, например
ТоварыНоменклатура. - В палитре свойств найдите «Параметры выбора». Добавьте строку: имя
Отбор.ПометкаУдаления, значениеЛожь. - Для зависимой колонки откройте «Связи параметров выбора». Имя —
Отбор.Владелец, реквизит-источник — поле текущей строки:Элементы.Товары.ТекущиеДанные.Номенклатура.
💡 Те же свойства есть у реквизита табличной части в дереве метаданных. Настройка там действует во всех формах объекта. Настройка у элемента формы — только в этой форме.
Отбор строк коллекции (ОтборСтрок) в конструкторе статически не задают. Его ставят кодом: при открытии формы или по действию пользователя.
Программная установка отбора строк табличной части
Базовый сценарий: в шапку формы выводим поле «Отбор по номенклатуре», при его изменении фильтруем табличную часть.
Шаг 1. На вкладке «Реквизиты» создайте реквизит формы ОтборНоменклатура с типом СправочникСсылка.Номенклатура. Перетащите его в дерево элементов над таблицей.
Шаг 2. В свойствах поля создайте обработчик события ПриИзменении.
Шаг 3. Вставьте код в модуль формы:
&НаКлиенте
Процедура ОтборНоменклатураПриИзменении(Элемент)
ПрименитьОтборТоваров();
КонецПроцедуры
&НаКлиенте
Процедура ПрименитьОтборТоваров()
Если ЗначениеЗаполнено(ОтборНоменклатура) Тогда
Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", ОтборНоменклатура);
Иначе
Элементы.Товары.ОтборСтрок = Неопределено;
КонецЕсли;
КонецПроцедуры
Очистил поле — отбор снят, видны все строки.
Отбор по нескольким полям
Ключи структуры объединяются условием «И». Строка видна, только если совпали все поля:
&НаКлиенте
Процедура ОтобратьПоСкладуИСтавке(Склад, СтавкаНДС)
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("Склад", Склад);
СтруктураОтбора.Вставить("СтавкаНДС", СтавкаНДС);
Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура(СтруктураОтбора);
КонецПроцедуры
Свойство ожидает именно ФиксированнаяСтруктура. Обычную структуру передавайте в конструктор фиксированной, как в примере.
Условия «больше», «не равно», «в списке»
ОтборСтрок умеет только равенство. Для остальных условий нужна служебная колонка-флаг: заполняете её по своему правилу, а отбираете по ней.
Сделать это можно в таблице значений, которая является реквизитом формы, — туда колонку добавить просто. Пример: в реквизите ТаблицаРасчета есть колонки Сумма (число) и Видим (булево).
&НаКлиенте
Процедура ПоказатьСтрокиБольше(Порог)
Для Каждого Строка Из ТаблицаРасчета Цикл
Строка.Видим = (Строка.Сумма > Порог);
КонецЦикла;
Элементы.ТаблицаРасчета.ОтборСтрок = Новый ФиксированнаяСтруктура("Видим", Истина);
КонецПроцедуры
В табличную часть документа колонку так не добавить: её состав задан в метаданных. Варианты — добавить реквизит в конфигурацию (это доработка типовой) или вывести строки в таблицу значений на форме и работать с ней.
Отбор сразу при открытии формы
Бывает, что форму открывают из другого места уже с нужным фильтром: например, из отчёта по одной номенклатуре. Передайте значение параметром и поставьте отбор в ПриСозданииНаСервере. Свойство ОтборСтрок доступно и на сервере, поэтому отбор будет виден сразу, без мигания полной таблицы.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("ОтборНоменклатура") Тогда
ОтборНоменклатура = Параметры.ОтборНоменклатура;
Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", ОтборНоменклатура);
КонецЕсли;
КонецПроцедуры
Чтобы параметр дошёл до формы, добавьте его на вкладке «Параметры» редактора формы с тем же именем и типом. Иначе платформа его не примет.
Найти строки кодом, не трогая вид
Если отбор нужен для обработки, а не для показа, используйте НайтиСтроки. Метод вернёт массив строк, таблица на экране не изменится:
&НаКлиенте
Процедура ОбнулитьСкидкуПоНоменклатуре(Номенклатура)
Отбор = Новый Структура("Номенклатура", Номенклатура);
НайденныеСтроки = Объект.Товары.НайтиСтроки(Отбор);
Для Каждого Строка Из НайденныеСтроки Цикл
Строка.ПроцентСкидки = 0;
КонецЦикла;
КонецПроцедуры
Отбор в динамическом списке и виды сравнения
Часто «табличной частью» называют таблицу на форме списка или на форме подбора. Там данные — динамический список, и отбор ставится через компоновку данных.
Код без библиотеки стандартных подсистем
&НаСервере
Процедура УстановитьОтборПоКонтрагенту(Контрагент)
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Контрагент;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
Если вызывать процедуру повторно, каждый раз добавится новый элемент. Перед добавлением ищите существующий элемент с тем же полем и меняйте его значение, а не плодите дубли.
Код в типовых конфигурациях на БСП
В БП 3.0, ЗУП 3.1, УТ 11 и других конфигурациях на библиотеке стандартных подсистем есть готовая процедура. Она сама находит и обновляет элемент отбора:
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
Список, "Контрагент", Контрагент, ВидСравненияКомпоновкиДанных.Равно, , ЗначениеЗаполнено(Контрагент));
Последний параметр — «Использование». Передали Ложь — отбор отключён, но элемент остаётся. Удобно для поля-фильтра, которое пользователь может очистить.
Открыть список уже с отбором
Для форм списка у платформы есть стандартный параметр Отбор. Структура из него становится отбором динамического списка, и модуль формы трогать не нужно:
&НаКлиенте
Процедура ОткрытьДокументыКонтрагента(Команда)
ПараметрыФормы = Новый Структура("Отбор", Новый Структура("Контрагент", Объект.Контрагент));
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаСписка", ПараметрыФормы, ЭтотОбъект);
КонецПроцедуры
Имя документа в примере — из БП 3.0, в своей конфигурации подставьте нужный объект. Поле Контрагент должно быть в списке, иначе отбор не сработает.
Виды сравнения, которые нужны чаще всего
| Вид сравнения | Когда применять | Значение справа |
|---|---|---|
Равно / НеРавно | Конкретный контрагент, склад, статус | Одно значение |
ВСписке / НеВСписке | Несколько складов или организаций | СписокЗначений |
ВИерархии | Группа номенклатуры со всеми подгруппами | Ссылка на группу |
Больше, МеньшеИлиРавно и др. | Суммы, даты, количества | Число или дата |
Содержит | Часть наименования или комментария | Строка |
Заполнено / НеЗаполнено | Документы без договора, товары без артикула | Не нужно |
💡 Пользователь в режиме «Предприятие» тоже может поставить такой отбор сам: Ещё → Настроить список → Отбор. Программный отбор из кода и пользовательский складываются.
Фильтр на командной панели табличной части
Пользователю удобнее одна кнопка, чем поле в шапке. Сделаем переключатель «Только без номенклатуры»: нажал — видны незаполненные строки, нажал снова — все.
- На вкладке «Команды» формы создайте команду
ТолькоНезаполненные, задайте ей обработчик. - Перетащите команду в командную панель таблицы
Товары(узел «Командная панель» внутри элемента таблицы). - Вставьте код:
&НаКлиенте
Процедура ТолькоНезаполненные(Команда)
Кнопка = Элементы.ТоварыТолькоНезаполненные;
Кнопка.Пометка = Не Кнопка.Пометка;
Если Кнопка.Пометка Тогда
ПустаяНоменклатура = ПредопределенноеЗначение("Справочник.Номенклатура.ПустаяСсылка");
Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", ПустаяНоменклатура);
Иначе
Элементы.Товары.ОтборСтрок = Неопределено;
КонецЕсли;
КонецПроцедуры
Имя кнопки (ТоварыТолькоНезаполненные) посмотрите в дереве элементов: платформа складывает его из имени таблицы и команды. Свойство Пометка делает кнопку «залипающей» — видно, что фильтр включён.
Подсказка, что отбор включён
Отфильтрованная таблица выглядит как обычная. Пользователь забывает про фильтр и думает, что строки пропали. Два простых решения:
- 🟡 меняйте заголовок таблицы:
Элементы.Товары.Заголовок = "Товары (отбор: " + ОтборНоменклатура + ")"; - 🟡 держите рядом кнопку «Показать все», которая сбрасывает
ОтборСтроки снимает пометку с переключателя.
Если в форме несколько кнопок-фильтров, сводите их в одну процедуру ПрименитьОтборТоваров(). Она собирает структуру из всех включённых условий. Иначе вторая кнопка затрёт отбор первой: ОтборСтрок хранит только одну структуру.
Особенности управляемых форм: где отбор ломается
Ещё несколько вещей, которые полезно знать заранее.
📌 Номера строк не перенумеровываются. После отбора видны строки 3, 17, 42 — это нормально. Колонка НомерСтроки показывает позицию в полной табличной части.
📌 Код обходит все строки. Цикл Для Каждого Строка Из Объект.Товары видит и скрытые строки. Если обработка должна касаться только видимых, используйте НайтиСтроки с той же структурой, что в ОтборСтрок.
📌 Удаление и групповые команды. Выделение и удаление работают с видимыми строками. Команды, которые перебирают коллекцию в коде (заполнение цен, пересчёт скидок), затронут все.
Если отбор добавляете в типовую форму, делайте это в расширении конфигурации, а не правкой самой формы. Тогда обновления типовой конфигурации не придётся объединять вручную.
Частые вопросы
Можно ли сделать отбор в табличной части без программирования?
ОтборСтрок задаётся кодом. Без кода настраиваются только отбор динамического списка и параметры выбора колонки.Как отобрать строки по части наименования товара?
ОтборСтрок такое условие не поддерживает. Добавьте в таблицу значений на форме колонку-флаг, заполните её через СтрНайти() и отбирайте по флагу.Работает ли ОтборСтрок на сервере?
Можно ли отобрать строки по значению из шапки документа?
Объект, например склад, и положите его в структуру отбора. При изменении поля в шапке вызывайте ту же процедуру установки отбора.