Как отфильтровать строки табличной части в управляемой форме 1С 8.3

· 9 мин

Содержание

Чтобы установить отбор в табличной части 1С 8.3, присвойте свойству ОтборСтрок элемента формы фиксированную структуру: Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", Значение). Снять отбор — присвоить Неопределено. Данные при этом не меняются: строки только скрываются из вида.

Типичная ситуация: в накладной 300 строк, кладовщик ищет все позиции одного поставщика или строки без цены. Листать долго, поиск по Ctrl+F прыгает по одной строке. Нужен фильтр прямо в форме документа. Отбор решает это за секунду, и его можно повесить на поле в шапке или на кнопку. Речь об управляемых формах (интерфейс «Такси»), в обычных формах объектная модель другая.

Три разных механизма отбора в формах 1С

Под словом «отбор» в 1С скрываются три механизма. Их путают, поэтому код из одного примера не работает в другом.

Что фильтруемЧемКакие условияГде задать
Строки табличной части документа или справочника, таблицу значений на формеСвойство ОтборСтрок у элемента «Таблица формы»Только равенство, несколько полей через «И»Кодом
Динамический список (журнал, список справочника, подбор)Отбор компоновки данных: Список.ОтборРавно, не равно, больше, в списке, в иерархии, содержит, заполнено и др.Конструктор и код
Значения, которые можно выбрать в колонку табличной частиПараметры выбора и связи параметров выбораОтбор по реквизитам выбираемого объектаКонфигуратор и код

📌 Главное различие:

  • 🔹 ОтборСтрок работает с данными, которые уже лежат в форме. Сервер не участвует, отбор применяется мгновенно.
  • 🔹 Отбор динамического списка превращается в условие запроса к базе. Список читает с сервера только подходящие записи.
  • 🔹 Параметры выбора ничего не скрывают в самой таблице. Они ограничивают форму выбора, которая открывается из ячейки.

Табличная часть документа на форме — это коллекция данных формы (Объект.Товары). У неё нет отбора компоновки, поэтому конструкция Объект.Товары.Отбор не существует, а Элементы.Товары.ОтборСтрок — существует.

Что настраивается в конструкторе формы без кода

Без программирования в конструкторе форм можно задать отбор для двух случаев из трёх.

Отбор динамического списка

  1. Откройте форму в Конфигураторе, вкладка «Реквизиты».
  2. Дважды щёлкните реквизит типа «Динамический список» (обычно он называется Список).
  3. В окне свойств найдите пункт «Настройки списка» и откройте его.
  4. На закладке «Отбор» добавьте поле, выберите вид сравнения и значение.
  5. Сохраните форму и обновите конфигурацию.

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

Отбор значений при выборе в колонку

Здесь фильтруется не таблица, а то, что пользователь выбирает в ячейку. Пример: в колонке «Номенклатура» должны выбираться только услуги, а в колонке «Характеристика» — только характеристики выбранной в строке номенклатуры.

  1. В дереве элементов формы раскройте таблицу и выделите поле-колонку, например ТоварыНоменклатура.
  2. В палитре свойств найдите «Параметры выбора». Добавьте строку: имя Отбор.ПометкаУдаления, значение Ложь.
  3. Для зависимой колонки откройте «Связи параметров выбора». Имя — Отбор.Владелец, реквизит-источник — поле текущей строки: Элементы.Товары.ТекущиеДанные.Номенклатура.

💡 Те же свойства есть у реквизита табличной части в дереве метаданных. Настройка там действует во всех формах объекта. Настройка у элемента формы — только в этой форме.

Отбор строк коллекции (ОтборСтрок) в конструкторе статически не задают. Его ставят кодом: при открытии формы или по действию пользователя.

Программная установка отбора строк табличной части

Базовый сценарий: в шапку формы выводим поле «Отбор по номенклатуре», при его изменении фильтруем табличную часть.

Шаг 1. На вкладке «Реквизиты» создайте реквизит формы ОтборНоменклатура с типом СправочникСсылка.Номенклатура. Перетащите его в дерево элементов над таблицей.

Шаг 2. В свойствах поля создайте обработчик события ПриИзменении.

Шаг 3. Вставьте код в модуль формы:

&НаКлиенте
Процедура ОтборНоменклатураПриИзменении(Элемент)
	ПрименитьОтборТоваров();
