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

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

1С: как программно установить отбор

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

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

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

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

Как устроен отбор в динамическом списке

Динамический список на управляемой форме работает на механизме системы компоновки данных (СКД), даже если вы не создавали схему явно. У него есть свойство КомпоновщикНастроек, внутри которого находятся пользовательские настройки и фиксированные настройки. Программный отбор добавляется в коллекцию Отбор.Элементы одной из этих настроек.

Каждый элемент отбора описывается тремя обязательными свойствами: ЛевоеЗначение (поле, по которому фильтруем, типа ПолеКомпоновкиДанных), ВидСравнения (равно, в списке, содержит и т.д.) и ПравоеЗначение (само значение фильтра). Дополнительно задаётся Использование = Истина, иначе элемент будет существовать, но не применяться.

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

Как установить отбор в динамическом списке формы

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

Процедура УстановитьОтборПоОрганизации(Организация)

ЭлементОтбора = Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(

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

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

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

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

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

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

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

Свойство РежимОтображения = Недоступный скрывает элемент из пользовательских настроек: пользователь увидит отфильтрованный список, но не сможет снять отбор. Если нужно, чтобы фильтр был виден и редактируем, используйте Обычный или БыстрыйДоступ.

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

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

Как передать отбор при открытии формы списка

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

ПараметрыФормы = Новый Структура;

Отбор = Новый Структура;

Отбор.Вставить("Организация", ТекущаяОрганизация);

Отбор.Вставить("Проведен", Истина);

ПараметрыФормы.Вставить("Отбор", Отбор);

ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаСписка", ПараметрыФормы);

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

Если поле, по которому вы фильтруете, не выведено в список и не входит в основную таблицу динамического списка, платформа может проигнорировать такой отбор или выдать ошибку. В этом случае добавьте поле в запрос динамического списка (свойство «Произвольный запрос») или используйте программную установку отбора в модуле формы.

Способы установить отбор

Параметр «Отбор» при открытии формы

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

КомпоновщикНастроек динамического списка

Полный контроль: любые виды сравнения, группы И/ИЛИ, фиксированные отборы; требует доработки модуля формы

Запрос с параметрами

Используется вне форм — в отчётах, обработках, выборках; не применим напрямую к динамическому списку

Отбор в СКД отчёта

Для отчётов на компоновке данных; настраивается через Настройки компоновщика отчёта

Отбор в запросе через параметры

В обработках, отчётах и серверных процедурах данные чаще получают запросом. Отбор здесь задаётся секцией ГДЕ с параметрами, которые передаются методом УстановитьПараметр. Это самый производительный способ: фильтрация выполняется на стороне СУБД, и в память не загружаются лишние записи.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Док.Ссылка,

| Док.Дата,

| Док.СуммаДокумента

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Док

|ГДЕ

| Док.Организация = &Организация

| И Док.Дата МЕЖДУ &НачалоПериода И &КонецПериода

| И Док.Проведен";

Запрос.УстановитьПараметр("Организация", Организация);

Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(Период.ДатаНачала));

Запрос.УстановитьПараметр("КонецПериода", КонецДня(Период.ДатаОкончания));

Результат = Запрос.Выполнить().Выгрузить();

Для отбора по списку значений используйте оператор В (&СписокЗначений) и передавайте массив или список значений одним параметром. Для поиска по подстроке — оператор ПОДОБНО "%" + &СтрокаПоиска + "%" либо конструкция ПОДОБНО &Шаблон с готовым шаблоном, не забывая экранировать спецсимволы.

Частая ошибка — сравнение с пустой ссылкой через = &Параметр, когда параметр не заполнен. Если параметр необязателен, используйте оборот И (Док.Контрагент = &Контрагент ИЛИ &Контрагент = НЕОПРЕДЕЛЕНО) и передавайте Неопределено для пропуска условия. Альтернатива — динамическая сборка текста запроса, но она усложняет поддержку.

Отбор в отчёте на СКД

