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

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

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

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

Понимание иерархических справочников и их структуры в 1С

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

  1. Иерархия элементов и групп: В этом случае справочник явно содержит как элементы (конечные данные), так и группы (папки для их логической организации). Группы и элементы являются разными сущностями.
  2. Иерархия элементов: В этом случае любой элемент справочника может быть родителем для других элементов, то есть нет строгого разделения на группы и элементы, любая запись может выступать в роли "папки".

Для нашей задачи важно, что в иерархическом справочнике автоматически создается стандартный реквизит Родитель. Этот реквизит имеет тип "Ссылка на справочник" и указывает на элемент или группу, которая является непосредственным родителем текущей записи. Если элемент находится в корне иерархии, значение реквизита Родитель будет пустым (Неопределено).

Еще одним важным стандартным реквизитом иерархических справочников является ЭтоГруппа. Этот булевый реквизит автоматически принимает значение Истина, если текущая запись является группой, и Ложь, если это обычный элемент. Именно эти два реквизита – Родитель и ЭтоГруппа – мы будем использовать для настройки наших отборов.

Решение 1: Настройка динамического отбора элементов по выбранной группе (реквизиту "Родитель")

Начнем с первой части задачи: обеспечение того, чтобы в Реквизите.2 отображались только элементы, принадлежащие группе, выбранной в Реквизите.1.

Использование Связей параметров выбора

Для динамического отбора в 1С существует мощный механизм — Связи параметров выбора. Этот механизм позволяет нам настроить зависимость списка выбора одного поля ввода от значения другого поля. Когда значение в "связанном" поле изменяется, система автоматически обновляет отбор в поле, для которого настроена связь.

Разберем по шагам, как настроить эту связь в конфигураторе 1С:Предприятие.

  1. Подготовка справочников и реквизитов:

    Прежде всего, убедимся, что наши справочники настроены корректно:

    • У нас есть Справочник.1 (например, "ДокументПоступления" или "ОсновнойСправочник"), в котором мы будем выбирать данные.
    • У нас есть Справочник.2 (например, "Номенклатура" или "ИерархическийСправочник"), который должен быть иерархическим. Для Справочника.2 в конфигураторе на вкладке "Основные" установите свойство "Иерархический" в значение "Элементы и группы" или "Иерархия элементов", в зависимости от вашей модели данных.

    В Справочнике.1 или в его табличной части (как в нашем случае, где реквизиты находятся в табличной части) нам понадобятся два реквизита:

    • Реквизит.1 (например, "ГруппаНоменклатуры"): Тип — "Ссылка на Справочник.2". Этот реквизит будет использоваться для выбора группы.
    • Реквизит.2 (например, "ЭлементНоменклатуры"): Тип — "Ссылка на Справочник.2". Этот реквизит будет использоваться для выбора элемента из группы.

    Давайте представим, что мы работаем с формой элемента Справочника.1 и эти реквизиты находятся на этой форме.

  2. Открытие формы и реквизита для настройки:

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

  3. Настройка параметров выбора для Реквизита.2:

    В свойствах элемента управления, связанного с Реквизитом.2 (например, поле ввода для "ЭлементНоменклатуры"), найдем свойство ПараметрыВыбора. Это коллекция, в которой мы будем добавлять условия отбора.

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

    Что мы этим сделали? Мы установили Связь параметров выбора. Теперь, когда пользователь выбирает группу в Реквизите.1, значение этой группы автоматически передается в качестве условия отбора для реквизита Родитель в списке выбора Реквизита.2. Таким образом, в списке выбора Реквизита.2 будут показаны только те элементы, у которых реквизит Родитель совпадает с выбранным значением из Реквизита.1.

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

Решение 2: Исключение групп из списка выбора Реквизита.2

Теперь перейдем ко второй части задачи: как настроить, чтобы в списке выбора Реквизита.2 не отображались группы, а только конечные элементы. Для этого мы будем использовать стандартный реквизит ЭтоГруппа.

Настройка отбора по свойству "ЭтоГруппа"

