Отбор в динамическом списке 1С: интерфейс, код и параметры
Содержание
Отбор в динамическом списке ставится двумя путями: пользователь задаёт его в самой форме через команду Настроить список, а разработчик добавляет элемент в Список.Отбор.Элементы или передаёт параметр запроса. Какой путь выбрать, зависит от того, должен ли пользователь иметь возможность отбор снять.
Ниже разобраны оба способа: от кнопок в интерфейсе до группы условий в коде и отбора для виртуальных таблиц регистров. Речь о платформе 1С:Предприятие 8.3 и управляемых формах.
Что такое отбор динамического списка и где он живёт
Динамический список — это реквизит формы типа ДинамическийСписок. Он читает данные порциями, по мере прокрутки, и под капотом использует схему компоновки данных. Поэтому отбор у него устроен так же, как в отчётах на СКД.
Отборов у списка не один, а несколько слоёв. Их полезно различать:
- 🧱 Отбор в запросе. Условие
ГДЕв тексте запроса (при произвольном запросе). Пользователь его не видит и не меняет. - 🔒 Фиксированный отбор. Задаётся из кода, виден пользователю, но снять его в форме нельзя.
- 🙋 Пользовательский отбор. Тот, что человек включил сам через настройки списка. Сохраняется между сеансами.
- 🧩 Параметры. Не отбор в строгом смысле, но тоже сужают выборку: значение подставляется прямо в запрос.
Каждый элемент отбора состоит из четырёх частей:
| Часть | Что означает | Пример |
|---|---|---|
| Левое значение | Поле списка | Организация |
| Вид сравнения | Условие | Равно, Содержит, В списке |
| Правое значение | С чем сравниваем | ссылка, строка, дата |
| Использование | Включён ли элемент | Истина / Ложь |
Элемент отбора можно создать и оставить выключенным. Он появится в настройках списка, а человеку останется поставить галочку.
Как установить отбор в динамическом списке через интерфейс
Пользователю код не нужен. В любом списке справочника или документа есть несколько способов сузить выборку.
Быстрый отбор по значению
Встаньте на ячейку с нужным значением, например на контрагента, откройте контекстное меню и выберите пункт отбора по значению в текущей колонке. Список сразу покажет только строки с этим контрагентом. В шапке списка появится строка с условием, которую можно отключить.
Расширенная настройка списка
Если нужно больше одного условия, откройте команду Настроить список. В форме списка она обычно лежит в меню Ещё или Все действия.
Дальше порядок такой:
- На закладке
ОтборнажмитеДобавить отбор(или перетащите поле в область условий). - Выберите поле:
Организация,Дата,Ответственный. - Задайте вид сравнения:
Равно,Больше,Содержити так далее. - Введите значение и поставьте галочку использования.
- Нажмите
Завершить редактирование.
Условия можно объединять в группы. Правой кнопкой по строке отбора вызывается добавление группы, и у группы выбирается тип: И, ИЛИ или НЕ.
Если пункта Настроить список в форме нет, разработчик мог отключить пользовательские настройки. Это решается в конфигураторе, а не в режиме 1С:Предприятие.
Вид сравнения: что выбрать
| Вид сравнения | Когда брать |
|---|---|
Равно / Не равно | Точное значение: один склад, один контрагент |
В списке / Не в списке | Несколько значений сразу |
В группе / В иерархии | Элемент и всё, что лежит внутри группы справочника |
Содержит / Не содержит | Поиск по части строки |
Начинается с | Номера и коды с известным префиксом |
Заполнено / Не заполнено | Найти строки без договора, комментария, ответственного |
Больше, Меньше и их «или равно» | Даты и суммы |
Отбор в динамическом списке программно: код для управляемой формы
Для разработчика основной вход — свойство Отбор динамического списка. Правильное место — процедура ПриСозданииНаСервере: тогда список читается один раз уже с условием.
Простейший пример, когда по умолчанию показываем документы одной организации:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = ОсновнаяОрганизация;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
Здесь Список — имя реквизита формы, а ОсновнаяОрганизация — любая подготовленная вами переменная со ссылкой.
Отбор по списку значений и по диапазону дат
Для вида сравнения ВСписке правое значение — список значений или массив:
Статусы = Новый Массив;
Статусы.Добавить(Перечисления.СтатусыЗаказов.Новый);
Статусы.Добавить(Перечисления.СтатусыЗаказов.ВРаботе);
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Статус");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
ЭлементОтбора.ПравоеЗначение = Статусы;
ЭлементОтбора.Использование = Истина;
Диапазон дат — это два отдельных элемента: БольшеИлиРавно на начало периода и Меньше на начало следующего. Так конец периода не теряет документы последнего дня с временем:
НачалоПериода = НачалоМесяца(ТекущаяДата());
Условие1 = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Условие1.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Дата");
Условие1.ВидСравнения = ВидСравненияКомпоновкиДанных.БольшеИлиРавно;
Условие1.ПравоеЗначение = НачалоПериода;
Условие1.Использование = Истина;
Условие2 = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Условие2.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Дата");
Условие2.ВидСравнения = ВидСравненияКомпоновкиДанных.Меньше;
Условие2.ПравоеЗначение = ДобавитьМесяц(НачалоПериода, 1);
Условие2.Использование = Истина;
Вспомогательные процедуры БСП
Если конфигурация построена на библиотеке стандартных подсистем, писать это руками не нужно. В общем модуле ОбщегоНазначенияКлиентСервер есть процедура установки элемента отбора динамического списка: ей передают список, имя поля, значение и вид сравнения. Она сама найдёт существующий элемент и поменяет его, а не создаст дубль. Точную сигнатуру посмотрите в синтаксис-помощнике вашей конфигурации.
Как выбрать способ
ПриСозданииНаСервере и оставьте режим отображения обычным или быстрым доступом.Группы И, ИЛИ, НЕ: составные отборы
Верхний уровень отбора всегда работает по правилу «И»: каждый следующий элемент сужает выборку. Чтобы получить «или», нужна группа.
Пример: показать документы, где статус «Новый» или сумма больше 100 000:
Группа = Список.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
Группа.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
Группа.Использование = Истина;
Э1 = Группа.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Э1.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Статус");
Э1.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Э1.ПравоеЗначение = Перечисления.СтатусыЗаказов.Новый;
Э1.Использование = Истина;
Э2 = Группа.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Э2.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("СуммаДокумента");
Э2.ВидСравнения = ВидСравненияКомпоновкиДанных.Больше;
Э2.ПравоеЗначение = 100000;
Э2.Использование = Истина;
Группы вкладываются друг в друга. Типы групп:
- ✅
ГруппаИ— все условия внутри должны выполняться. - 🔀
ГруппаИли— достаточно одного. - 🚫
ГруппаНе— выбираются строки, для которых условия группы не выполняются.
Сначала нарисуйте условие словами, потом переводите в группы. Выражение «А и (Б или В)» — это один элемент А и группа ИЛИ с Б и В внутри.
Фиксированный отбор и режимы отображения
У каждого элемента есть свойство РежимОтображения. Оно решает, увидит ли человек условие и сможет ли его изменить:
| Режим | Что видит пользователь |
|---|---|
Недоступный | Ничего. Условие работает скрыто |
Обычный | Строка в настройках списка |
БыстрыйДоступ | Поле отбора прямо в шапке формы |
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ;
Отдельная история с фиксированными настройками. У компоновщика списка есть два набора: обычные Настройки и ФиксированныеНастройки. Всё, что лежит в фиксированных, пользователь не сможет ни снять, ни перезаписать своими настройками.
Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Добавить(
Тип("ЭлементОтбораКомпоновкиДанных"));
Так делают, когда форма выбора должна показывать, например, только контрагентов-поставщиков, и никаких исключений.
Чтобы пользовательский отбор запоминался между сеансами, элементу нужен идентификатор пользовательской настройки. Без него условие, поставленное из кода, будет вести себя как временное.
Отбор для виртуальных таблиц: через параметры
Если основная таблица списка — виртуальная таблица регистра (Остатки, Обороты, СрезПоследних), отбор поверх готового результата работает медленно. Платформа сначала собирает всю виртуальную таблицу, и только потом отбрасывает лишнее.
Правильнее передать условие в параметры самой таблицы. В запросе списка это выглядит так:
ВЫБРАТЬ
Остатки.Номенклатура КАК Номенклатура,
Остатки.КоличествоОстаток КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки
А значения кладутся в параметры списка:
Список.Параметры.УстановитьЗначениеПараметра("Склад", ТекущийСклад);
Список.Параметры.УстановитьЗначениеПараметра("Период", ТекущаяДата());
Разница ощутима. При отборе по параметру платформа читает из регистра только записи нужного склада. При обычном отборе ей приходится сначала свернуть остатки по всем складам.
Отбор по измерениям регистра лучше всегда переводить в условие виртуальной таблицы. Отбор по ресурсам (количество, сумма) так не сделать: их условие применяется уже к готовой выборке, это нормально.
Если параметр запроса объявлен, но значения не получил, список откроется пустым или с ошибкой. Задавайте параметры до первого показа формы, лучше в ПриСозданииНаСервере.
Отбор не работает или тормозит: что проверить
Чаще всего виноваты не сами условия, а место, где они ставятся.
- 🕳️ Поле не найдено в схеме. Условие на поле, которого нет в запросе списка, вызовет ошибку. Добавьте поле в выборку или проверьте его имя.
- ♻️ Дубли условий. Если вызывать добавление при каждом открытии формы без проверки, элементы копятся. Сначала найдите существующий или очистите
Отбор.Элементы. - 🐌 Установка на клиенте после открытия. Список уже прочитан без условия, а потом читается второй раз. Перенесите установку на сервер.
- 🔗 Отбор через точку. Условие по
Контрагент.ИННзаставляет платформу присоединять справочник. На больших таблицах это заметно; лучше вывести нужное поле в запрос явно. - 🔍
Содержитна миллионе строк. Такое условие не использует индекс. Если возможно, замените наНачинается сили на точное значение. - 🔓 Отбор «слетает». Пользователь сбросил его кнопкой очистки. Для обязательных условий берите фиксированные настройки.
Как изменить или прочитать уже существующий отбор
Часто нужно не добавить условие, а поменять значение у того, что уже есть: форма открывается повторно, пользователь выбрал другую организацию в шапке. Если добавлять элемент заново, условия начнут множиться.
Рабочая схема из трёх шагов:
- Обойдите
Список.Отбор.Элементыи найдите элемент по полю: сравнитеЛевоеЗначениесНовый ПолеКомпоновкиДанных("Организация"). - Нашли — поменяйте
ПравоеЗначениеи поставьтеИспользование = Истина. - Не нашли — создайте новый элемент, как в примерах выше.
&НаСервере
Процедура УстановитьОтборПоОрганизации(Организация)
Поле = Новый ПолеКомпоновкиДанных("Организация");
Найден = Неопределено;
Для Каждого Элемент Из Список.Отбор.Элементы Цикл
Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных")
И Элемент.ЛевоеЗначение = Поле Тогда
Найден = Элемент;
Прервать;
КонецЕсли;
КонецЦикла;
Если Найден = Неопределено Тогда
Найден = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Найден.ЛевоеЗначение = Поле;
Найден.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
КонецЕсли;
Найден.ПравоеЗначение = Организация;
Найден.Использование = ЗначениеЗаполнено(Организация);
КонецПроцедуры
Последняя строка делает полезную вещь: если организация не выбрана, условие просто выключается, а список показывает все строки. Не нужно городить отдельную ветку «очистить отбор».
Этот же приём подходит для обработчика изменения поля в шапке формы. Вызов идёт на сервер, список перечитывается один раз.
Хотите посмотреть, какие условия сейчас реально действуют? Выведите в отладке Список.Отбор.Элементы и проверьте у каждого Использование и РежимОтображения. Выключенные элементы часто принимают за «не работающий отбор».
Отбор по справочнику с иерархией
Для справочников с группами действует свой нюанс. Вид сравнения Равно вернёт только сам элемент. Если нужны все позиции внутри группы «Товары для офиса», берите В группе или В иерархии, в зависимости от того, какие виды сравнения предлагает поле.
Типичная картина: человек выбрал группу, а список остался пустым. Причина проста: в группе нет собственных строк, всё лежит в подгруппах. Смена вида сравнения решает вопрос за минуту.
То же самое относится к кодам и артикулам. Для значений вроде 00-0001234 удобно сравнение Начинается с: вводите первые символы, а не весь номер.
Частые вопросы
Чем отбор динамического списка отличается от отбора в запросе?
Можно ли поставить отбор на реквизит, которого нет в списке на форме?
Как сбросить отбор в динамическом списке из кода?
Список.Отбор.Элементы.Очистить(). Фиксированные настройки при этом не затрагиваются.Почему после обновления формы мой отбор исчез?
Можно ли отбирать по нескольким значениям сразу?
В списке принимает массив или список значений. Для справочников с иерархией есть вариант В списке по иерархии.