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

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

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

Проблема системных диалогов и динамических элементов

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

Способ 1. Программное назначение обработчика через УстановитьДействие

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

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


&НаСервере
Процедура КомпоновщикНастроекУстановитьДействияНаСервере()
    
    ИмяЭлементаОтбор = "";
    
    // Ищем основной элемент управления отборами на форме
    Для Каждого Элемент Из Элементы Цикл
        // Платформа генерирует имена для групп отборов, часто они содержат слово "Отбор"
        Если Прав(Элемент.Имя, 5) = "Отбор" Тогда 
            ИмяЭлементаОтбор = Элемент.Имя;
            Прервать;
        КонецЕсли;
    КонецЦикла;

    Если ПустаяСтрока(ИмяЭлементаОтбор) Тогда
        Возврат;
    КонецЕсли;

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

Теперь рассмотрим клиентскую часть. Нам нужно описать процедуру ОтборНачалоВыбора, которая будет срабатывать при нажатии кнопки выбора. В этой процедуре мы можем проверить, какой именно отбор сейчас редактируется, и, если условие совпадает (например, вид сравнения — «В списке»), открыть свою форму подбора.


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

Способ 2. Использование модуля менеджера для глобального перехвата

Если задача стоит шире — например, нужно, чтобы при выборе определенного типа данных (скажем, «Контрагенты») в любом месте системы (включая настройки динамических списков) открывалась специальная форма, — лучше использовать возможности модуля менеджера объекта. Выясним причину, почему это удобно: такой подход работает даже в тех системных диалогах, где мы не можем программно дотянуться до элементов формы.

В модуле менеджера справочника или документа можно использовать обработчик ОбработкаПолученияФормыВыбора. Рассмотрим пример:


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

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

Способ 3. Настройка параметров выбора в схеме компоновки данных (СКД)

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

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

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

Реализация кастомного подбора значений списком

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


&НаКлиенте
Процедура ОткрытьСвоюФормуПодбора(СтрокаОтбора, Элемент)
    
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("Отмеченные", СтрокаОтбора.ПравоеЗначение);
    ПараметрыОткрытия.Вставить("ОписаниеТипов", СтрокаОтбора.ПравоеЗначение.ТипЗначения);
    ПараметрыОткрытия.Вставить("Представление", "Выберите значения для отбора: " + СтрокаОтбора.ЛевоеЗначение);
    
    ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗакрытияФормыПодбора", ЭтотОбъект, СтрокаОтбора);
    
    ОткрытьФорму("ОбщаяФорма.ВводЗначенийСпискомСФлажками", ПараметрыОткрытия, ЭтотОбъект, , , , ОписаниеОповещения);
    
КонецПроцедуры

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

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

Выводы и рекомендации

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

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

← На главную