К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как сделать отбор в динамическом списке в 1С

Как сделать отбор в динамическом списке 1С: настройка произвольного запроса, отбор в конструкторе, программный отбор через ЭлементыОтбора, типичные ошибки и проверка результата.

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

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

Важно понимать разницу между отбором, зашитым в динамический список, и отбором, который пользователь ставит сам через кнопку «Ещё — Настроить список». Первый работает всегда и не может быть снят пользователем, второй — временный и виден только в текущем сеансе. Ниже разобраны оба подхода и программная установка отбора через код.

Где находится настройка отбора динамического списка

Откройте форму списка в конфигураторе и найдите реквизит формы типа «ДинамическийСписок» — обычно он называется «Список». В палитре свойств этого реквизита есть строка «Настройка списка», при нажатии на которую открывается конструктор настроек. Именно здесь задаются отбор, сортировка, группировка и условное оформление, которые будут применяться к списку по умолчанию.

В конструкторе перейдите на вкладку «Отбор» и добавьте элемент: укажите поле (например, «Организация» или «ПометкаУдаления»), вид сравнения («Равно», «Не равно», «В списке» и другие) и значение. Если флажок «Включать в пользовательские настройки» снят, отбор будет работать скрыто от пользователя, и тот не сможет его отключить — это удобно для жёстких ограничений вроде фильтра по текущей организации.

Обратите внимание на флажок «Произвольный запрос» в свойствах динамического списка. Если он включён и текст запроса написан вручную, часть полей для отбора может быть недоступна или вести себя неочевидно — например, отбор по полю, которого нет в выборке запроса, не сработает. В таких случаях отбор логичнее переносить в сам текст запроса через условие ГДЕ.

Отбор через конструктор настроек: пошагово

Рассмотрим типовую задачу: в списке документов «Реализация товаров» нужно показывать только проведённые документы. Откройте настройку списка, перейдите на вкладку «Отбор», нажмите «Добавить» и выберите поле «Проведен». Установите вид сравнения «Равно» и значение «Истина». После сохранения формы список будет автоматически скрывать непроведённые документы.

Для составных условий используйте группы элементов отбора: «Группа И» (все условия выполняются одновременно) и «Группа ИЛИ» (достаточно одного условия). Например, чтобы показать документы по двум складам, создайте группу «ИЛИ» и добавьте в неё два элемента отбора по полю «Склад» с разными значениями. Альтернатива — один элемент с видом сравнения «В списке», что короче и читается проще.

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

Программная установка отбора через код

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

Типовой фрагмент кода для отбора документов по текущей организации выглядит так:

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");

ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;

ЭлементОтбора.ПравоеЗначение = Параметры.Организация;

ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;

ЭлементОтбора.Использование = Истина;

КонецПроцедуры

Режим отображения «Недоступный» скрывает отбор из пользовательских настроек, чтобы пользователь не мог его снять. Если нужен изменяемый отбор, используйте «Быстрый доступ» — тогда элемент появится в панели быстрых отборов над списком. Для динамического изменения отбора (например, при выборе контрагента на форме) тот же код выполняется в обработчике события, но перед добавлением нового элемента старый отбор по этому полю следует удалить или отключить, иначе условия будут накапливаться.

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

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

Если для списка включён флажок «Произвольный запрос», постоянные ограничения правильнее писать прямо в тексте запроса через условие ГДЕ. Такой отбор гарантированно не будет снят, не конфликтует с пользовательскими настройками и выполняется оптимально на стороне СУБД. Например, чтобы исключить помеченные на удаление элементы, в запрос добавляется строка «ГДЕ НЕ СправочникНоменклатура.ПометкаУдаления».

Для отборов, зависящих от параметров, в запросе используются параметры: «ГДЕ Документ.Организация = &Организация». Значение параметра устанавливается программно через Список.Параметры.УстановитьЗначениеПараметра("Организация", ЗначениеОрганизации) в обработчике ПриСозданииНаСервере. Если параметр не установлен, запрос вернёт пустой результат или ошибку — поэтому параметру всегда нужно задавать значение до первого обращения к списку.

Ограничение этого подхода: условие ГДЕ с параметром делает отбор обязательным. Если нужно, чтобы при пустом параметре показывались все записи, используйте конструкцию «ГДЕ (&Организация = ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка) ИЛИ Документ.Организация = &Организация)». Это стандартный приём для «мягких» отборов, но помните, что при больших таблицах такие условия с ИЛИ могут замедлять запрос.

Сравнение вариантов

Отбор в конструкторе настроек

Подходит для постоянных условий с фиксированными значениями; не требует кода, но не может зависеть от контекста сеанса

Программный отбор через Список.Отбор

Гибкий вариант для значений, зависящих от пользователя или параметров формы; требует аккуратного управления элементами, чтобы не плодить дубли

Условие в тексте произвольного запроса

Самый надёжный и быстрый для жёстких ограничений; недоступен пользователю, но требует навыков языка запросов

Динамический отбор при изменении данных на форме

