Как программно установить динамический отбор на форме выбора элементов в 1С:Предприятии 8.3?

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

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

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

Общий подход: Передача параметров в форму выбора

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

Рассмотрим по шагам, как это выглядит:

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

Настройка отбора в открываемой форме (обработчик ПриСозданииНаСервере)

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

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

Разберем по шагам работу с динамическим списком:

  1. Проверка наличия переданных параметров: В обработчике ПриСозданииНаСервере прежде всего необходимо убедиться, что нужные параметры были переданы в форму. Это можно сделать с помощью метода Параметры.Свойство("ИмяПараметра").
  2. Очистка существующего отбора: Перед тем как добавлять свои условия отбора, рекомендуется очистить текущий отбор динамического списка. Это предотвратит наложение отборов, установленных пользователем ранее или другими частями программы. Для этого используем метод Список.Отбор.Элементы.Очистить().
  3. Добавление нового элемента отбора: Для каждого условия отбора нам потребуется создать новый элемент отбора. Мы добавляем его в коллекцию с помощью метода Добавить(), указывая тип Тип("ЭлементОтбораКомпоновкиДанных").
    
    ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    
  4. Установка левого значения (поля для отбора): Определяем, по какому полю справочника или документа будет производиться отбор. Это поле указывается с помощью объекта ПолеКомпоновкиДанных. ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ИмяПоляСправочника");

    Например, если мы хотим отбирать по контрагенту, который является реквизитом справочника "Номенклатура", то указываем Новый ПолеКомпоновкиДанных("Контрагент").

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

Примеры кода для реализации

Давайте рассмотрим конкретный сценарий: у нас есть документ "Счет покупателя", и при выборе элемента справочника "Номенклатура" нам нужно показывать только те позиции, которые относятся к контрагенту, указанному в текущем документе.

Пример 1: Вызов формы выбора с параметрами (из модуля формы документа)

Допустим, на форме документа "СчетПокупателя" есть поле Номенклатура, и при его выборе мы хотим открыть форму выбора справочника "Номенклатура" с отбором по контрагенту из текущего документа. Мы будем использовать обработчик события поля ввода.

В модуле формы документа (например, в обработчике события НоменклатураПриНачалеВыбора или НоменклатураОбработкаВыбора для поля ввода Номенклатура):


&НаКлиенте
Процедура НоменклатураПриНачалеВыбора(Элемент, СтандартнаяОбработка)
    // Отменяем стандартную обработку выбора, чтобы открыть свою форму
    СтандартнаяОбработка = Ложь;

    // Получаем контрагента из текущего объекта документа
    // Предполагаем, что реквизит "Контрагент" существует в Объекте документа
    КонтрагентДляОтбора = Объект.Контрагент; 

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

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

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

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

// Если требуется обработать результат выбора после закрытия формы, 
// можно использовать событие ОбработкаВыбора, но при открытии формы
// через ОткрытьФорму с третьим параметром, результат выбора возвращается автоматически
// в элемент, вызвавший открытие формы.

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

Пример 2: Обработка параметров и установка отбора (в модуле формы выбора справочника)

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

В модуле формы справочника Справочник.Номенклатура.ФормаВыбора:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    // Проверяем, были ли переданы параметры с именем "КонтрагентДляОтбора"
    Если Параметры.Свойство("КонтрагентДляОтбора") Тогда
        // Получаем значение контрагента из переданных параметров
        ЗначениеКонтрагентаДляОтбора = Параметры.КонтрагентДляОтбора;

        // Важно: Сначала очищаем существующий отбор динамического списка.
        // Это гарантирует, что наш программный отбор будет единственным или будет иметь приоритет.
        Список.Отбор.Элементы.Очистить();

        // Добавляем новый элемент отбора в коллекцию элементов отбора динамического списка.
        // ЭлементОтбораКомпоновкиДанных - это универсальный объект для настройки отборов.
        ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

        // Устанавливаем "левое значение" - это поле, по которому будет производиться отбор.
        // Здесь мы указываем имя реквизита "Контрагент" в справочнике "Номенклатура"
        // (или имя поля, доступного через запрос динамического списка).
        ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");

        // Устанавливаем "вид сравнения" - как именно будет сравниваться поле.
        // В нашем случае нам нужно точное совпадение, поэтому используем "Равно".
        ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;

        // Устанавливаем "правое значение" - это значение, с которым будет сравниваться поле.
        // Мы используем значение, которое получили из параметров.
        ЭлементОтбора.ПравоеЗначение = ЗначениеКонтрагентаДляОтбора;

        // Активируем элемент отбора, чтобы он начал действовать.
        ЭлементОтбора.Использование = Истина;

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

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

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

Использование Библиотеки стандартных подсистем (БСП)

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

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

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

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

Таким образом, мы видим, что программная настройка отбора на форме выбора в 1С:Предприятии 8.3 — это гибкий и мощный инструмент, который позволяет адаптировать пользовательский интерфейс под конкретные бизнес-задачи и значительно повысить удобство работы пользователей.

← На главную