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