Как отобразить элементы справочника в форме списка по иерархии его реквизита

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

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

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

Метод 1. Использование вспомогательного иерархического справочника (Теневые таблицы)

Этот метод считается наиболее надежным для производительности системы и активно используется в крупных типовых решениях, таких как 1С:Документооборот (механизм «Адресная книга»). Суть заключается в создании специального справочника, который будет выступать «зеркалом» для отображения нужной нам структуры.

Алгоритм реализации:

  1. Создаем новый иерархический справочник (например, ВспомогательнаяИерархия).
  2. Добавляем в него реквизит ОбъектСсылкой (тип: ЛюбаяСсылка).
  3. Настраиваем подписки на события ПриЗаписи для Спр1 и Спр2.
  4. При записи элемента в Спр2 (группа или элемент) — создаем или обновляем соответствующий узел во вспомогательном справочнике.
  5. При записи элемента в Спр1 — создаем элемент во вспомогательном справочнике, указывая в качестве родителя узел, соответствующий значению реквизита Спр2.

Рассмотрим пример кода для подписки на событие, которая будет поддерживать актуальность нашей «теневой» структуры:


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

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

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

Минус метода: Избыточность данных и необходимость контролировать целостность ссылок при удалении или перемещении объектов.

Метод 2. Построение дерева значений (программная обработка)

Если объем данных невелик (до 2–3 тысяч записей), мы можем полностью отказаться от динамического списка в пользу элемента формы Таблица с типом ДеревоЗначений. Это даст нам абсолютную гибкость в визуализации.

Проанализируем процесс формирования такого дерева. Нам потребуется запрос, который соберет данные из обоих справочников и объединит их в иерархическую структуру на стороне клиента/сервера.


&НаСервере
Процедура СформироватьДеревоНаСервере()
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Спр2.Ссылка КАК Ссылка,
        |	Спр2.Родитель КАК Родитель,
        |	Спр2.Наименование КАК Наименование,
        |	ИСТИНА КАК ЭтоГруппа
        |ИЗ
        |	Справочник.Спр2 КАК Спр2
        |ОБЪЕДИНИТЬ ВСЕ
        |ВЫБРАТЬ
        |	Спр1.Ссылка,
        |	Спр1.Спр2,
        |	Спр1.Наименование,
        |	ЛОЖЬ
        |ИЗ
        |	Справочник.Спр1 КАК Спр1";
    
    РезультатЗапроса = Запрос.Выполнить();
    // Далее следует рекурсивный обход и заполнение ДереваЗначений на форме
    // ...
КонецПроцедуры

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

Метод 3. Виртуальная иерархия через UNION в динамическом списке

Этот способ позволяет «обмануть» систему, создав искусственное поле связи. Рассмотрим ситуацию: у нас есть элементы типа СправочникСсылка.Спр1 и СправочникСсылка.Спр2. Чтобы динамический список воспринял их как одну иерархию, мы приводим их к одному типу (например, строковому представлению UUID) внутри запроса.

Разберем по шагам:

  1. В запросе динамического списка объединяем таблицы Спр1 и Спр2.
  2. Создаем вычисляемое поле Идентификатор (строка из ссылки) и поле ИдентификаторРодителя.
  3. Для записей из Спр2 родителем будет его реальный родитель.
  4. Для записей из Спр1 родителем станет ссылка на Спр2 из его реквизита.

Однако помните, что стандартная настройка «Дерево» в динамическом списке требует наличия Основной таблицы. Если вы используете сложный запрос с UNION, платформа может запретить иерархический просмотр или значительно замедлить работу, так как не сможет эффективно строить индексы по вычисляемым полям.

Метод 4. Двухпанельный интерфейс (Компромиссное решение)

Если заказчик готов к небольшому изменению в UX (пользовательском опыте), мы рекомендуем использовать проверенную схему «Дерево навигации + Список элементов», как это сделано в подборе номенклатуры типовых конфигураций.

Как это настроить:

Этот вариант является самым «чистым» с точки зрения архитектуры 1С. Он не требует создания лишних объектов в базе данных (как в Методе 1) и не страдает от проблем с производительностью (как в Методах 2 и 3). При этом пользователь получает четкую структуру навигации.

Выводы и рекомендации

Выбор метода зависит от конкретных требований бизнеса. Если критически важно видеть всё в одном едином дереве и записей очень много — ваш путь лежит через Метод 1 (Теневые таблицы). Если же данных мало и нужна быстрая разработка — используйте Метод 2 (Дерево значений). Для типовых задач наиболее предпочтительным остается Метод 4, так как он минимизирует риски ошибок при обновлении конфигурации и сохраняет высокую отзывчивость интерфейса.

← На главную