Как программно установить отбор в форме выбора справочника на обычных формах 1С 8.3?

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

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

Постановка задачи и выбор стратегии

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

  1. Объект Запрос — для получения ссылок на нужные должности (например, по коду или наименованию).
  2. Объект СписокЗначений — если должностей несколько, фильтр должен работать по условию «В списке».
  3. Свойство Отбор формы выбора — основной механизм фильтрации списка.

Шаг 1: Получение нужных данных через запрос

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


// Создаем запрос для получения ссылок на должности
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Должности.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Должности КАК Должности
    |ГДЕ
    |	Должности.Код В (&КодыДолжностей)";

// Передаем массив кодов в параметры запроса
МассивКодов = Новый Массив;
МассивКодов.Добавить("000000002");
МассивКодов.Добавить("000000003");
Запрос.УстановитьПараметр("КодыДолжностей", МассивКодов);

Выборка = Запрос.Выполнить().Выбрать();

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

Проанализируем этот фрагмент: мы используем запрос к базе данных, чтобы получить именно ссылки (объекты типа СправочникСсылка.Должности). Это критически важно, так как отбор в списке работает по ссылочным типам, а не по строковым названиям.

Шаг 2: Программное открытие формы и установка отбора

Теперь нам нужно получить форму выбора справочника Сотрудники и применить к ней наш список значений. Рассмотрим правильный способ обращения к свойствам формы в обычном приложении.


// Получаем форму выбора
ФормаВыбора = Справочники.Сотрудники.ПолучитьФормуВыбора("ФормаВыбора", ЭтаФорма);

// Настраиваем отбор по реквизиту "Должность"
// Используем переменную "ОтборСписка", чтобы избежать конфликта имен
ОтборСписка = ФормаВыбора.Отбор;

Если СписокДолжностей.Количество() > 0 Тогда
    ОтборСписка.Должность.ВидСравнения = ВидСравнения.ВСписке;
    ОтборСписка.Должность.Значение = СписокДолжностей;
    ОтборСписка.Должность.Использование = Истина;
КонецЕсли;

// Открываем форму и получаем выбранное значение
ВыбранноеЗначение = ФормаВыбора.ОткрытьМодально();

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

Шаг 3: Ограничение работы отбора конкретной формой

Часто возникает вопрос: как сделать так, чтобы этот отбор срабатывал не всегда, а только при вызове из определенного документа? Рассмотрим три способа решения этой задачи:

1. Использование события «НачалоВыбора»

Разместим наш код непосредственно в модуле формы документа в обработчике события поля ввода. В этом случае логика отбора будет инкапсулирована внутри конкретной формы документа и не затронет другие части системы.

2. Проверка владельца формы

В самой форме выбора справочника (в событии ПередОткрытием) мы можем проверить, кто инициировал открытие. Проанализируем пример кода:


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

3. Передача параметров через структуру

Мы можем передать в форму выбора специальный параметр, указывающий на необходимость фильтрации. Это наиболее гибкий метод, позволяющий управлять поведением формы выбора извне без жесткой привязки к типам объектов.

Оптимизация и безопасность кода

При реализации отборов важно помнить о производительности и стабильности системы. Рассмотрим несколько рекомендаций:

Альтернатива: Связи параметров выбора

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

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

← На главную