Продолжим работать со свойствами элемента управления, связанного с Реквизитом.2 (например, поле ввода для "ЭлементНоменклатуры"), в той же коллекции ПараметрыВыбора.

  1. Добавление нового параметра выбора:

    В редакторе ПараметрыВыбора (который мы открывали для настройки отбора по родителю), добавим еще один новый элемент.

  2. Настройка отбора по свойству "ЭтоГруппа":

    • В поле Параметр выбора выберем стандартный параметр Отбор.ЭтоГруппа.
    • В поле Значение укажем Ложь. Это означает, что мы хотим видеть только те записи, у которых свойство ЭтоГруппа равно Ложь, то есть только элементы, а не группы.

    Нажимаем ОК для сохранения изменений.

После этих настроек, при открытии списка выбора для Реквизита.2, система будет применять два условия отбора одновременно:

  1. Показывать только те записи, у которых реквизит Родитель совпадает со значением из Реквизита.1 (динамический отбор).
  2. Показывать только те записи, у которых свойство ЭтоГруппа равно Ложь (фиксированный отбор, исключающий группы).

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

Резюме настроек для реквизита формы (Поле ввода)

Давайте еще раз посмотрим, как будут выглядеть свойства элемента управления (поля ввода) для Реквизита.2 в конфигураторе:

Свойства элемента формы (например, ПолеВводаРеквизит2):

Дополнительные возможности: Программный подход к отборам

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

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

Пример программного открытия формы выбора с отбором:


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

    // Получаем ссылку на группу из Реквизита.1
    СсылкаНаГруппуИзРеквизита1 = ЭлементыФормы.ТабличнаяЧасть.ТекущиеДанные.Реквизит1; // Пример для табличной части

    // Создаем структуру параметров отбора
    СтруктураОтбора = Новый Структура;
    // Устанавливаем отбор по родителю
    СтруктураОтбора.Вставить("Родитель", СсылкаНаГруппуИзРеквизита1);
    // Устанавливаем отбор, чтобы показывались только элементы (не группы)
    СтруктураОтбора.Вставить("ЭтоГруппа", Ложь);

    // Можно также указать, что отборы используются
    // Для более детальной настройки можно использовать коллекцию Отбор,
    // например, в ПараметрыОткрытия.Отбор.Родитель.Установить(...)

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

В этом примере мы создаем структуру СтруктураОтбора, где указываем значения для Родитель и ЭтоГруппа. Затем мы передаем эту структуру в метод ОткрытьФорму(). Механизм ОткрытьФорму() сам интерпретирует эту структуру как параметры отбора для динамического списка формы выбора справочника.

Если нам нужно более тонкое управление каждым отбором (например, точно указать вид сравнения, использование, или необходимость исключить), можно использовать коллекцию Отбор в ПараметрыОткрытия:


// Создаем коллекцию отборов
ОтборДляФормы = Новый Отбор;

// Добавляем отбор по родителю
ЭлементОтбораРодитель = ОтборДляФормы.Элементы.Добавить(Тип("ЭлементОтбора"));
ЭлементОтбораРодитель.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Родитель");
ЭлементОтбораРодитель.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбораРодитель.ПравоеЗначение = СсылкаНаГруппуИзРеквизита1;
ЭлементОтбораРодитель.Использование = Истина;

// Добавляем отбор по ЭтоГруппа
ЭлементОтбораЭтоГруппа = ОтборДляФормы.Элементы.Добавить(Тип("ЭлементОтбора"));
ЭлементОтбораЭтоГруппа.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ЭтоГруппа");
ЭлементОтбораЭтоГруппа.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбораЭтоГруппа.ПравоеЗначение = Ложь;
ЭлементОтбораЭтоГруппа.Использование = Истина;

// Передаем коллекцию отборов в параметры открытия формы
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("Отбор", ОтборДляФормы);

ОткрытьФорму("Справочник.Справочник2.ФормаВыбора", ПараметрыОткрытия, Элемент);

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

Заключение

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

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

← На главную