Как настроить выбор договора контрагента с определенным условием в 1С

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

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

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

Метод 1. Использование свойства «Параметры выбора» в метаданных

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

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

Преимущества: скорость настройки и отсутствие кода.

Недостатки: невозможность реализовать сложную логику (например, если условие зависит от даты документа или других динамических параметров).

Метод 2. Программная установка параметров выбора в форме

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

Проанализируем пример кода, который устанавливает жесткий фильтр для элемента формы. Для быстрой проверки свойств можно редактировать свойства элементов прямо в режиме предприятия:


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

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

Метод 3. Ограничение через динамический список формы выбора

Иногда разработчики решают задачу путем модификации самой формы выбора справочника ДоговорыКонтрагентов. В этом случае в динамическом списке формы устанавливается произвольный запрос с условием ГДЕ или настраивается отбор в настройках компоновки данных. Существуют различные методы доработки динамических списков для таких задач.

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

Чтобы этого избежать, при использовании кастомных форм выбора необходимо также назначать эту форму в свойство реквизита Форма выбора или программно через Событие НачалоВыбора.

Метод 4. Обработка получения данных выбора (Модуль менеджера)

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

Разберем алгоритм работы этого метода:

  1. Система обращается к менеджеру справочника за данными.
  2. Мы перехватываем этот запрос.
  3. Анализируем параметры (например, мы можем передать в параметрах структуру, указывающую на необходимость фильтрации).
  4. Добавляем условия в отбор.

Пример кода в модуле менеджера:


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

Метод 5. Серверная валидация (Золотой стандарт)

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

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


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

Использование механизмов БСП

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

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

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

← На главную