Разработка интерфейсов на управляемых формах в платформе «1С:Предприятие 8.3» предоставляет мощные механизмы для работы с динамическими списками и Системой компоновки данных (СКД). Одним из стандартных и наиболее удобных элементов управления является таблица отборов компоновщика настроек. Выводя свойство Отбор на управляемую форму, мы предоставляем пользователям гибкий инструмент для фильтрации данных.
Однако на практике часто возникает классическая задача: необходимо ограничить выбор в колонке «Правое значение» (колонке «Значение») определенным условием. Например, если пользователь выбирает отбор по полю «Контрагент», в форме выбора должны отображаться только активные контрагенты, либо контрагенты конкретного региона. Стандартное поведение платформы по умолчанию предлагает выбор из всего справочника-источника без каких-либо ограничений. В этой статье мы подробно разберем, как решить данную задачу программными средствами управляемой формы.
Когда мы перетаскиваем свойство Отбор динамического списка или компоновщика настроек на форму, платформа автоматически генерирует таблицу элементов. По умолчанию для этой таблицы включено свойство Автозаполнение колонок. В таком режиме дерево элементов формы не содержит явных полей ввода для значений отбора — они создаются динамически «на лету» в процессе отрисовки интерфейса платформой.
Из-за этого разработчик сталкивается со следующими трудностями:
НачалоВыбора.Для обхода этих ограничений мы применим элегантное программное решение, основанное на управлении структурой элементов формы и динамическом назначении обработчиков событий.
Первым делом нам необходимо сделать структуру таблицы отборов статической, чтобы иметь возможность напрямую обратиться к ее элементам из кода. Выполним следующие действия:
КомпоновщикНастроекНастройкиОтбор или СписокОтбор).КомпоновщикНастроекНастройкиОтборЗначение (или аналогичное поле с именем правого значения).Теперь, когда поле правого значения зафиксировано в метаданных формы, мы можем взаимодействовать с ним программно.
Для того чтобы перехватить момент нажатия пользователем на кнопку выбора в поле значения, нам потребуется привязать к этому полю обработчик события НачалоВыбора. Сделать это лучше всего при инициализации формы на сервере.
Проанализируем программный код, который решает эту задачу. В модуле формы в процедуре ПриСозданииНаСервере мы найдем элемент управления правого значения и назначим ему обработчик с помощью метода УстановитьДействие.
Рассмотрим пример реализации:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Определяем имя элемента формы, отвечающего за ввод правого значения.
// Обратите внимание: имя элемента зависит от того, как называется ваш реквизит на форме.
ИмяЭлементаЗначения = "КомпоновщикНастроекНастройкиОтборЗначение";
Если Элементы.Найти(ИмяЭлементаЗначения) <> Неопределено Тогда
// Подключаем клиентский обработчик события "НачалоВыбора"
Элементы[ИмяЭлементаЗначения].УстановитьДействие("НачалоВыбора", "ОтборПравоеЗначениеНачалоВыбора");
КонецЕсли;
КонецПроцедуры
Использование метода УстановитьДействие позволяет нам динамически «пришить» процедуру-обработчик к событию элемента формы, даже если само поле генерируется сложными механизмами платформы.
Теперь напишем непосредственно сам обработчик события на клиенте. В этой процедуре нам предстоит выполнить три ключевых действия:
СтандартнаяОбработка = Ложь.Проанализируем пример кода клиентской процедуры:
&НаКлиенте
Процедура ОтборПравоеЗначениеНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
// Получаем текущую строку из таблицы отборов
ТекущиеДанные = Элементы.КомпоновщикНастроекНастройкиОтбор.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Свойство "ЛевоеЗначение" имеет системный тип "ПолеКомпоновкиДанных".
// Преобразуем его в строку для удобства анализа имени поля.
ИмяПоляОтбора = Строка(ТекущиеДанные.ЛевоеЗначение);
// Проверяем, для какого поля мы хотим переопределить форму выбора
Если ИмяПоляОтбора = "Контрагент" Тогда
// Отключаем стандартный диалог выбора, предоставляемый платформой
СтандартнаяОбработка = Ложь;
// Настраиваем параметры открытия формы выбора контрагентов
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("РежимВыбора", Истина);
// Формируем отбор для формы выбора.
// Например, нам нужно отображать только юридические лица
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("ЮридическоеФизическоеЛицо", ПредопределенноеЗначение("Перечисление.ЮридическоеФизическоеЛицо.ЮридическоеЛицо"));
ПараметрыФормы.Вставить("Отбор", СтруктураОтбора);
// Открываем форму выбора справочника, передавая Элемент в качестве владельца.
// Это гарантирует, что выбранное значение автоматически вернется в активную ячейку.
ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", ПараметрыФормы, Элемент);
КонецЕсли;
КонецПроцедуры
Данный подход является чрезвычайно гибким. Мы можем накладывать любые, даже самые сложные динамические фильтры, зависящие от других реквизитов текущей формы, времени суток или прав текущего пользователя.
При реализации данного механизма разработчики часто сталкиваются с неочевидными особенностями работы платформы 1С. Рассмотрим их подробнее и разберем способы решения.
1. Проблема «Истории выбора» при вводе текста
Перехват события НачалоВыбора отлично работает, когда пользователь нажимает на кнопку с троеточием («педальку»). Однако, если пользователь начинает вводить текст в ячейку правого значения клавиатурой, платформа может предложить ему список быстрого выбора из истории ранее выбиравшихся значений. Эта история не знает о наших программных фильтрах и может содержать неподходящие элементы.
Чтобы исключить эту проблему, рекомендуется отключать историю выбора для данного поля. Сделать это можно в процедуре инициализации на сервере:
Элементы.КомпоновщикНастроекНастройкиОтборЗначение.ИсторияВыбораПриВводе = ИсторияВыбораПриВводе.НеИспользовать;
2. Проблема сравнения типа «В списке» (Список значений)
Если пользователь в таблице отборов меняет вид сравнения с «Равно» на «В списке» или «Не в списке», тип данных в колонке правого значения динамически меняется платформой на СписокЗначений. В этот момент стандартное поведение интерактивного выбора меняется: открывается окно редактирования списка значений.
При этом стандартный механизм платформы «Связи параметров выбора» перестает корректно отрабатывать. В случае программного перехвата события НачалоВыбора вам также потребуется предусмотреть ветвление в коде: если тип текущего значения в строке отбора равен типу СписокЗначений, необходимо открывать не стандартную форму выбора справочника, а форму подбора или специализированное диалоговое окно для работы со списком значений, транслируя туда ваши фильтры.
3. Альтернатива: Обработка получения данных выбора в менеджере
Если перед вами стоит задача ограничить выбор элементов определенного типа абсолютно везде в рамках конфигурации (не только на этой конкретной управляемой форме, но и при любых отборах в отчетах, динамических списках документов и т.д.), то лучшим решением будет перенос логики фильтрации на уровень бизнес-логики.
Для этого используется обработчик события ОбработкаПолученияДанныхВыбора в модуле менеджера соответствующего объекта метаданных (например, справочника Контрагенты). Этот метод вызывается платформой каждый раз, когда запрашиваются данные для автоподбора или интерактивного выбора, в том числе и из настроек компоновщика СКД. Внутри этого обработчика вы можете программно модифицировать параметры запроса и накладывать жесткие фильтры на уровне сервера.
Мы подробно изучили технологию гибкого управления выбором значений в стандартной таблице отбора СКД на управляемых формах. Отключение автозаполнения колонок открывает нам доступ к реквизитам элементов формы, а метод УстановитьДействие позволяет элегантно переопределить логику кнопки выбора. Применяя данные практики, вы сможете создавать максимально удобные и защищенные от ошибок пользователей интерфейсы.