При работе в системе 1С часто возникает необходимость контролировать данные, доступные пользователям. Одна из таких задач – ограничение видимости документов по конкретным организациям. Например, если пользователь относится к определенному филиалу или департаменту, ему может быть разрешен доступ только к документам, связанным с его организацией. В этой статье мы подробно рассмотрим, как реализовать такое ограничение в управляемой форме списка документов реализации, чтобы отбор по организации был недоступен, кроме одной, заранее определенной организации.
Мы разберем несколько подходов, каждый из которых имеет свои преимущества и области применения: программную установку отбора в динамическом списке, использование механизмов RLS (Row-Level Security) и фиксированный отбор, настраиваемый в конфигураторе.
Один из наиболее гибких и часто используемых способов ограничения данных в управляемых формах – это программная установка отбора непосредственно в динамическом списке. Этот метод позволяет динамически устанавливать параметры отбора в зависимости от различных условий, таких как роль текущего пользователя, его персональные настройки или другие факторы.
Рассмотрим по шагам, как мы можем реализовать такой отбор.
Шаг 1: Определение места для установки отбора.
Наиболее подходящим местом для инициализации отбора является процедура ПриСозданииНаСервере формы. Эта процедура выполняется при создании формы на сервере, до того как форма будет передана клиенту и отображена пользователю. Это позволяет нам установить отбор до того, как пользователь сможет взаимодействовать с элементами формы.
Шаг 2: Получение нужной организации для отбора.
Прежде чем установить отбор, нам нужно определить, по какой именно организации мы собираемся фильтровать список. Это значение может быть получено из различных источников:
ПараметрыСеанса.ОсновнаяОрганизацияПользователя, если таковой существует).Предположим, у нас есть некая функция ПолучитьТекущуюОрганизациюПользователя(), которая возвращает ссылку на нужную организацию.
Шаг 3: Добавление элемента отбора в динамический список.
Теперь, когда у нас есть целевая организация, мы можем добавить элемент отбора в коллекцию отборов динамического списка. Динамический список на форме – это реквизит формы, обычно имеющий имя Список (или другое, если вы его переименовали). У этого реквизита есть свойство Отбор, которое представляет собой коллекцию элементов отбора.
Мы будем работать с коллекцией Список.Отбор.Элементы. Для добавления нового отбора нам нужно создать объект типа ЭлементОтбораКомпоновкиДанных и настроить его свойства:
ЛевоеЗначение: Указывает поле, по которому мы хотим отбирать данные. В нашем случае это будет Новый ПолеКомпоновкиДанных("Организация"), так как мы хотим отбирать по реквизиту "Организация" документов реализации.ВидСравнения: Определяет операцию сравнения. Для точного отбора по одной организации мы используем ВидСравненияКомпоновкиДанных.Равно.ПравоеЗначение: Это то значение, с которым будет сравниваться поле. В нашем случае это будет ссылка на конкретную организацию, которую мы получили на шаге 2.Использование: Флаг, который включает или отключает отбор. Мы устанавливаем его в Истина, чтобы отбор был активен.РежимОтображения: Очень важное свойство, которое позволяет нам управлять видимостью и доступностью элемента отбора для пользователя на форме. Чтобы пользователь не мог изменить или удалить наш фиксированный отбор, мы установим РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный.Давайте посмотрим на пример кода, который объединяет эти шаги в процедуре ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Шаг 2: Получаем ссылку на текущую организацию для отбора.
// Это может быть функция, которая определяет организацию
// в зависимости от текущего пользователя, его роли или других параметров.
ТекущаяОрганизация = ПолучитьТекущуюОрганизациюПользователя();
// Проверяем, удалось ли определить организацию
Если ТекущаяОрганизация <> Неопределено Тогда
// Шаг 3: Добавляем элемент отбора по организации
ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
// Устанавливаем ЛевоеЗначение - поле, по которому отбираем
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация"); // Имя поля в динамическом списке
// Устанавливаем ВидСравнения - "Равно" для точного совпадения
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
// Устанавливаем ПравоеЗначение - конкретная организация
ЭлементОтбора.ПравоеЗначение = ТекущаяОрганизация;
// Включаем отбор
ЭлементОтбора.Использование = Истина;
// Делаем элемент отбора недоступным для изменения пользователем на форме
// Это гарантирует, что пользователь не сможет снять или изменить данный отбор.
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецЕсли;
КонецПроцедуры
// Пример реализации вспомогательной функции (может быть в общем модуле или на форме)
// Эта функция должна быть серверной, если вызывается в ПриСозданииНаСервере.
&НаСервере
Функция ПолучитьТекущуюОрганизациюПользователя()
// Здесь должна быть ваша логика определения организации.
// Например, если в параметрах сеанса хранится основная организация пользователя:
// Возврат ПараметрыСеанса.ОсновнаяОрганизацияПользователя;
// Или если вы жестко привязываете к конкретной организации для тестирования:
Возврат Справочники.Организации.НайтиПоКоду("000000001"); // Пример: ищем по коду
// Или, например, получаем из настроек пользователя
// ...
КонецФункции
Таким образом, при открытии формы списка документов реализации, пользователи увидят только те документы, которые относятся к "их" организации, а элемент отбора по организации будет заблокирован для изменений.
Помимо прямого добавления элементов в коллекцию Список.Отбор.Элементы, существуют и другие методы, которые могут быть полезны при работе с отборами динамического списка.
Если вы открываете форму программно (например, с помощью метода ОткрытьФорму()), вы можете передать параметры отбора через структуру ПараметрыВыбора. Этот механизм предназначен для установки начальных значений отбора. Однако важно понимать его особенности:
Отбор, установленный таким образом, добавляется в фиксированные настройки компоновки данных. Если пользователь затем изменит этот отбор на форме (например, через "Настроить список"), а платформа попытается сохранить пользовательские настройки, может возникнуть конфликт или ошибка, так как фиксированный отбор может быть несовместим с измененными пользовательскими настройками. Чтобы избежать таких проблем, многие разработчики предпочитают устанавливать отбор напрямую через элементы динамического списка, как мы рассмотрели выше, или через пользовательские настройки, если требуется, чтобы пользователь мог их изменять.
Начиная с версии платформы 8.3.10, появилась полезная возможность запрещать пользователям создавать отборы по определенным полям. Это достигается с помощью метода УстановитьОграниченияИспользованияВОтборе() динамического списка. Этот метод позволяет указать, какие поля не должны быть доступны для использования в пользовательских отборах. Это может быть полезно для:
Пример использования этого метода также можно разместить в процедуре ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// ... (код для установки отбора по организации, как выше)
// Запрещаем пользователю создавать собственные отборы по полю "Контрагент"
// и по любому полю, содержащему "Комментарий"
Список.УстановитьОграниченияИспользованияВОтборе(
Новый Массив(
Новый ПолеКомпоновкиДанных("Контрагент"),
Новый ПолеКомпоновкиДанных("Комментарий")
),
ВидОграниченияИспользованияВОтборе.ЗапретитьИспользование
);
// Дополнительно можно разрешить только определенные поля, запретив остальные
// Список.УстановитьОграниченияИспользованияВОтборе(
// Новый Массив(
// Новый ПолеКомпоновкиДанных("Номер"),
// Новый ПолеКомпоновкиДанных("Дата"),
// Новый ПолеКомпоновкиДанных("Организация") // Эту можно оставить
// ),
// ВидОграниченияИспользованияВОтборе.РазрешитьИспользование
// );
КонецПроцедуры
Используя ВидОграниченияИспользованияВОтборе.ЗапретитьИспользование, мы указываем поля, которые не должны появляться в списке доступных полей для отбора в пользовательских настройках. Если нужно разрешить только конкретный набор полей, а все остальные запретить, можно использовать ВидОграниченияИспользованияВОтборе.РазрешитьИспользование с соответствующим массивом полей.
Если ваша конфигурация использует Библиотеку Стандартных Подсистем (БСП), мы настоятельно рекомендуем использовать типовые функции и процедуры, предоставляемые БСП, для работы с отборами динамического списка. Эти функции обычно находятся в общих модулях, таких как ОбщегоНазначенияКлиентСервер или РаботаСДинамическимиСписками. Использование БСП-функций обеспечивает стандартизацию, упрощает поддержку и улучшает совместимость с будущими обновлениями платформы и конфигурации.
Например, в БСП может существовать функция, подобная УстановитьЭлементОтбораДинамическогоСписка. Её использование будет выглядеть примерно так:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ТекущаяОрганизация = ПолучитьТекущуюОрганизациюПользователя();
Если ТекущаяОрганизация <> Неопределено Тогда
// Пример использования гипотетической функции БСП
// Имя общего модуля и функции могут отличаться в вашей конфигурации
МодульБСП.УстановитьЭлементОтбораДинамическогоСписка(
Список,
"Организация",
ТекущаяОрганизация,
ВидСравненияКомпоновкиДанных.Равно,
Истина, // Использование
РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный // Режим отображения
);
КонецЕсли;
КонецПроцедуры
Всегда стоит проверить документацию к вашей версии БСП, чтобы найти актуальные и рекомендованные методы для работы с динамическими списками.
Для более комплексных и глобальных задач по ограничению доступа к данным, затрагивающих всю систему, а не только отдельную форму списка, мы можем рассмотреть механизм RLS (Row-Level Security), или ограничение доступа на уровне записей. Это мощный инструмент платформы 1С, который позволяет контролировать, какие записи объектов базы данных видит и к каким имеет доступ пользователь, основываясь на его ролях и заданных ограничениях.
Суть RLS заключается в том, что даже если пользователь имеет доступ к объекту метаданных (например, к документу "Реализация"), он увидит только те записи этого объекта, которые разрешены ему его ролью. Это происходит на уровне запросов к базе данных: платформа автоматически добавляет условия в запрос, формируемый для пользователя, основываясь на настройках RLS.
В отличие от программной установки отбора в динамическом списке, которая действует только на конкретной форме, RLS является системным механизмом. Если пользователь попытается получить данные об организации через отчет, обработку или другую форму, RLS будет действовать повсеместно, гарантируя соблюдение правил доступа.
RLS очень часто используется для ограничения доступа к документам и справочникам по признаку "Организация". Это позволяет легко настроить систему таким образом, чтобы сотрудники могли просматривать и изменять информацию только по своей организации или по группе разрешенных для них организаций, скрывая данные других организаций.
Реализация RLS – это процесс, который выполняется в режиме конфигуратора и требует глубокого понимания механизма прав доступа. Давайте рассмотрим общие шаги:
Документ.Реализация).Пример шаблона для чтения данных документа по организации может выглядеть так:
#Если &НаСервере Тогда
Документ.Реализация ГДЕ Организация В (&Параметры.ОрганизацииДоступныеДляЧтения)
#КонецЕсли
В этом шаблоне &Параметры.ОрганизацииДоступныеДляЧтения – это параметр, который будет заполняться системой автоматически из настроек пользователя или его ролей. Для того чтобы это работало, необходимо настроить сопоставление параметра ограничения с правами пользователя, например, через регистры сведений "Дополнительные права пользователей" или аналогичные механизмы.
Настройка RLS может быть достаточно сложной, особенно в нетиповых случаях или при наличии множества взаимосвязанных объектов и сложных иерархий доступа. Ошибки в RLS могут привести к непреднамеренному раскрытию данных или, наоборот, к полной блокировке доступа для пользователей. Фирма "1С" предоставляет подробные рекомендации по организации ролей и использованию RLS в Библиотеке Стандартных Подсистем, которые мы советуем изучить.
В некоторых случаях, когда требуется внести изменения в типовой RLS, но конфигурация не должна сниматься с поддержки, мы можем использовать расширения конфигурации. Расширения позволяют корректировать или дополнять существующие ограничения RLS без изменения основной конфигурации, что значительно упрощает обновление.
Для самых простых и глобальных сценариев, когда требуется установить отбор, который будет действовать для всех пользователей системы и не подлежит изменению, мы можем использовать фиксированный отбор, настроенный непосредственно в конфигураторе.
Фиксированный отбор – это отбор для динамического списка, который настраивается один раз в конфигураторе и после этого становится недоступным для редактирования пользователем средствами платформы. Управление такими настройками осуществляется исключительно программно или на этапе разработки.
Этот метод подходит, если:
Документ.Реализация.ФормаСписка).Список) и выделим его.После сохранения конфигурации и обновления базы данных, этот отбор будет постоянно применяться к списку документов реализации, и пользователи не смогут его изменить или удалить. Такой подход является наиболее простым с точки зрения кода, но наименее гибким, поскольку организация для отбора жестко задается в конфигураторе.
Мы рассмотрели несколько эффективных методов для ограничения отбора по организации в управляемой форме списка документов реализации. Выбор конкретного подхода зависит от требований вашей задачи:
ПриСозданииНаСервере) является наиболее гибким решением. Она позволяет динамически определять организацию для отбора (например, по роли пользователя) и делать элемент отбора недоступным для изменения. Это рекомендуемый подход для большинства сценариев.Всегда анализируйте требования к безопасности и гибкости перед выбором метода. В большинстве случаев комбинация программного отбора на формах и правильно настроенного RLS обеспечивает наилучший баланс функциональности и безопасности.