Как скрыть группы справочника в динамическом списке на мобильной платформе 1С?

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

При разработке мобильных приложений на платформе «1С:Предприятие» разработчики часто сталкиваются с задачей фильтрации данных в иерархических списках. Типичный сценарий: в справочнике Номенклатура есть реквизит ПоказыватьВМоб (типа Булево), определяющий, должен ли элемент или целая папка отображаться на мобильном устройстве. Нам необходимо сделать так, чтобы в динамическом списке, отображаемом в виде дерева, выводились только те элементы и группы, для которых этот реквизит имеет значение Истина.

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

Почему стандартное ограничение доступа (RLS) не работает на мобильном устройстве?

В настольной («десктопной») версии платформы «1С:Предприятие» подобную задачу легко решить с помощью механизма RLS (Record Level Security — ограничение доступа на уровне записей). Достаточно прописать простейшее условие для роли:

Номенклатура ГДЕ Номенклатура.ПоказыватьВМоб = ИСТИНА

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

Выясним причину этого поведения. Она кроется в архитектурных различиях платформ:

  1. Ограничение мобильной платформы: Механизм RLS полностью отсутствует в СУБД, используемой локально на мобильном устройстве (в мобильном приложении с файловой базой данных). Платформа «1С» на мобильном устройстве просто игнорирует правила RLS, прописанные в конфигурации.
  2. Мобильное приложение vs Мобильный клиент: Важно разделять эти две технологии. В Мобильном клиенте (который работает онлайн и обращается непосредственно к серверу «1С» на ПК) правила RLS будут успешно выполнены на стороне сервера. Но в автономном Мобильном приложении, работающем со своей локальной базой данных, RLS работать не будет.

Почему платформа «сопротивляется» скрытию пустых групп в иерархии?

Попытка наложить обычный отбор на динамический список (ДинамическийСписок) в режиме отображения «Дерево» сталкивается с системной логикой платформы «1С»:

Проанализируем четыре практических метода, которые помогут обойти эти ограничения.

Способ 1. Условное оформление («Видимость = Ложь») и его подводные камни

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

Рассмотрим по шагам, как это настраивается программно в модуле формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Создаем элемент условного оформления
    ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
    
    // Задаем оформление: Видимость = Ложь
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
    
    // Формируем условие: ПоказыватьВМоб = Ложь
    КомпоновочныйОтбор = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    КомпоновочныйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПоказыватьВМоб");
    КомпоновочныйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    КомпоновочныйОтбор.ПравоеЗначение = Ложь;
    
КонецПроцедуры

Важное предупреждение согласно стандартам разработки «1С» (ИТС):

Фирма «1С» настоятельно не рекомендует использовать свойство Видимость = Ложь в условном оформлении динамических списков для скрытия строк целиком. На мобильных устройствах этот подход имеет критические недостатки:

Способ 2. Режим «Список» с группировкой по Родителю (Рекомендуемый метод для ДС)

Чтобы обойти системное ограничение дерева и сохранить высокую производительность динамического списка, мы можем использовать альтернативный подход к визуализации иерархии. Мы переведем список в плоский режим, наложим полноценный жесткий отбор, а затем сгруппируем данные.

Разберем этот алгоритм по шагам:

  1. В свойствах таблицы формы, отображающей динамический список, установим свойство Отображение в значение Список (вместо «Дерево» или «Иерархический список»).
  2. Наложим стандартный отбор на динамический список. Поскольку список стал плоским, платформа без проблем полностью исключит все элементы и группы, у которых ПоказыватьВМоб = Ложь.
  3. Чтобы вернуть визуальную структуру папок, зайдем в настройки компоновки данных динамического списка (свойство НастройкиКомпоновкиДанных) и добавим Группировку по полю Родитель.

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

Способ 3. Фильтрация данных при синхронизации (Best Practice для мобильных)

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

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

Рассмотрим пример реализации фильтрации в модуле плана обмена при регистрации данных:


Процедура ОпределитьПолучателейИзменения(Данные, Получатели) Экспорт
    
    // Проверяем, что регистрируется Номенклатура (элемент или группа)
    Если ТипЗнч(Данные) = Тип("СправочникСсылка.Номенклатура") Тогда
        
        // Считываем значение признака отображения в мобильном
        ПоказыватьВМоб = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Данные, "ПоказыватьВМоб");
        
        Если Не ПоказыватьВМоб Тогда
            // Исключаем отправку этого объекта на мобильные устройства
            Получатели.Очистить();
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

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

Способ 4. Дерево значений на форме

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

Проанализируем пример кода, который выбирает нужную номенклатуру запросом и строит иерархическую структуру на форме:


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

Важное ограничение метода:

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

Резюме

Мы рассмотрели особенности работы с иерархическими списками на мобильной платформе «1С». Для достижения наилучшей производительности и корректности отображения интерфейса рекомендуется использовать Способ 3 (фильтрация данных на уровне синхронизации) в сочетании со Способом 2 (группировка по родителю в плоском списке). Это гарантирует быструю и стабильную работу вашего мобильного приложения.

← На главную