КонецПроцедуры

&НаКлиенте
Процедура ПрименитьОтборТоваров()
	
	Если ЗначениеЗаполнено(ОтборНоменклатура) Тогда
		Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", ОтборНоменклатура);
	Иначе
		Элементы.Товары.ОтборСтрок = Неопределено;
	КонецЕсли;
	
КонецПроцедуры

Очистил поле — отбор снят, видны все строки.

Отбор по нескольким полям

Ключи структуры объединяются условием «И». Строка видна, только если совпали все поля:

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

Свойство ожидает именно ФиксированнаяСтруктура. Обычную структуру передавайте в конструктор фиксированной, как в примере.

Условия «больше», «не равно», «в списке»

ОтборСтрок умеет только равенство. Для остальных условий нужна служебная колонка-флаг: заполняете её по своему правилу, а отбираете по ней.

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

&НаКлиенте
Процедура ПоказатьСтрокиБольше(Порог)
	
	Для Каждого Строка Из ТаблицаРасчета Цикл
		Строка.Видим = (Строка.Сумма > Порог);
	КонецЦикла;
	
	Элементы.ТаблицаРасчета.ОтборСтрок = Новый ФиксированнаяСтруктура("Видим", Истина);
	
КонецПроцедуры

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

Отбор сразу при открытии формы

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Если Параметры.Свойство("ОтборНоменклатура") Тогда
		ОтборНоменклатура = Параметры.ОтборНоменклатура;
		Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", ОтборНоменклатура);
	КонецЕсли;
	
КонецПроцедуры

Чтобы параметр дошёл до формы, добавьте его на вкладке «Параметры» редактора формы с тем же именем и типом. Иначе платформа его не примет.

Найти строки кодом, не трогая вид

Если отбор нужен для обработки, а не для показа, используйте НайтиСтроки. Метод вернёт массив строк, таблица на экране не изменится:

&НаКлиенте
Процедура ОбнулитьСкидкуПоНоменклатуре(Номенклатура)
	
	Отбор = Новый Структура("Номенклатура", Номенклатура);
	НайденныеСтроки = Объект.Товары.НайтиСтроки(Отбор);
	
	Для Каждого Строка Из НайденныеСтроки Цикл
		Строка.ПроцентСкидки = 0;
	КонецЦикла;
	
КонецПроцедуры

Отбор в динамическом списке и виды сравнения

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

Код без библиотеки стандартных подсистем

&НаСервере
Процедура УстановитьОтборПоКонтрагенту(Контрагент)
	
	ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");
	ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ЭлементОтбора.ПравоеЗначение = Контрагент;
	ЭлементОтбора.Использование = Истина;
	
КонецПроцедуры

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

Код в типовых конфигурациях на БСП

В БП 3.0, ЗУП 3.1, УТ 11 и других конфигурациях на библиотеке стандартных подсистем есть готовая процедура. Она сама находит и обновляет элемент отбора:

ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
	Список, "Контрагент", Контрагент, ВидСравненияКомпоновкиДанных.Равно, , ЗначениеЗаполнено(Контрагент));

Последний параметр — «Использование». Передали Ложь — отбор отключён, но элемент остаётся. Удобно для поля-фильтра, которое пользователь может очистить.

Открыть список уже с отбором

Для форм списка у платформы есть стандартный параметр Отбор. Структура из него становится отбором динамического списка, и модуль формы трогать не нужно:

&НаКлиенте
Процедура ОткрытьДокументыКонтрагента(Команда)
	
	ПараметрыФормы = Новый Структура("Отбор", Новый Структура("Контрагент", Объект.Контрагент));
	ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаСписка", ПараметрыФормы, ЭтотОбъект);
	
КонецПроцедуры

Имя документа в примере — из БП 3.0, в своей конфигурации подставьте нужный объект. Поле Контрагент должно быть в списке, иначе отбор не сработает.

Виды сравнения, которые нужны чаще всего

Вид сравненияКогда применятьЗначение справа
Равно / НеРавноКонкретный контрагент, склад, статусОдно значение
ВСписке / НеВСпискеНесколько складов или организацийСписокЗначений
ВИерархииГруппа номенклатуры со всеми подгруппамиСсылка на группу
Больше, МеньшеИлиРавно и др.Суммы, даты, количестваЧисло или дата
СодержитЧасть наименования или комментарияСтрока
Заполнено / НеЗаполненоДокументы без договора, товары без артикулаНе нужно

