Как программно настроить фильтр контактных лиц по контрагенту в 1С:УНФ

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет
← На главную

При разработке в среде 1С:Предприятие 8.3, особенно в конфигурации 1С:Управление нашей фирмой (УНФ), программисты часто сталкиваются с задачей ограничения выбора данных в зависимости от значения других реквизитов. Типичный пример: при выборе контактного лица в документе или справочнике необходимо показывать только те контакты, которые непосредственно связаны с уже выбранным контрагентом.

В этой статье мы подробно разберем, почему стандартные механизмы платформы «Связи параметров выбора» могут не работать в данном случае, и реализуем программный метод решения задачи с использованием событий формы и расширений.

Анализ архитектурных особенностей 1С:УНФ

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

Выясним причину, по которой стандартный метод не работает: в УНФ связь между контрагентом и контактным лицом реализована через механизм регистров сведений (в частности, регистр СвязиКонтрагентов). Это позволяет одному и тому же контактному лицу быть связанным с несколькими контрагентами одновременно. Поскольку прямой иерархической связи (владелец-подчиненный) нет, платформа не может автоматически отфильтровать список по владельцу.

Программная фильтрация через событие НачалоВыбора

Рассмотрим основной способ решения задачи — перехват процесса выбора через программный код. Нам необходимо выполнить следующие шаги:

  1. Отменить стандартное открытие формы выбора.
  2. Сформировать собственные параметры отбора.
  3. Открыть форму выбора программно с этими параметрами.
  4. Обработать результат выбора.

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


&НаКлиенте
Процедура Расш1_КонтактноеЛицоНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)

    // Останавливаем стандартное открытие формы, чтобы не открылось два окна
    СтандартнаяОбработка = Ложь;

    // Подготавливаем структуру отбора
    ПараметрыОтбора = Новый Структура;
    ПараметрыОтбора.Вставить("Контрагент", Объект.Контрагент);

    // Формируем параметры открытия формы
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора);
    ПараметрыФормы.Вставить("РежимВыбора", Истина);
    ПараметрыФормы.Вставить("МножественныйВыбор", Ложь);

    // Указываем, какую процедуру вызвать после выбора значения
    ОбработкаВыбора = Новый ОписаниеОповещения("ПриЗакрытииФормыВыбораКонтактногоЛица", ЭтаФорма);

    // Открываем форму выбора справочника КонтактныеЛица
    ОткрытьФорму("Справочник.КонтактныеЛица.ФормаВыбора", ПараметрыФормы, Элемент, , , , ОбработкаВыбора);

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

Обработка результата выбора

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


&НаКлиенте
Процедура ПриЗакрытииФормыВыбораКонтактногоЛица(Значение, ДопПараметры) Экспорт

    // Если пользователь закрыл форму без выбора, значение будет Неопределено
    Если Значение = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Присваиваем выбранное значение реквизиту объекта
    Объект.КонтактноеЛицо = Значение;

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

Почему важно устанавливать СтандартнаяОбработка = Ложь?

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

Использование этого флага — критически важный момент при работе с событиями НачалоВыбора, ОбработкаПроверкиЗаполнения и другими интерактивными действиями в 1С.

Дополнительная настройка автоподбора

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

В этом событии мы также можем передать параметры отбора. Рассмотрим пример:


&НаКлиенте
Процедура КонтактноеЛицоАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, СтандартнаяОбработка)
    
    // Добавляем контрагента в параметры получения данных
    ПараметрыПолученияДанных.Отбор.Вставить("Контрагент", Объект.Контрагент);
    
КонецПроцедуры

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

Рекомендации по работе с расширениями

Если вы реализуете данную задачу в расширении для 1С:Управление нашей фирмой, старайтесь использовать аннотацию &Вместо для события НачалоВыбора только в крайнем случае, чтобы не нарушить работу типовых механизмов (например, если там заложен сложный расчет доступных контактов). Предпочтительнее использовать &НаКлиенте на созданный вручную обработчик события элемента формы в расширении.

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

← На главную