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

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

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

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

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

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

Давайте рассмотрим самый простой и распространенный способ. Если основной реквизит формы выбора является динамическим списком (что верно для 99% случаев в управляемом приложении), платформа автоматически попытается применить переданную структуру отбора к этому списку.

Разберем пример кода, где мы открываем форму выбора справочника "Номенклатура" и хотим видеть только товары определенного вида:


// Создаем структуру параметров формы
ПараметрыФормы = Новый Структура;

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

// Вставляем отбор в параметры формы
ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора);

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

В данном примере мы выполнили следующие действия:

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

Этот метод отлично работает для простых равенств (когда поле равно значению). Однако, давайте посмотрим глубже: что делать, если условия отбора сложнее?

Сложные отборы: Использование фиксированных настроек

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

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

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

Шаг 1. Код в месте вызова (на клиенте):


ПараметрыФормы = Новый Структура;
// Передаем список складов, по которым хотим фильтровать
ПараметрыФормы.Вставить("СписокСкладовДляОтбора", МойСписокСкладов);

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

Шаг 2. Код в модуле формы выбора (событие ПриСозданииНаСервере):

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


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

КонецПроцедуры

Давайте проанализируем, почему мы используем именно ФиксированныеНастройки. В динамическом списке есть основные настройки (которые может менять пользователь через "Еще - Настроить список") и фиксированные. Фиксированные настройки применяются поверх пользовательских и имеют приоритет (логическое "И"). Это гарантирует, что пользователь случайно не отключит наш программный фильтр.

Особенности работы с владельцем формы

Еще один важный сценарий — фильтрация по владельцу. Если мы открываем справочник, подчиненный другому справочнику (например, "ДоговорыКонтрагентов", подчиненный "Контрагенты"), нам часто нужно показать договоры только конкретного контрагента.

В этом случае платформа 1С предоставляет удобный штатный механизм. Нам не нужно писать сложный код с компоновщиком настроек. Достаточно использовать стандартные параметры формы.

Разберем пример открытия формы выбора договоров:


ПараметрыФормы = Новый Структура;
// Параметр "Отбор" работает как фильтр по реквизитам
ПараметрыФормы.Вставить("Отбор", Новый Структура("Владелец", СсылкаНаКонтрагента));

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

ОткрытьФорму("Справочник.ДоговорыКонтрагентов.ФормаВыбора", ПараметрыФормы, Элемент);

Обратите внимание: если вы используете параметр Отбор по полю "Владелец", то при создании нового элемента из этой формы выбора, поле "Владелец" заполнится автоматически. Это значительно упрощает работу пользователя.

Использование связей параметров выбора

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

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

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

Это работает автоматически и не требует вызова ОткрытьФорму.

Подводные камни и частые ошибки

Проанализируем типичные ошибки, которые возникают при реализации отборов:

Резюме

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

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

Используйте эти подходы комбинированно, в зависимости от сложности бизнес-логики вашего приложения.

← На главную