Как правильно реализовать отбор в форме выбора 1С по нескольким условиям?

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

Часто при разработке на платформе 1С возникает задача ограничить выбор элементов справочника в форме выбора для конкретного пользователя. Например, нам нужно, чтобы начальник видел только сотрудников тех подразделений, которые закреплены за ним. При попытке реализовать это через циклы и стандартные методы отбора начинающие разработчики часто сталкиваются с тем, что отбор применяется некорректно — фильтрация работает либо только по последнему элементу, либо вовсе не срабатывает. Рассмотрим, в чем кроется ошибка и как сделать это правильно.

Разбор типичной ошибки

Основная проблема, с которой сталкиваются разработчики, заключается в двух моментах:

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

Для корректной работы нам необходимо использовать вид сравнения ВидСравненияКомпоновкиДанных.ВСписке. Это позволит системе понять, что поле Должность должно проверяться на вхождение в переданный нами список, а не сравниваться с одним объектом.

Пошаговое решение задачи

Давайте перестроим наш подход. Вместо перебора массива в цикле, мы подготовим один СписокЗначений и передадим его в отбор динамического списка один раз.

Шаг 1: Подготовка данных на сервере. Сформируем функцию, которая возвращает список необходимых подразделений (в вашем случае — должностей).


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

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


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

Почему это работает лучше?

Использование ВидСравненияКомпоновкиДанных.ВСписке и передача СписокЗначений в ПравоеЗначение заставляет систему компоновки данных (СКД) автоматически сформировать условие ГДЕ Должность В (&Параметр) в запросе динамического списка. Это наиболее производительный способ фильтрации данных в 1С.

Советы по оптимизации:

Применяя этот подход, вы избавитесь от ошибок, связанных с очисткой элементов отбора и некорректным сравнением, а ваш код станет чище и профессиональнее.

← На главную