Как проверить наличие установленного отбора и включить свой фильтр в обычной форме 1С

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

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

В этой статье мы подробно разберем, как программно проверить, открыта ли форма справочника с уже заданными отборами, и если нет — установить свой собственный фильтр. Мы проанализируем различные подходы: от простых проверок конкретных полей до универсальных циклов.

Зачем проверять существующие отборы?

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

  1. Проверить, установлены ли какие-либо фильтры платформой или вызывающим кодом.
  2. Проверить контекст открытия (не является ли форма формой выбора).
  3. Если фильтров нет — установить «дефолтный» отбор для удобства работы.

Способ 1: Проверка конкретных полей отбора

Проанализируем самый простой вариант, когда мы проверяем активность конкретных полей, которые чаще всего используются пользователями (например, Код, Наименование или ИНН). Этот метод подходит, если структура справочника стабильна и список полей поиска невелик.

Рассмотрим пример реализации в процедуре ПриОткрытии для справочника физических лиц:


Процедура ПриОткрытии()
    // Проверяем, не включены ли стандартные фильтры пользователем или системой
    Если Не (СправочникСписок.Отбор.Код.Использование
        Или СправочникСписок.Отбор.Наименование.Использование
        Или СправочникСписок.Отбор.ИНН.Использование) Тогда
        
        // Если форма "чистая", устанавливаем наш отбор
        // Например, показываем только сотрудников основной организации
        Попытка
            СправочникСписок.Отбор.СотрудникОсновнойОрганизации.Значение = Истина;
            СправочникСписок.Отбор.СотрудникОсновнойОрганизации.Использование = Истина;
        Исключение
            // Обработка случая, если реквизита не существует в списке
        КонецПопытки;
    КонецЕсли;
КонецПроцедуры

Важный нюанс: В обычных формах свойство Использование определяет, активен ли данный элемент отбора в текущий момент.

Способ 2: Универсальная проверка всех отборов (рекомендуемый)

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


Процедура ПриОткрытии()
    ЕстьУстановленныйОтбор = Ложь;
    
    // Перебираем все возможные поля отбора в списке
    Для Каждого ЭлементОтбора Из СправочникСписок.Отбор Цикл
        Если ЭлементОтбора.Использование Тогда
            ЕстьУстановленныйОтбор = Истина;
            Прервать;
        КонецЕсли;
    КонецЦикла;

    // Если ни один отбор не используется, накладываем свой
    Если Не ЕстьУстановленныйОтбор Тогда
        // Установка фильтра по флагу "Активный"
        Если СправочникСписок.Отбор.Найти("Активный") <> Неопределено Тогда
            СправочникСписок.Отбор.Активный.Значение = Истина;
            СправочникСписок.Отбор.Активный.Использование = Истина;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Этот метод хорош тем, что он «устойчив» к изменениям метаданных. Если в справочник добавят новый реквизит и пользователь установит по нему отбор, наш код корректно это определит и не будет навязывать стандартный фильтр.

Способ 3: Проверка контекста открытия через владельца

Иногда проверка только коллекции Отбор недостаточна. Форма может открываться для выбора в поле документа. В этом случае свойство ЭтаФорма.Владелец будет заполнено. Проанализируем, как это использовать:


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

Оптимизация производительности: почему «сложные» отборы — это плохо

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

Рекомендуемое решение:

  1. Добавить в справочник реальный реквизит типа Булево (например, ИспользуетсяВУчете).
  2. Сделать этот реквизит индексированным.
  3. Написать регламентное задание, которое раз в сутки (или чаще) анализирует наличие оборотов/договоров и проставляет этот флаг.
  4. В форме списка устанавливать отбор именно по этому индексированному полю.

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

Альтернатива: Использование RLS

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

В таких случаях следует использовать RLS (Restriction at Leaf Level) — механизм ограничения доступа на уровне записей. Это позволит скрыть данные на уровне запроса к базе данных, и они исчезнут не только из форм списка, но и из отчетов, и из подборов. Однако помните, что RLS может существенно снизить общую производительность системы.

Подведение итогов

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

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

← На главную