Как в 1С 7.7 открыть форму выбора иерархического справочника в нужной группе на основе других реквизитов?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При разработке интерфейсов в платформе 1С:Предприятие 7.7 часто возникает задача связать выбор значений из неподчиненных справочников. Типичный пример: на форме документа или элемента справочника уже заполнены реквизиты ТипОборудования (например, «Ноутбук») и Производитель (например, «ASUS»). При переходе к выбору модели или серии требуется сразу открыть справочник ТМЦ внутри конкретной папки, соответствующей выбранному типу и производителю, чтобы пользователю не приходилось вручную перемещаться по дереву групп.

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

Перехват события выбора значения

Для управления стандартным процессом выбора в модуле формы предусмотрена предопределенная процедура ПриНачалеВыбораЗначения. Проанализируем ее синтаксис и назначение:


Процедура ПриНачалеВыбораЗначения(ИдентЭлемДиалога, ФлагСтандОбр)
    // ИдентЭлемДиалога - строковый идентификатор элемента диалога формы
    // ФлагСтандОбр - флаг стандартной обработки (1 - выполнять, 0 - отменить)
КонецПроцедуры

Если присвоить параметру ФлагСтандОбр = 0, платформа отменит автоматическое открытие формы списка по умолчанию, что позволит выполнить собственный программный код: найти нужную группу, передать параметры и открыть форму выбора с установленным родителем.

Способ 1. Иерархический поиск группы и установка родителя

Рассмотрим по шагам реализацию поиска нужной группы без перебора всей базы данных. Если структура каталога ТМЦ имеет вид «Тип оборудования → Производитель → Модели», наиболее производительным решением является последовательный поиск по наименованию с ограничением родителем.

Разберем пример кода для модуля формы:


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

Способ 2. Обработка параметров в форме списка справочника

Посмотрим, как настроить принимающую сторону — модуль формы списка справочника ТМЦ, чтобы он автоматически отображал элементы внутри переданной папки.

В процедуре ПриОткрытии формы списка справочника анализируем системную переменную Форма.Параметр:


Процедура ПриОткрытии()
    
    // Проверяем переданный параметр
    Если ТипЗначенияСтр(Форма.Параметр) = "Справочник" Тогда
        Если (Форма.Параметр.Вид() = "ТМЦ") И (Форма.Параметр.Выбран() = 1) Тогда
            Если Форма.Параметр.ЭтоГруппа() = 1 Тогда
                // Устанавливаем текущего родителя для списка
                ИспользоватьРодителя(Форма.Параметр);
                ИерархическийСписок(1, 1);
            Иначе
                // Если передан элемент, позиционируемся на него
                АктивизироватьОбъект(Форма.Параметр);
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Разберем ключевые методы, используемые в обработчике:

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

Способ 3. Прямой перебор с проверкой условий

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

Для ускорения выборки по реквизитам следует использовать отбор по индексированным полям:


СпрТов = СоздатьОбъект("Справочник.ТМЦ");
// Если по реквизиту включен отбор в конфигураторе
СпрТов.ВыбратьЭлементыПоРеквизиту("Вид", ТипОборудования, 1, 0);

Пока СпрТов.ПолучитьЭлемент() = 1 Цикл
    Если (СпрТов.ЭтоГруппа() = 1) И (СокрЛП(СпрТов.Наименование) = СокрЛП(Производитель)) Тогда
        ЦелеваяГруппа = СпрТов.ТекущийЭлемент();
        Прервать;
    КонецЕсли;
КонецЦикла;

Рекомендации по проектированию структуры данных

Для надежной связи справочников рекомендуется придерживаться следующих правил:

  1. Использование прямых ссылок вместо текстовых наименований. Поиск по строковому представлению чувствителен к случайным опечаткам и пробелам. Надежнее добавить в справочник Производители реквизит типа Справочник.ТМЦ, в котором будет храниться ссылка на соответствующую группу каталога.
  2. Ограничение области поиска. При вызове метода НайтиПоНаименованию всегда указывайте третий параметр 1 (поиск только среди подчиненных установленному родителю), если предварительно задан ИспользоватьРодителя().
  3. Проверка заполненности. Всегда выполняйте проверку на пустое значение перед началом поиска и блокируйте выбор с понятным для пользователя предупреждением.
← На главную