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

Программист 1С v8.3 (Обычные формы) Управленческий учет IT и автоматизация бизнеса
← На главную

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

Проблема использования метода Установить() для списков

Рассмотрим типичную ошибку начинающего разработчика. При попытке передать СписокЗначений в метод Установить(), система не выдает ошибку, но отбор работает некорректно — список документов оказывается пустым. Проанализируем причину. Метод Установить() по умолчанию всегда выставляет вид сравнения Равно. Однако поле документа (например, СтатусЗаказа) не может быть «равно» целому списку; оно может только «входить в состав» этого списка.

Для решения этой задачи нам необходимо вручную определить вид сравнения. Разберем по шагам, как это сделать правильно:

  1. Создаем объект СписокЗначений и наполняем его нужными элементами (например, ссылками из перечисления).
  2. Обращаемся к элементу отбора напрямую через коллекцию Отбор.
  3. Устанавливаем свойство ВидСравнения в значение ВидСравнения.ВСписке.
  4. Передаем наш список в свойство Значение.
  5. Активируем отбор через свойство Использование.

Посмотрим на пример кода, реализующий эту логику:


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

// Настраиваем отбор в списке документов
ЭлементОтбора = ДокументСписок.Отбор.СтатусЗаказа;
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = СписокСтатусов;
ЭлементОтбора.Использование = Истина;

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

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

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


Процедура ПриОткрытии()
    // Включаем возможность отбора по системному полю "Проведен"
    // "Список" — это имя элемента формы (табличного поля)
    ЭлементыФормы.Список.НастройкаОтбора.Проведен.Доступность = Истина;
КонецПроцедуры

После того как доступность установлена, мы можем управлять этим фильтром так же, как и любым другим реквизитом. Важно помнить, что поле Проведен имеет булево тип (Истина/Ложь), поэтому вид сравнения здесь должен быть Равно.

Комплексное решение: множественный отбор по статусу и проведению

Теперь объединим полученные знания в одну процедуру. Допустим, у нас на форме есть флажок (ФлажокФильтр), при установке которого список должен мгновенно фильтроваться по трем статусам и признаку «Не проведен».


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

Важные нюансы и рекомендации

При реализации сложных отборов в 1С стоит учитывать несколько технических аспектов, которые влияют на стабильность и скорость работы программы:

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

Заключение: Управление списками в 1С 8.3 на обычных формах требует внимательного отношения к типам сравнения. Использование ВидСравнения.ВСписке в сочетании с СписокЗначений открывает гибкие возможности для фильтрации, а предварительная настройка доступности системных полей в ПриОткрытии позволяет строить отчеты и списки любой сложности.

← На главную