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