При работе с конфигурациями на обычных формах (например, 1С:УТП или 1С:УПП) разработчики часто сталкиваются с необходимостью программно ограничить список документов по сложным критериям. Типичная задача: показать только те документы, которые имеют определенные статусы и при этом уже проведены (или, наоборот, не проведены). В этой статье мы подробно разберем, как правильно управлять объектом Отбор, почему стандартный метод Установить() не всегда подходит и как «проявить» скрытые системные поля для фильтрации.
Рассмотрим типичную ошибку начинающего разработчика. При попытке передать СписокЗначений в метод Установить(), система не выдает ошибку, но отбор работает некорректно — список документов оказывается пустым. Проанализируем причину. Метод Установить() по умолчанию всегда выставляет вид сравнения Равно. Однако поле документа (например, СтатусЗаказа) не может быть «равно» целому списку; оно может только «входить в состав» этого списка.
Для решения этой задачи нам необходимо вручную определить вид сравнения. Разберем по шагам, как это сделать правильно:
СписокЗначений и наполняем его нужными элементами (например, ссылками из перечисления).Отбор.ВидСравнения в значение ВидСравнения.ВСписке.Значение.Использование.Посмотрим на пример кода, реализующий эту логику:
// Подготовим список необходимых статусов
СписокСтатусов = Новый СписокЗначений;
СписокСтатусов.Добавить(Перечисления.СтатусЗаказа.ВРаботе);
СписокСтатусов.Добавить(Перечисления.СтатусЗаказа.Оплачен);
СписокСтатусов.Добавить(Перечисления.СтатусЗаказа.Отправлен);
// Настраиваем отбор в списке документов
ЭлементОтбора = ДокументСписок.Отбор.СтатусЗаказа;
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = СписокСтатусов;
ЭлементОтбора.Использование = Истина;
Следующий частый вопрос: как отфильтровать список так, чтобы видеть только проведенные или только непроведенные документы? В метаданных за это отвечает системное поле Проведен (в программном коде часто доступно по англоязычному идентификатору Posted). Однако при попытке программного обращения к Отбор.Проведен можно столкнуться с тем, что это поле недоступно для фильтрации по умолчанию.
Выясним причину: в обычных формах платформа 1С иногда скрывает системные поля из настройки отбора для оптимизации. Чтобы сделать поле доступным для управления, нам нужно принудительно включить его доступность в модуле формы. Проанализируем ситуацию на примере процедуры ПриОткрытии.
Процедура ПриОткрытии()
// Включаем возможность отбора по системному полю "Проведен"
// "Список" — это имя элемента формы (табличного поля)
ЭлементыФормы.Список.НастройкаОтбора.Проведен.Доступность = Истина;
КонецПроцедуры
После того как доступность установлена, мы можем управлять этим фильтром так же, как и любым другим реквизитом. Важно помнить, что поле Проведен имеет булево тип (Истина/Ложь), поэтому вид сравнения здесь должен быть Равно.
Теперь объединим полученные знания в одну процедуру. Допустим, у нас на форме есть флажок (ФлажокФильтр), при установке которого список должен мгновенно фильтроваться по трем статусам и признаку «Не проведен».
Процедура ФлажокФильтрПриИзменении(Элемент)
// Получаем доступ к объекту отбора нашего списка
ТекущийОтбор = ЭлементыФормы.Список.Значение.Отбор;
Если ЭлементыФормы.ФлажокФильтр.Значение = Истина Тогда
// 1. Установка множественного фильтра по статусам
СписокДляОтбора = Новый СписокЗначений;
СписокДляОтбора.Добавить(Перечисления.СтатусЗаказа.ВРаботе);
СписокДляОтбора.Добавить(Перечисления.СтатусЗаказа.Оплачен);
ТекущийОтбор.СтатусЗаказа.ВидСравнения = ВидСравнения.ВСписке;
ТекущийОтбор.СтатусЗаказа.Значение = СписокДляОтбора;
ТекущийОтбор.СтатусЗаказа.Использование = Истина;
// 2. Установка фильтра по статусу проведения (только НЕ проведенные)
// Используем системное имя "Posted" или "Проведен" (зависит от версии)
ТекущийОтбор.Posted.ВидСравнения = ВидСравнения.Равно;
ТекущийОтбор.Posted.Значение = Ложь;
ТекущийОтбор.Posted.Использование = Истина;
Иначе
// Отключаем использование отборов при снятии флажка
ТекущийОтбор.СтатусЗаказа.Использование = Ложь;
ТекущийОтбор.Posted.Использование = Ложь;
КонецЕсли;
КонецПроцедуры
При реализации сложных отборов в 1С стоит учитывать несколько технических аспектов, которые влияют на стабильность и скорость работы программы:
Отбор, объединяются по логическому «И». Это значит, что документ попадет в список только в том случае, если он соответствует ВСЕМ установленным фильтрам одновременно. Реализовать логику «ИЛИ» (например, показать или статус 'В работе', или 'Все проведенные') стандартным механизмом Отбор в обычных формах невозможно. Для таких целей используются динамические списки с произвольным запросом (в управляемых формах) или построитель отчета.Проведен является очень быстрым, так как это поле всегда индексируется платформой. Однако если вы строите сложный отбор по списку значений для неиндексированного реквизита, при большом количестве документов в базе (десятки и сотни тысяч) открытие списка может замедлиться. В этом случае рекомендуется установить свойство «Индексировать» у соответствующего реквизита в конфигураторе.ТекущийОтбор.Сбросить(). Это гораздо эффективнее, чем вручную перебирать каждое поле и устанавливать Использование = Ложь.Отбор.Posted может вызвать ошибку. Если это произошло, попробуйте использовать русскоязычный вариант Отбор.Проведен.Заключение: Управление списками в 1С 8.3 на обычных формах требует внимательного отношения к типам сравнения. Использование ВидСравнения.ВСписке в сочетании с СписокЗначений открывает гибкие возможности для фильтрации, а предварительная настройка доступности системных полей в ПриОткрытии позволяет строить отчеты и списки любой сложности.