Для отчётов, построенных на системе компоновки данных, программный отбор добавляется в настройки компоновщика отчёта. Типовое место — модуль объекта отчёта или модуль формы отчёта, обработчик ПриСозданииНаСервере либо ПередЗагрузкойВариантаНаСервере.

Настройки = Отчет.КомпоновщикНастроек.Настройки;

ЭлементОтбора = Настройки.Отбор.Элементы.Добавить(

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

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

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

ЭлементОтбора.ПравоеЗначение = СписокСкладов;

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

Если поле отбора должно быть доступно пользователю в шапке отчёта, используйте коллекцию Настройки.ПараметрыДанных и пользовательские настройки: найдите нужный элемент по ИдентификаторПользовательскойНастройки и установите ему значение и Использование = Истина. Так отчёт откроется с предустановленным фильтром, который пользователь сможет изменить.

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

Отбор в таблице значений и табличной части

Таблица значений не поддерживает отбор в стиле СКД, но предлагает два метода: НайтиСтроки(ПараметрыОтбора) для получения массива подходящих строк и Найти(Значение, Колонка) для поиска первой совпадающей строки. Параметры отбора передаются структурой, где ключи — имена колонок.

Отбор = Новый Структура;

Отбор.Вставить("Номенклатура", ИскомаяНоменклатура);

Отбор.Вставить("Склад", ИскомыйСклад);

НайденныеСтроки = ТаблицаТоваров.НайтиСтроки(Отбор);

Для Каждого СтрокаТовара Из НайденныеСтроки Цикл

// обработка строки

КонецЦикла;

Сравнение в НайтиСтроки идёт строго на равенство с учётом типа: число 10 не совпадёт со строкой "10". Если нужен поиск по частичному совпадению или по диапазону, придётся перебирать таблицу циклом с проверкой условия вручную — либо выгрузить данные запросом с нужным отбором сразу.

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

Проверка результата и отладка

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

Полезный приём: метод ПолучитьИсполняемуюСхемуКомпоновкиДанных и ПолучитьИсполняемыеНастройкиКомпоновкиДанных у динамического списка позволяют увидеть итоговые настройки с учётом всех слоёв — фиксированных, пользовательских и программных. Если отбор «потерялся», чаще всего он переопределён загрузкой пользовательских настроек после вашего кода.

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

Контрольные точки

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

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

Показываются только записи, удовлетворяющие условию

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

Список пуст либо содержит лишние записи — проверьте вид сравнения и тип значения

Элементы отбора в «Настроить список»
Норма

Добавленный элемент виден (или скрыт, если задан Недоступный) и активен

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

Элемента нет — вероятно, настройки перезаписаны после вашего кода

Результат запроса с параметрами
Норма

Количество записей соответствует ожиданию при ручной проверке

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

Пустой результат — проверьте заполненность параметров и границы дат

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

Как установить отбор «не равно» или «не заполнено»?

Используйте соответствующий вид сравнения компоновки данных: ВидСравненияКомпоновкиДанных.НеРавно, НеЗаполнено, Заполнено, НеВСписке. Для условия «не заполнено» правое значение указывать не нужно — достаточно левого значения и вида сравнения.

Как объединить несколько условий через «ИЛИ»?

Добавьте в коллекцию элементов отбора группу типа ГруппаЭлементовОтбораКомпоновкиДанных с ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли, а затем добавляйте элементы уже внутрь этой группы. По умолчанию элементы верхнего уровня объединяются по «И».

Почему отбор по дате не срабатывает?

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

Можно ли установить отбор в обычных формах (не управляемых)?

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

Как программно снять установленный отбор?

Найдите элемент в коллекции Отбор.Элементы и либо удалите его методом Удалить, либо установите Использование = Ложь. Если элементов много и их происхождение неизвестно, проще очистить всю коллекцию методом Очистить и заново добавить нужные элементы.

Влияет ли программный отбор на производительность?

Сам по себе отбор ускоряет работу, так как уменьшает объём выбираемых данных. Проблемы возникают при отборе по неиндексированным полям больших таблиц и при использовании «ПОДОБНО» с подстановкой в начале строки — такие условия не позволяют СУБД использовать индекс.

Итог

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

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