При разработке мобильных рабочих мест или интерфейсов для планшетов на платформе «1С:Предприятие» разработчики часто сталкиваются с аппаратными ограничениями мобильных устройств. Одно из наиболее критичных — неудобство работы с древовидными структурами. Стандартные кнопки развертывания групп (так называемые «плюсики») на экранах планшетов выглядят слишком мелко, из-за чего пользователям сложно по ним попадать пальцем. Логичным решением кажется скрыть корневую родительскую папку, чтобы сразу показать ее содержимое на верхнем уровне списка. Давайте разберем, почему стандартные механизмы отборов здесь бессильны и как решить эту задачу правильно.
Попытки использовать условное оформление динамического списка для скрытия родительской папки (например, через установку параметра Видимость = Ложь) обычно приводят к двум проблемам: либо вместе с родителем исчезают все подчиненные элементы, либо структура дерева ломается. Проанализируем, почему так происходит.
Дело в том, что платформа 1С строит иерархическое дерево на клиенте динамически. Связь между родителем и потомком является жесткой. Если мы скрываем или отфильтровываем родительскую запись в запросе или через отборы динамического списка, платформа теряет связующее звено. В режиме отображения Дерево или Иерархический список система обязана отобразить всю цепочку родительских элементов до самого корня. Если родитель отфильтрован, подчиненные элементы просто «повисают в воздухе» и не выводятся на экран.
Для управляемых форм платформа предлагает элегантное штатное решение. У элемента формы типа Таблица, который отображает динамический список, есть стандартное свойство РодительВерхнегоУровня. Оно позволяет переопределить корень иерархии для отображения. При этом сама указанная папка скрывается, а все ее дочерние элементы и группы выводятся на самом верхнем уровне дерева, как будто они лежат в корне справочника.
Рассмотрим по шагам, как настроить это свойство программно. Лучше всего выполнять эту операцию на сервере при создании формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Находим ссылку на папку, которую нужно сделать виртуальным корнем
СсылкаНаРодителя = Справочники.Номенклатура.НайтиПоНаименованию("НашаПапка");
Если ЗначениеЗаполнено(СсылкаНаРодителя) Тогда
// Устанавливаем свойство родителя верхнего уровня для таблицы на форме
Элементы.Список.РодительВерхнегоУровня = СсылкаНаРодителя;
// Запрещаем пользователю переходить на уровень выше установленного родителя
Элементы.Список.ИзменятьТекущегоРодителя = Ложь;
КонецЕсли;
КонецПроцедуры
Благодаря этому коду папка «НашаПапка» полностью исчезнет из интерфейса, а пользователи на планшетах сразу увидят ее содержимое на первом уровне списка. Им больше не придется кликать по мелким элементам интерфейса для раскрытия группы.
Если пользователи работают исключительно на планшетах, то само использование дерева может быть нецелесообразным. Гораздо удобнее предоставить им плоский прокручиваемый список. Для этого мы можем перевести таблицу динамического списка в режим обычного списка и наложить правильные отборы.
Проанализируем настройку этого варианта:
Отображение в значение Список (вместо Дерево или Иерархический список).Посмотрим на пример кода, реализующий такую настройку:
&НаСервере
Процедура НастроитьПлоскийСписокДляПланшета()
СсылкаНаРодителя = Справочники.Номенклатура.НайтиПоНаименованию("НашаПапка");
Если Не ЗначениеЗаполнено(СсылкаНаРодителя) Тогда
Возврат;
КонецЕсли;
// Очищаем стандартные отборы для исключения конфликтов
Список.Отбор.Элементы.Очистить();
// Добавляем отбор по иерархии (выбираем все внутренние элементы)
ЭлементОтбораИерархия = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораИерархия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
ЭлементОтбораИерархия.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
ЭлементОтбораИерархия.ПравоеЗначение = СсылкаНаРодителя;
ЭлементОтбораИерархия.Использование = Истина;
// Исключаем саму родительскую папку, чтобы она не выводилась строкой в списке
ЭлементОтбораИсключение = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораИсключение.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
ЭлементОтбораИсключение.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
ЭлементОтбораИсключение.ПравоеЗначение = СсылкаНаРодителя;
ЭлементОтбораИсключение.Использование = Истина;
КонецПроцедуры
В результате мы получаем удобный плоский список товаров и подгрупп, который легко листается пальцем на планшете. Отсутствие мелких значков раскрытия групп значительно повышает юзабилити интерфейса в полевых условиях.
Бывают случаи, когда логика отображения слишком сложна для стандартного динамического списка. Например, требуется программно скрывать пустые папки на определенных уровнях или динамически менять иерархию в зависимости от сложных внешних условий. В таких ситуациях мы рекомендуем отказаться от динамического списка в пользу реквизита формы с типом ДеревоЗначений.
Выясним, как это реализовать по шагам:
ДеревоЗначений и выведем его в виде таблицы на форму.Разберем пример реализации заполнения дерева значений:
&НаСервере
Процедура ЗаполнитьДеревоЗначенийНаФорме()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Родитель КАК Родитель,
| Номенклатура.ЭтоГруппа КАК ЭтоГруппа,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка В ИЕРАРХИИ(&РодительскаяПапка)
| И Номенклатура.Ссылка <> &РодительскаяПапка";
Запрос.УстановитьПараметр("РодительскаяПапка", Справочники.Номенклатура.НайтиПоНаименованию("НашаПапка"));
РезультатЗапроса = Запрос.Выполнить();
// Выгружаем данные с обходом по иерархии
ДеревоОбъект = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
// Заполняем реквизит формы типа ДеревоЗначений
ЗначениеВРеквизитФормы(ДеревоОбъект, "ДеревоНоменклатуры");
КонецПроцедуры
Важно понимать: Использование дерева значений дает полную свободу в оформлении строк (можно сделать строки крупными, адаптированными под пальцы), но требует ручного обновления данных при их изменении в базе данных. При больших объемах данных справочника этот метод может вызывать задержки при первоначальном построении дерева на сервере, поэтому используйте его обдуманно.
Для выбора оптимального решения проанализируем сценарии использования нашей формы:
РодительВерхнегоУровня). Это самый надежный и быстрый способ в разработке.Дерева значений).