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