Частая задача — фильтровать один список в зависимости от выбора в другом. Например, на форме есть поле «Контрагент», а список должен показывать только его договоры. Реализуется это в обработчике ПриИзменении поля: в нём программно устанавливается отбор динамического списка по полю «Владелец» или «Контрагент» в зависимости от структуры справочника.

Ключевой момент — перед установкой нового отбора нужно найти и отключить прежний элемент по тому же полю. Проще всего перебрать Список.Отбор.Элементы в цикле и сравнить ЛевоеЗначение каждого элемента с нужным полем, установив Использование = Ложь или удалив элемент. Если этого не делать, при каждом изменении поля будет добавляться новый элемент отбора, и список в итоге покажет пустой результат, потому что условия начнут противоречить друг другу.

Альтернатива ручному управлению — механизм связей параметров выбора и отбор по владельцу, встроенный в платформу для полей ввода. Но для динамических списков на форме программная установка отбора остаётся основным инструментом, поэтому код управления отбором имеет смысл вынести в отдельную серверную процедуру и вызывать её из всех обработчиков, где меняется контекст.

Проверка результата и типичные ошибки

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

Наиболее частая ошибка — отбор по полю, которого нет в запросе динамического списка при включённом произвольном запросе: элемент добавляется без ошибки, но фильтрация не работает или возникает ошибка выполнения запроса. Вторая типичная проблема — сравнение несовместимых типов, например отбор строкового поля значением типа «Число». Третья — установка отбора в клиентском контексте: коллекция отбора динамического списка доступна только на сервере, поэтому код размещают в серверных процедурах.

Типичные ошибки
01
Добавление нового элемента отбора при каждом изменении без удаления старого — условия накапливаются, список пустеет
02
Отбор по полю, отсутствующему в произвольном запросе — фильтр не срабатывает или запрос падает с ошибкой
03
Установка отбора в клиентской процедуре — недоступность свойств динамического списка на клиенте
04
Несовпадение типов значения и поля — отбор молча не фильтрует данные
05
Неустановленный параметр произвольного запроса — пустой список без видимой причины
Контрольные точки

Как проверить результат

Содержимое списка после настройки
Норма

Отображаются только записи, удовлетворяющие условию

Тревожный признак

Видны лишние записи или список пуст при наличии подходящих данных

Панель быстрых отборов над списком
Норма

Видны ожидаемые условия, пользовательский отбор не конфликтует с фиксированным

Тревожный признак

Дублирующиеся условия по одному полю или отсутствие задуманного отбора

Повторное открытие формы
Норма

Отбор применяется стабильно при каждом открытии

Тревожный признак

После перезапуска отбор пропадает или умножается

Производительность и ограничения

Отбор по индексированным полям (ссылки, дата, номер, стандартные реквизиты) выполняется быстро даже на больших таблицах. Отбор по неиндексированным реквизитам, по подстроке («Содержит») и по выражениям с функциями заставляет СУБД перебирать записи, что заметно при сотнях тысяч строк. Если такой отбор неизбежен, ограничьте его дополнительным условием по дате или организации, чтобы сузить выборку.

Учитывайте и ограничения платформы: динамический список не позволяет напрямую фильтровать по вычисляемым полям, которых нет в запросе, а отбор вида «В иерархии» по большим иерархическим справочникам может работать медленнее, чем ожидается. Для сложных аналитических выборок вместо динамического списка иногда целесообразнее использовать отчёт на СКД, где механизм отборов реализован полнее.

Итог

Что важно запомнить

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

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

Как скрыть от пользователя возможность снять отбор?

Установите элементу отбора режим отображения «Недоступный» (программно) или снимите флажок «Включать в пользовательские настройки» в конструкторе настроек. Ещё надёжнее перенести условие в текст произвольного запроса через ГДЕ — такой отбор пользователь не увидит и не сможет изменить.

Почему программный отбор добавлен, но список не фильтруется?

Проверьте три вещи: установлено ли свойство Использование в Истина, совпадает ли имя поля с полем запроса динамического списка (для произвольного запроса поле должно присутствовать в выборке) и совпадает ли тип значения с типом поля. Также убедитесь, что код выполняется в серверной процедуре.

Как сделать отбор по нескольким значениям одного поля?

Используйте вид сравнения «В списке» и передайте в правое значение список значений или массив. Это компактнее, чем группа «ИЛИ» из нескольких элементов, и обычно эффективнее выполняется на уровне СУБД.

Можно ли программно снять пользовательский отбор, установленный через «Настроить список»?

Да, пользовательские настройки хранятся в Список.КомпоновщикНастроек.ПользовательскиеНастройки. Можно найти нужный элемент и установить Использование = Ложь. Однако вмешиваться в настройки пользователя стоит осторожно — при следующем открытии формы платформа может восстановить сохранённые настройки.

Чем отбор в динамическом списке отличается от отбора в отчёте на СКД?

Механизм компоновки данных общий, но в отчёте на СКД отборы настраиваются пользователем свободнее и поддерживают сложные сценарии с ресурсами и группировками. Динамический список ориентирован на оперативную работу со списком объектов, поэтому для аналитических выборок с гибкими фильтрами отчёт предпочтительнее.

Как отфильтровать список документов за текущий месяц?

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