Как ограничить выбор элементов в табличной части на обычных формах 1С?

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

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

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

Почему не работают параметры выбора на обычных формах?

Проанализируем архитектурные различия платформ:

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

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

Способ 1. Программное открытие формы выбора с отбором

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

Разберем по шагам реализацию этого способа:

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

Посмотрим на пример кода в модуле формы документа:


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

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

Способ 2. Использование режима выбора из списка (выпадающий список)

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

Разберем по шагам настройку динамического формирования списка:

  1. В свойствах колонки табличного поля включаем флаг РежимВыбораИзСписка.
  2. Создаем обработчик события НачалоВыбораИзСписка для нужной колонки табличного поля.
  3. Формируем запрос к базе данных и заполняем коллекцию СписокВыбора подходящими значениями.

Посмотрим на пример реализации заполнения выпадающего списка:


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

Важный нюанс производительности: заполняйте СписокВыбора именно в событии НачалоВыбораИзСписка, а не в событии ПриАктивизацииСтроки. Это исключит лишние запросы к базе данных при обычном перемещении курсора по строкам документа.

Способ 3. Контроль ввода с клавиатуры и защита данных

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

Для ограничения подбора по строке на обычной форме переопределяют события поля ввода:

  1. В событии АвтоПодборТекста фильтруют входящий текст.
  2. В событии ОкончаниеВводаТекста устанавливают СтандартнаяОбработка = Ложь, самостоятельно находят подходящие элементы запросом с учетом условий и передают массив найденных ссылок в параметр Значение.

Для окончательной валидации данных используем событие табличной части ПриИзменении или проверку на стороне объекта:


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

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

← На главную