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

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

Работа с динамическими списками в 1С — одна из самых частых задач разработчика. Однако стандартные возможности настройки через конфигуратор не всегда позволяют реализовать гибкое поведение интерфейса, когда пользователю требуется изменить структуру отображения данных «на лету». Например, переключиться с простой иерархии справочника на сложную вложенность: Заказ -> Номенклатура -> Подгруппа. В этой статье мы подробно разберем, как реализовать такую логику программно, используя механизмы системы компоновки данных (СКД), которые лежат в основе динамического списка.

Понимание основ: Иерархия против Группировки

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

Динамический список — это объект, работающий через компоновщик настроек. Чтобы изменить структуру отображения, нам нужно манипулировать коллекцией Группировка. Если мы хотим, чтобы список выглядел как дерево, необходимо также убедиться, что у элемента формы (таблицы) свойство Отображение установлено в значение Иерархический список или Дерево.

Способ 1. Программное управление группировками через Компоновщик настроек

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

Разберем пример кода, который очищает текущие группировки и устанавливает новую группировку по полю Заказ:


// 1. Очищаем старые группировки
Список.КомпоновщикНастроек.Настройки.Группировка.Элементы.Очистить();

// 2. Создаем новый элемент группировки
НоваяГруппировка = Список.КомпоновщикНастроек.Настройки.Группировка.Элементы.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
НоваяГруппировка.Использование = Истина;

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

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

После выполнения этого кода динамический список перестроится. Важно помнить: если вы хотите создать вложенную структуру (Заказ -> Номенклатура), вам нужно добавить еще один элемент группировки внутрь коллекции Элементы первой группировки.

Способ 2. Изменение текста запроса для поддержки иерархии

Иногда поле, по которому вы хотите выполнить группировку (например, Заказ), отсутствует в текущей выборке динамического списка. В этом случае группировка не сработает. Выясним причину: компоновщик не может найти поле, которое не определено в секции ВЫБРАТЬ запроса. Нам потребуется программно изменить текст запроса. Для расширения состава данных можно изучить руководство по методам добавления полей в динамические списки.

Посмотрим на пример, как изменить ТекстЗапроса динамического списка:


Текст = "ВЫБРАТЬ
       |    ОсновнаяТаблица.Ссылка,
       |    ОсновнаяТаблица.Наименование,
       |    ДокументЗаказ.Ссылка КАК Заказ
       |ИЗ
       |    Справочник.Номенклатура КАК ОсновнаяТаблица
       |    ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказПокупателя КАК ДокументЗаказ
       |    ПО ОсновнаяТаблица.Заказ = ДокументЗаказ.Ссылка";

Список.ТекстЗапроса = Текст;

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

Способ 3. Работа с выделенными строками

В процессе обсуждения часто возникает вопрос: как программно выделить строки после изменения структуры списка? Нужно учитывать специфику динамического списка: он подгружает данные порциями (ленивая загрузка). Если вы попытаетесь выделить объект, который еще не загружен в память клиента, метод Добавить() может не дать визуального результата.

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


// Создаем массив ссылок, которые нужно выделить
МассивСсылок = Новый Массив;
МассивСсылок.Add(НужнаяСсылка1);
МассивСсылок.Add(НужнаяСсылка2);

// Очищаем текущее выделение в элементе формы Таблица
Элементы.Список.ВыделенныеСтроки.Очистить();

// Добавляем ссылки в выделение
Для Каждого СсылкаИзМассива Из МассивСсылок Цикл
    Элементы.Список.ВыделенныеСтроки.Добавить(СсылкаИзМассива);
КонецЦикла;

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

Важные нюансы и ограничения

При программной настройке динамических списков следует учитывать несколько критических моментов:

  1. Режим отображения групп: Для того чтобы группировка выглядела эстетично, используйте параметр вывода ТипМакетаГруппировки. Установив его в значение Вертикальный, вы добьетесь классического древовидного вида.
  2. Пользовательские настройки: Если пользователь уже вручную настроил группировки через меню «Настроить список», ваши программные изменения в КомпоновщикНастроек.Настройки могут не примениться. Чтобы гарантированно переопределить настройки, работайте с Список.КомпоновщикНастроек.ПользовательскиеНастройки, находя нужные элементы по их идентификаторам.
  3. Разворачивание узлов: К сожалению, в платформе 1С для динамического списка (в отличие от ДереваЗначений) отсутствует прямой метод РазвернутьВсе(). Это связано с тем, что данные подгружаются динамически, и система «не знает» о содержимом вложенных групп, пока пользователь их не откроет.

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

← На главную