Как определить вызывающую форму в событии ОбработкаПолученияДанныхВыбора для фильтрации списка

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

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

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

Суть проблемы и анализ стандартных механизмов

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


Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
    // Здесь мы должны сформировать список ДанныеВыбора
КонецПроцедуры

Параметр Параметры имеет тип Структура. По умолчанию он содержит такие ключи, как СтрокаПоиска, ВыборГруппИЭлементов, СпособПоиска и Отбор. Но в нем отсутствует информация о владельце формы или имени самой формы. Если нам нужно запретить выбор определенной группы номенклатуры только для «Документа А», но разрешить для «Документа Б», нам необходимо найти способ «пробросить» идентификатор документа в эту структуру.

Решение №1: Программная установка параметров выбора через БСП

Если конфигурация построена на базе ERP, КА 2 или УТ 11, мы можем воспользоваться механизмом переопределения событий форм. Это самый элегантный способ, позволяющий избежать модификации сотен объектов метаданных. Мы внедрим логику в общие модули, которые отвечают за создание форм.

Рассмотрим по шагам, как это реализовать:

  1. Найдем в конфигурации общий модуль, отвечающий за создание форм на сервере (например, МодификацияКонфигурацииПереопределяемый или специализированные модули БСП типа СобытияФорм).
  2. Используем механизм расширений, чтобы перехватить событие ПриСозданииНаСервере.
  3. Внутри обработчика проанализируем элементы формы и добавим в ПараметрыВыбора нужный нам контекст.

Проанализируем пример кода для расширения общего модуля:


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

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

Решение №2: Обработка параметров в модуле менеджера

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

В модуле менеджера справочника Номенклатура (лучше также через расширение) модифицируем процедуру ОбработкаПолученияДанныхВыбора:


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

КонецПроцедуры

Решение №3: Использование «Связей параметров выбора»

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

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

Алгоритм настройки:

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

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

Важные рекомендации по производительности

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

Резюме

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

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

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

← На главную