Как наложить произвольный фильтр на правое значение в стандартном отборе СКД на управляемой форме?

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

Разработка интерфейсов на управляемых формах в платформе «1С:Предприятие 8.3» предоставляет мощные механизмы для работы с динамическими списками и Системой компоновки данных (СКД). Одним из стандартных и наиболее удобных элементов управления является таблица отборов компоновщика настроек. Выводя свойство Отбор на управляемую форму, мы предоставляем пользователям гибкий инструмент для фильтрации данных.

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

В чем сложность стандартного механизма?

Когда мы перетаскиваем свойство Отбор динамического списка или компоновщика настроек на форму, платформа автоматически генерирует таблицу элементов. По умолчанию для этой таблицы включено свойство Автозаполнение колонок. В таком режиме дерево элементов формы не содержит явных полей ввода для значений отбора — они создаются динамически «на лету» в процессе отрисовки интерфейса платформой.

Из-за этого разработчик сталкивается со следующими трудностями:

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

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

Шаг 1. Отключение автозаполнения колонок таблицы отбора

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

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

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

Шаг 2. Динамическое подключение обработчика событий

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

Проанализируем программный код, который решает эту задачу. В модуле формы в процедуре ПриСозданииНаСервере мы найдем элемент управления правого значения и назначим ему обработчик с помощью метода УстановитьДействие.

Рассмотрим пример реализации:


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

Использование метода УстановитьДействие позволяет нам динамически «пришить» процедуру-обработчик к событию элемента формы, даже если само поле генерируется сложными механизмами платформы.

Шаг 3. Обработка события «НачалоВыбора» на клиенте

Теперь напишем непосредственно сам обработчик события на клиенте. В этой процедуре нам предстоит выполнить три ключевых действия:

  1. Определить, на какой строке таблицы отборов находится пользователь и по какому именно полю компоновки (левому значению) происходит выбор.
  2. Если это интересующее нас поле (например, «Контрагент» или «Склад»), то мы должны отменить стандартную обработку выбора платформы, установив параметр СтандартнаяОбработка = Ложь.
  3. Сформировать структуру параметров для ограничения выбора и открыть нужную нам форму с наложенными фильтрами.

Проанализируем пример кода клиентской процедуры:


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

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

Важные нюансы и подводные камни

При реализации данного механизма разработчики часто сталкиваются с неочевидными особенностями работы платформы 1С. Рассмотрим их подробнее и разберем способы решения.

1. Проблема «Истории выбора» при вводе текста

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

Чтобы исключить эту проблему, рекомендуется отключать историю выбора для данного поля. Сделать это можно в процедуре инициализации на сервере:


Элементы.КомпоновщикНастроекНастройкиОтборЗначение.ИсторияВыбораПриВводе = ИсторияВыбораПриВводе.НеИспользовать;

2. Проблема сравнения типа «В списке» (Список значений)

Если пользователь в таблице отборов меняет вид сравнения с «Равно» на «В списке» или «Не в списке», тип данных в колонке правого значения динамически меняется платформой на СписокЗначений. В этот момент стандартное поведение интерактивного выбора меняется: открывается окно редактирования списка значений.

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

3. Альтернатива: Обработка получения данных выбора в менеджере

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

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

Резюме

Мы подробно изучили технологию гибкого управления выбором значений в стандартной таблице отбора СКД на управляемых формах. Отключение автозаполнения колонок открывает нам доступ к реквизитам элементов формы, а метод УстановитьДействие позволяет элегантно переопределить логику кнопки выбора. Применяя данные практики, вы сможете создавать максимально удобные и защищенные от ошибок пользователей интерфейсы.

← На главную