Как реализовать фильтр списка контрагентов в 1С:УТ 10.3 при выборе на форме

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

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

Метод 1. Программная установка отбора в событии НачалоВыбора

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

Для начала нам необходимо создать обработчик события НачалоВыбора для поля ввода на форме. В этом обработчике мы напишем код для настройки формы выбора. Разберем пример реализации:


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

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


ФормаВыбора.ЭлементыФормы.СправочникСписок.Отбор.Родитель.Установить(НужныйРодитель);

Метод 2. Ограничение навигации через РодительВерхнегоУровня

Если нам нужно не просто «показать» элементы определенной группы, но и запретить пользователю выходить за её пределы (например, нажимать кнопку «Вверх» и выбирать других контрагентов), следует использовать свойство РодительВерхнегоУровня. Этот метод делает выбранную папку «корневой» для пользователя в момент выбора.

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


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

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

Метод 3. Использование отбора «В иерархии»

Бывают ситуации, когда в целевой папке (например, «БРАК») есть подпапки. Если использовать простой отбор по родителю с видом сравнения Равно, программа покажет только те элементы, которые лежат непосредственно в корне папки. Чтобы увидеть всех контрагентов, включая вложенные папки, проанализируем использование вида сравнения ВИерархии.


ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВИерархии;
ФормаВыбора.Отбор.Ссылка.Значение = НужныйРодитель;
ФормаВыбора.Отбор.Ссылка.Использование = Истина;

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

Метод 4. Подмена списка выбора (ComboBox)

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


// Пример заполнения списка выбора
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Контрагенты.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    |   Контрагенты.Родитель = &Родитель";

Запрос.УстановитьПараметр("Родитель", Справочники.Контрагенты.НайтиПоНаименованию("БРАК СПИСАНИЕ"));
Результат = Запрос.Выполнить().Выгрузить();

Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(Результат.ВыгрузитьКолонку("Ссылка"));

ЭлементыФормы.КонтрагентСписания.СписокВыбора = Список;
ЭлементыФормы.КонтрагентСписания.РежимВыбораИзСписка = Истина;

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

Недостаток: Если контрагентов в группе сотни, такой список станет неудобным и будет долго подгружаться.

Рекомендации по поиску родителя

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

  1. Риск переименования: Если пользователь переименует папку «БРАК СПИСАНИЕ» в «Брак для утилизации», код перестанет работать.
  2. Дубли: В справочнике может быть две папки с одинаковым названием в разных ветках.

Как делать правильно:

Подводя итог, выбор метода зависит от бизнес-задачи. Если нужно строго ограничить область видимости — используйте РодительВерхнегоУровня. Если нужно просто подсказать пользователю нужную папку, но оставить свободу действий — используйте Отбор.Родитель в событии НачалоВыбора.

← На главную