Как программно развернуть верхние уровни иерархии в динамическом списке 1С

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

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

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

Анализируем проблему: почему нельзя просто использовать цикл?

Разберем ситуацию: у нас есть справочник (например, Номенклатура) с иерархией групп и элементов. На форме расположен динамический список. Мы хотим, чтобы при открытии формы все группы самого верхнего уровня (у которых нет родителя) были сразу развернуты.

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

Способ 1. Использование вспомогательного запроса и метода Развернуть

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

Шаг 1. Получение ссылок на верхнем уровне (на сервере)

Нам необходимо написать функцию, которая вернет массив ссылок элементов, у которых Родитель является пустой ссылкой. Это и будут наши «верхушки».


&НаСервере
Функция ПолучитьМассивВерхнихУзлов()
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Номенклатура.Ссылка КАК Ссылка
        |ИЗ
        |   Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |   Номенклатура.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
        |   И Номенклатура.ЭтоГруппа = ИСТИНА"; // Если нужно разворачивать только группы
    
    РезультатЗапроса = Запрос.Выполнить();
    Возврат РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Ссылка");
КонецФункции

Шаг 2. Развертывание строк на клиенте

Теперь, имея массив ссылок, мы должны вызвать метод Развернуть() для каждой строки. Важно помнить, что этот метод доступен только на клиенте и работает с расширением таблицы формы для динамического списка.


&НаКлиенте
Процедура РазвернутьВерхниеУзлы()
    МассивВерхушек = ПолучитьМассивВерхнихУзлов();
    
    Для Каждого ИдентификаторСтроки Из МассивВерхушек Цикл
        Элементы.Список.Развернуть(ИдентификаторСтроки);
    КонецЦикла;
КонецПроцедуры

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

Способ 2. Настройка «Начальное состояние дерева»

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

  1. Откройте форму в конфигураторе.
  2. Выберите элемент формы — таблицу, связанную с динамическим списком.
  3. В палитре свойств найдите раздел «Использование».
  4. Установите свойство Начальное состояние дерева в значение Раскрыть все уровни.

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

Способ 3. Оптимизация через предварительную загрузку данных

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

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

Например, мы можем установить отбор в динамическом списке, чтобы изначально показывались только элементы верхнего уровня, и добавить кнопку «Показать всё», которая будет менять параметры запроса или разворачивать дерево. Это сохранит «отзывчивость» интерфейса.

Сравнение динамического списка и дерева значений

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

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

Резюме по решению

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

  1. Выполняем запрос к основной таблице динамического списка с условием Родитель = ЗНАЧЕНИЕ(Справочник.ИмяСправочника.ПустаяСсылка).
  2. Передаем полученный массив ссылок на клиент.
  3. В цикле вызываем Элементы.ИмяТаблицы.Развернуть(Ссылка).
  4. Для предотвращения избыточных срабатываний обработчиков событий (например, ПриАктивизацииСтроки), на время работы цикла можно использовать флаг-предохранитель.

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

← На главную