💡 Пользователь в режиме «Предприятие» тоже может поставить такой отбор сам: Ещё → Настроить список → Отбор. Программный отбор из кода и пользовательский складываются.

Фильтр на командной панели табличной части

Пользователю удобнее одна кнопка, чем поле в шапке. Сделаем переключатель «Только без номенклатуры»: нажал — видны незаполненные строки, нажал снова — все.

  1. На вкладке «Команды» формы создайте команду ТолькоНезаполненные, задайте ей обработчик.
  2. Перетащите команду в командную панель таблицы Товары (узел «Командная панель» внутри элемента таблицы).
  3. Вставьте код:
&НаКлиенте
Процедура ТолькоНезаполненные(Команда)
	
	Кнопка = Элементы.ТоварыТолькоНезаполненные;
	Кнопка.Пометка = Не Кнопка.Пометка;
	
	Если Кнопка.Пометка Тогда
		ПустаяНоменклатура = ПредопределенноеЗначение("Справочник.Номенклатура.ПустаяСсылка");
		Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура("Номенклатура", ПустаяНоменклатура);
	Иначе
		Элементы.Товары.ОтборСтрок = Неопределено;
	КонецЕсли;
	
КонецПроцедуры

Имя кнопки (ТоварыТолькоНезаполненные) посмотрите в дереве элементов: платформа складывает его из имени таблицы и команды. Свойство Пометка делает кнопку «залипающей» — видно, что фильтр включён.

Подсказка, что отбор включён

Отфильтрованная таблица выглядит как обычная. Пользователь забывает про фильтр и думает, что строки пропали. Два простых решения:

  • 🟡 меняйте заголовок таблицы: Элементы.Товары.Заголовок = "Товары (отбор: " + ОтборНоменклатура + ")";
  • 🟡 держите рядом кнопку «Показать все», которая сбрасывает ОтборСтрок и снимает пометку с переключателя.

Если в форме несколько кнопок-фильтров, сводите их в одну процедуру ПрименитьОтборТоваров(). Она собирает структуру из всех включённых условий. Иначе вторая кнопка затрёт отбор первой: ОтборСтрок хранит только одну структуру.

Особенности управляемых форм: где отбор ломается

Диагностика: выберите симптом

Ещё несколько вещей, которые полезно знать заранее.

📌 Номера строк не перенумеровываются. После отбора видны строки 3, 17, 42 — это нормально. Колонка НомерСтроки показывает позицию в полной табличной части.

📌 Код обходит все строки. Цикл Для Каждого Строка Из Объект.Товары видит и скрытые строки. Если обработка должна касаться только видимых, используйте НайтиСтроки с той же структурой, что в ОтборСтрок.

📌 Удаление и групповые команды. Выделение и удаление работают с видимыми строками. Команды, которые перебирают коллекцию в коде (заполнение цен, пересчёт скидок), затронут все.

Если отбор добавляете в типовую форму, делайте это в расширении конфигурации, а не правкой самой формы. Тогда обновления типовой конфигурации не придётся объединять вручную.

Частые вопросы

Можно ли сделать отбор в табличной части без программирования?
Для строк табличной части документа — нет, ОтборСтрок задаётся кодом. Без кода настраиваются только отбор динамического списка и параметры выбора колонки.
Как отобрать строки по части наименования товара?
ОтборСтрок такое условие не поддерживает. Добавьте в таблицу значений на форме колонку-флаг, заполните её через СтрНайти() и отбирайте по флагу.
Работает ли ОтборСтрок на сервере?
Свойство доступно и на клиенте, и на сервере. Ставить его на клиенте удобнее: не нужен серверный вызов, таблица перерисуется сразу.
Можно ли отобрать строки по значению из шапки документа?
Да. Возьмите значение из реквизита Объект, например склад, и положите его в структуру отбора. При изменении поля в шапке вызывайте ту же процедуру установки отбора.
Почему отбор в обычной форме из старой обработки не работает в управляемой?
В обычных формах другая объектная модель: табличное поле и его свойства. В управляемой форме работают через элемент «Таблица формы» и данные формы, код нужно переписать.