При разработке конфигураций в 1С:Предприятие часто возникает необходимость создания иерархических структур. Стандартный иерархический справочник является мощным и удобным инструментом для этих целей, однако бывают ситуации, когда его использование неоптимально или невозможно. Например, если иерархия представляет собой список отчетов со строками, которые сами являются группами и элементами, и эта структура больше напоминает не справочник, а скорее аналитический разрез или данные, хранящиеся в регистрах. В таких случаях программисты ищут альтернативные подходы для реализации иерархии, а также сталкиваются с задачами по программной настройке визуального представления данных и управлению элементами формы.
В этой статье мы подробно рассмотрим, как можно создать иерархическую структуру в 1С, когда стандартные справочники не подходят, сфокусируемся на программной настройке динамического списка в виде дерева и на решении распространенной задачи по управлению курсором и текущей строкой в табличных частях.
Когда вы задумываетесь о хранении иерархических данных, но стандартный иерархический справочник кажется не совсем подходящим, вы, вероятно, ищете более гибкое решение. Одним из таких решений может быть использование Регистров сведений. Регистры сведений позволяют хранить данные в 'плоской' таблице, но при правильной организации измерений можно создать структуру, которая программно будет интерпретироваться как иерархическая.
Для реализации иерархии в регистре сведений, как правило, добавляются измерения типа "Родитель" и "Элемент", где "Родитель" ссылается на "Элемент". Однако при таком подходе возникает необходимость программно реализовывать всю логику построения дерева, контроля циклических ссылок и обеспечения целостности данных. Это может быть трудоемко и не всегда оптимально для сложных иерархий, требующих частых изменений или высокопроизводительного обхода.
Другие подходы включают использование реквизитов ссылки на себя в других объектах, временные таблицы или запросы с рекурсивным обходом для динамического построения иерархии. Выбор метода зависит от специфики вашей задачи, объема данных, частоты их изменений и требований к производительности. В нашем случае, автор темы изначально рассматривал регистр сведений, но затем столкнулся с более насущными задачами по визуализации данных и управлению формой, что является очень частой ситуацией в разработке.
Одной из наиболее востребованных задач является программная настройка отображения данных на форме, особенно когда требуется представить плоские данные в иерархическом виде. Рассмотрим ситуацию, когда у нас есть Динамический список, основанный, например, на запросе к регистру сведений или таблице, которая содержит поля "Ссылка" и "Родитель", позволяющие построить иерархию. Мы хотим отобразить этот динамический список в виде дерева прямо на форме — для этого подойдёт конструктор адаптивных интерфейсов и динамических списков в 1С.
Для этого нам необходимо программно управлять свойствами элемента формы типа "Таблица", который используется для отображения динамического списка. Автор темы столкнулся с проблемой, пытаясь установить свойства Отображение и ВыборГруппИЭлементов.
Чтобы превратить наш динамический список в иерархическое дерево, мы должны установить свойство Отображение элемента формы. Автору изначально не хватало правильного значения для этого свойства.
Правильное значение для свойства Отображение, чтобы список отображался в виде дерева, это ОтображениеТаблицы.Дерево. Давайте посмотрим, как это выглядит в коде:
Элементы.Дерево.Отображение = ОтображениеТаблицы.Дерево;
Здесь Элементы.Дерево — это ссылка на ваш элемент формы типа "Таблица" (или другой элемент, который отображает динамический список и имеет соответствующее имя). Установка этого свойства сообщает системе, что данные, привязанные к этому элементу формы, должны быть визуализированы как дерево, а не как плоский список.
Следующий шаг — это определение того, что пользователь может выбирать в этом иерархическом списке: только группы, только элементы или и группы, и элементы вместе. За это отвечает свойство ВыборГруппИЭлементов.
Автор темы также столкнулся с вопросом, какое значение присвоить этому свойству. Правильное значение зависит от вашей бизнес-логики:
ВыборГруппИЭлементов.Группы.ВыборГруппИЭлементов.Элементы.ВыборГруппИЭлементов.ГруппыИЭлементы.В контексте обсуждения, где автор указывал, что "Должно быть Группы", код будет выглядеть следующим образом:
Элементы.Дерево.ВыборГруппИЭлементов = ВыборГруппИЭлементов.Группы;
Таким образом, комбинируя эти два свойства, мы можем полностью настроить внешний вид и поведение нашего динамического списка для отображения иерархической структуры.
Помимо этих ключевых свойств, автор также настраивал другие параметры отображения командной панели, строки поиска и состояния просмотра, что является хорошей практикой для создания чистого и функционального интерфейса:
Элементы.Дерево.ПоложениеКоманднойПанели = ПоложениеКоманднойПанелиЭлементаФормы.Нет;
Элементы.Дерево.ПоложениеСтрокиПоиска = ПоложениеСтрокиПоиска.Нет;
Элементы.Дерево.ПоложениеСостоянияПросмотра = ПоложениеСостоянияПросмотра.Нет;
Элементы.Дерево.ПоложениеУправленияПоиском = ПоложениеУправленияПоиском.Нет;
Эти настройки позволяют убрать стандартные элементы управления, если они не нужны, и предоставить пользователю максимально лаконичный вид.
Для того чтобы динамический список действительно отображался как дерево, недостаточно просто установить свойства элемента формы. Необходимо, чтобы запрос динамического списка содержал поля, которые позволяют системе 1С построить эту иерархию. Как правило, это означает, что ваш запрос должен возвращать как минимум два поля: одно, представляющее сам элемент (например, Ссылка или Идентификатор), и другое, представляющее его родителя (например, Родитель или ИдентификаторРодителя). Эти поля должны быть правильно указаны в свойствах динамического списка (на вкладке "Настройка списка" в редакторе динамического списка).
Еще одна распространенная задача, с которой сталкиваются разработчики, — это программное управление положением курсора или выделением определенной строки в табличной части формы. Например, после заполнения табличной части данными мы можем захотеть установить курсор на первую строку или на строку, соответствующую определенным критериям.
Автор темы столкнулся с проблемой при попытке установить курсор на первую строку табличной части после ее заполнения. Он пробовал несколько подходов, включая использование свойства ТекущийЭлемент и метода ОтборСтрок, но столкнулся с ошибкой.
Автор предпринял попытку установить курсор на первую строку, используя следующий код:
ЭтотОбъект.ТекущийЭлемент = ЭтотОбъект.Элементы.таблицаСоставСтруктуры;
ПараметрыОтбора=Новый Структура;
ПараметрыОтбора.Вставить("НомерСтроки", 1);
МассивЗначений = Элементы.таблицаСоставСтруктуры.ОтборСтрок(ПараметрыОтбора); // Здесь возникла ошибка
Элементы.таблицаСоставСтруктуры.ТекущаяЗапись=МассивЗначений[0].ПолучитьИдентификатор;
Ошибка "Метод объекта не обнаружен (ОтборСтрок)" возникает потому, что метод ОтборСтрок доступен для табличной части объекта данных (например, ДокументОбъект.ТабличнаяЧасть.ОтборСтрок), но не для элемента формы типа "Таблица" (Элементы.таблицаСоставСтруктуры). Элемент формы — это визуальное представление, а не сами данные. Для работы с данными табличной части, отображаемой на форме, нам нужно обращаться к самому объекту данных.
Правильный подход заключается в следующем: сначала мы находим нужные строки в табличной части объекта данных, а затем используем полученные идентификаторы для установки текущей строки элемента формы. Автор самостоятельно нашел это решение.
Разберем решение по шагам:
Поиск строк в табличной части объекта данных. Для этого мы используем метод НайтиСтроки(), который применяется к самой табличной части объекта (например, Объект.ИмяТабличнойЧасти). Этот метод возвращает массив найденных строк.
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("НомерСтроки", 1); // Ищем строку с номером 1
МассивНайденныхСтрок = Объект.СоставСтруктуры.НайтиСтроки(ПараметрыОтбора);
Здесь Объект — это ссылка на ваш объект данных (например, документ или справочник), а СоставСтруктуры — имя вашей табличной части. Мы создаем структуру с параметрами отбора (в данном случае, по номеру строки) и передаем ее в метод НайтиСтроки().
Установка текущей строки элемента формы. После того как мы нашли нужные строки в объекте данных, мы можем получить идентификатор первой найденной строки и использовать его для установки свойства ТекущаяСтрока элемента формы.
Если МассивНайденныхСтрок.Количество() > 0 Тогда
Элементы.таблицаСоставСтруктуры.ТекущаяСтрока = МассивНайденныхСтрок[0].ПолучитьИдентификатор();
КонецЕсли;
Свойство ТекущаяСтрока элемента формы ожидает получить идентификатор строки, который можно получить с помощью метода ПолучитьИдентификатор() от найденной строки табличной части. Это позволит установить курсор или выделить нужную строку в визуальном представлении на форме.
Таким образом, полное и правильное решение для установки курсора на первую строку табличной части после ее заполнения будет выглядеть так:
// Предполагаем, что "Объект" - это ссылка на объект данных формы (например, ЭтотОбъект)
// и "СоставСтруктуры" - это имя табличной части объекта.
// "Элементы.таблицаСоставСтруктуры" - это элемент формы, отображающий табличную часть.
// 1. Заполнение табличной части (ваш код для заполнения)
// ...
// 2. Установка курсора на первую строку табличной части
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("НомерСтроки", 1); // Ищем строку с номером 1
МассивНайденныхСтрок = Объект.СоставСтруктуры.НайтиСтроки(ПараметрыОтбора);
Если МассивНайденныхСтрок.Количество() > 0 Тогда
Элементы.таблицаСоставСтруктуры.ТекущаяСтрока = МассивНайденныхСтрок[0].ПолучитьИдентификатор();
Иначе
// Если по какой-то причине строка не найдена (например, табличная часть пуста)
// можно установить текущую строку в Неопределено или обработать иначе
Элементы.таблицаСоставСтруктуры.ТекущаяСтрока = Неопределено;
КонецЕсли;
// Установка текущего элемента на саму таблицу, чтобы фокус был на ней
Элементы.таблицаСоставСтруктуры.УстановитьТекущийЭлемент();
Важно помнить, что НайтиСтроки() используется для поиска в объекте данных, а ТекущаяСтрока устанавливается для элемента формы, отображающего эти данные. Это фундаментальное различие между работой с данными и их визуальным представлением в управляемых формах 1С.
Реализация иерархических структур в 1С:Предприятие может выходить за рамки использования стандартных справочников. Мы рассмотрели, как можно программно настроить динамический список для отображения данных в виде дерева, используя свойства ОтображениеТаблицы.Дерево и ВыборГруппИЭлементов.Группы. Также мы разобрали распространенную проблему установки курсора на определенную строку табличной части, выяснив, почему метод ОтборСтрок вызывает ошибку применительно к элементам формы, и предложили корректное решение с использованием методов НайтиСтроки() для объекта данных и ТекущаяСтрока для элемента формы. Эти подходы позволяют более гибко управлять пользовательским интерфейсом и представлять данные в удобном для пользователя формате, расширяя стандартные возможности платформы 1С.
Всегда помните о разнице между данными объекта и их представлением на форме. Понимание этой концепции является ключом к успешной разработке сложных интерфейсов в 1С:Предприятие.