Как в управляемой форме списка документов реализации ограничить отбор по организации, чтобы пользователь мог выбирать только одну конкретную организацию?

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

При работе в системе 1С часто возникает необходимость контролировать данные, доступные пользователям. Одна из таких задач – ограничение видимости документов по конкретным организациям. Например, если пользователь относится к определенному филиалу или департаменту, ему может быть разрешен доступ только к документам, связанным с его организацией. В этой статье мы подробно рассмотрим, как реализовать такое ограничение в управляемой форме списка документов реализации, чтобы отбор по организации был недоступен, кроме одной, заранее определенной организации.

Мы разберем несколько подходов, каждый из которых имеет свои преимущества и области применения: программную установку отбора в динамическом списке, использование механизмов RLS (Row-Level Security) и фиксированный отбор, настраиваемый в конфигураторе.

1. Программная установка отбора в динамическом списке

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

Рассмотрим по шагам, как мы можем реализовать такой отбор.

Шаг 1: Определение места для установки отбора.

Наиболее подходящим местом для инициализации отбора является процедура ПриСозданииНаСервере формы. Эта процедура выполняется при создании формы на сервере, до того как форма будет передана клиенту и отображена пользователю. Это позволяет нам установить отбор до того, как пользователь сможет взаимодействовать с элементами формы.

Шаг 2: Получение нужной организации для отбора.

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

  1. Из параметров сеанса (ПараметрыСеанса.ОсновнаяОрганизацияПользователя, если таковой существует).
  2. Из настроек пользователя, хранящихся в регистре сведений.
  3. Из роли пользователя (например, если каждая роль соответствует определенной организации).
  4. Из реквизита формы, который заполняется при открытии.

Предположим, у нас есть некая функция ПолучитьТекущуюОрганизациюПользователя(), которая возвращает ссылку на нужную организацию.

Шаг 3: Добавление элемента отбора в динамический список.

Теперь, когда у нас есть целевая организация, мы можем добавить элемент отбора в коллекцию отборов динамического списка. Динамический список на форме – это реквизит формы, обычно имеющий имя Список (или другое, если вы его переименовали). У этого реквизита есть свойство Отбор, которое представляет собой коллекцию элементов отбора.

Мы будем работать с коллекцией Список.Отбор.Элементы. Для добавления нового отбора нам нужно создать объект типа ЭлементОтбораКомпоновкиДанных и настроить его свойства:

  1. ЛевоеЗначение: Указывает поле, по которому мы хотим отбирать данные. В нашем случае это будет Новый ПолеКомпоновкиДанных("Организация"), так как мы хотим отбирать по реквизиту "Организация" документов реализации.
  2. ВидСравнения: Определяет операцию сравнения. Для точного отбора по одной организации мы используем ВидСравненияКомпоновкиДанных.Равно.
  3. ПравоеЗначение: Это то значение, с которым будет сравниваться поле. В нашем случае это будет ссылка на конкретную организацию, которую мы получили на шаге 2.
  4. Использование: Флаг, который включает или отключает отбор. Мы устанавливаем его в Истина, чтобы отбор был активен.
  5. РежимОтображения: Очень важное свойство, которое позволяет нам управлять видимостью и доступностью элемента отбора для пользователя на форме. Чтобы пользователь не мог изменить или удалить наш фиксированный отбор, мы установим РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный.

Давайте посмотрим на пример кода, который объединяет эти шаги в процедуре ПриСозданииНаСервере:


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

// Пример реализации вспомогательной функции (может быть в общем модуле или на форме)
// Эта функция должна быть серверной, если вызывается в ПриСозданииНаСервере.
&НаСервере
Функция ПолучитьТекущуюОрганизациюПользователя()
    // Здесь должна быть ваша логика определения организации.
    // Например, если в параметрах сеанса хранится основная организация пользователя:
    // Возврат ПараметрыСеанса.ОсновнаяОрганизацияПользователя;
    
    // Или если вы жестко привязываете к конкретной организации для тестирования:
    Возврат Справочники.Организации.НайтиПоКоду("000000001"); // Пример: ищем по коду
    
    // Или, например, получаем из настроек пользователя
    // ...
КонецФункции

Таким образом, при открытии формы списка документов реализации, пользователи увидят только те документы, которые относятся к "их" организации, а элемент отбора по организации будет заблокирован для изменений.

2. Дополнительные возможности для программного отбора

Помимо прямого добавления элементов в коллекцию Список.Отбор.Элементы, существуют и другие методы, которые могут быть полезны при работе с отборами динамического списка.

2.1. Использование ПараметрыВыбора при открытии формы

Если вы открываете форму программно (например, с помощью метода ОткрытьФорму()), вы можете передать параметры отбора через структуру ПараметрыВыбора. Этот механизм предназначен для установки начальных значений отбора. Однако важно понимать его особенности:

Отбор, установленный таким образом, добавляется в фиксированные настройки компоновки данных. Если пользователь затем изменит этот отбор на форме (например, через "Настроить список"), а платформа попытается сохранить пользовательские настройки, может возникнуть конфликт или ошибка, так как фиксированный отбор может быть несовместим с измененными пользовательскими настройками. Чтобы избежать таких проблем, многие разработчики предпочитают устанавливать отбор напрямую через элементы динамического списка, как мы рассмотрели выше, или через пользовательские настройки, если требуется, чтобы пользователь мог их изменять.

2.2. Ограничение полей, доступных для отбора

Начиная с версии платформы 8.3.10, появилась полезная возможность запрещать пользователям создавать отборы по определенным полям. Это достигается с помощью метода УстановитьОграниченияИспользованияВОтборе() динамического списка. Этот метод позволяет указать, какие поля не должны быть доступны для использования в пользовательских отборах. Это может быть полезно для:

Пример использования этого метода также можно разместить в процедуре ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // ... (код для установки отбора по организации, как выше)

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

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

Используя ВидОграниченияИспользованияВОтборе.ЗапретитьИспользование, мы указываем поля, которые не должны появляться в списке доступных полей для отбора в пользовательских настройках. Если нужно разрешить только конкретный набор полей, а все остальные запретить, можно использовать ВидОграниченияИспользованияВОтборе.РазрешитьИспользование с соответствующим массивом полей.

2.3. Использование процедур БСП (Библиотеки Стандартных Подсистем)

Если ваша конфигурация использует Библиотеку Стандартных Подсистем (БСП), мы настоятельно рекомендуем использовать типовые функции и процедуры, предоставляемые БСП, для работы с отборами динамического списка. Эти функции обычно находятся в общих модулях, таких как ОбщегоНазначенияКлиентСервер или РаботаСДинамическимиСписками. Использование БСП-функций обеспечивает стандартизацию, упрощает поддержку и улучшает совместимость с будущими обновлениями платформы и конфигурации.

Например, в БСП может существовать функция, подобная УстановитьЭлементОтбораДинамическогоСписка. Её использование будет выглядеть примерно так:


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

Всегда стоит проверить документацию к вашей версии БСП, чтобы найти актуальные и рекомендованные методы для работы с динамическими списками.

3. Использование RLS (Row-Level Security) – Ограничение доступа на уровне записей

Для более комплексных и глобальных задач по ограничению доступа к данным, затрагивающих всю систему, а не только отдельную форму списка, мы можем рассмотреть механизм RLS (Row-Level Security), или ограничение доступа на уровне записей. Это мощный инструмент платформы 1С, который позволяет контролировать, какие записи объектов базы данных видит и к каким имеет доступ пользователь, основываясь на его ролях и заданных ограничениях.

3.1. Назначение RLS

Суть RLS заключается в том, что даже если пользователь имеет доступ к объекту метаданных (например, к документу "Реализация"), он увидит только те записи этого объекта, которые разрешены ему его ролью. Это происходит на уровне запросов к базе данных: платформа автоматически добавляет условия в запрос, формируемый для пользователя, основываясь на настройках RLS.

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

3.2. Применение RLS к организациям

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

3.3. Реализация RLS

Реализация RLS – это процесс, который выполняется в режиме конфигуратора и требует глубокого понимания механизма прав доступа. Давайте рассмотрим общие шаги:

  1. Создание или изменение роли: Мы начинаем с создания новой роли или модификации существующей, которой будет назначено ограничение.
  2. Настройка ограничений доступа к данным: В свойствах роли переходим на вкладку "Ограничения доступа к данным".
  3. Выбор объекта: Выбираем объект, для которого нужно установить ограничение (в нашем случае это будет Документ.Реализация).
  4. Задание шаблона ограничения: Для выбранного объекта указываем шаблон ограничения. Шаблон – это фактически текст запроса или выражение, которое будет использоваться платформой для фильтрации данных. Для ограничения по организации часто используются типовые шаблоны БСП, например, "ПоОрганизациям", или же пишется свой собственный шаблон.

    Пример шаблона для чтения данных документа по организации может выглядеть так:

    
    #Если &НаСервере Тогда
        Документ.Реализация ГДЕ Организация В (&Параметры.ОрганизацииДоступныеДляЧтения)
    #КонецЕсли
    

    В этом шаблоне &Параметры.ОрганизацииДоступныеДляЧтения – это параметр, который будет заполняться системой автоматически из настроек пользователя или его ролей. Для того чтобы это работало, необходимо настроить сопоставление параметра ограничения с правами пользователя, например, через регистры сведений "Дополнительные права пользователей" или аналогичные механизмы.

  5. Настройка ограничений на другие объекты: Важно помнить, что если вы ограничиваете документ по организации, то, скорее всего, вам также потребуется ограничить доступ к связанным справочникам (в этом поможет инструмент для анализа прав и ролей), регистрам и другим документам, чтобы обеспечить полную изоляцию данных.

3.4. Сложность RLS

Настройка RLS может быть достаточно сложной, особенно в нетиповых случаях или при наличии множества взаимосвязанных объектов и сложных иерархий доступа. Ошибки в RLS могут привести к непреднамеренному раскрытию данных или, наоборот, к полной блокировке доступа для пользователей. Фирма "1С" предоставляет подробные рекомендации по организации ролей и использованию RLS в Библиотеке Стандартных Подсистем, которые мы советуем изучить.

3.5. Расширения для RLS

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

4. Фиксированный отбор в конфигураторе

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

4.1. Что такое фиксированный отбор?

Фиксированный отбор – это отбор для динамического списка, который настраивается один раз в конфигураторе и после этого становится недоступным для редактирования пользователем средствами платформы. Управление такими настройками осуществляется исключительно программно или на этапе разработки.

4.2. Когда использовать фиксированный отбор?

Этот метод подходит, если:

4.3. Как настроить фиксированный отбор в конфигураторе?

  1. Откроем конфигуратор и найдем нужную форму списка документа (например, Документ.Реализация.ФормаСписка).
  2. На форме найдем реквизит динамического списка (обычно Список) и выделим его.
  3. В окне свойств реквизита списка перейдем на вкладку "Настройки компоновки данных".
  4. Развернем раздел "Отбор".
  5. Добавим новый элемент отбора. В качестве поля укажем "Организация".
  6. Вид сравнения установим "Равно".
  7. В качестве значения укажем ссылку на конкретную организацию, которую мы хотим фиксировать. Мы можем выбрать её из справочника.
  8. Самое важное: для этого элемента отбора установим флаг "Фиксированный". Это сделает отбор неизменяемым для пользователя в режиме предприятия.

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

Заключение

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

  1. Программная установка отбора в динамическом списке (в ПриСозданииНаСервере) является наиболее гибким решением. Она позволяет динамически определять организацию для отбора (например, по роли пользователя) и делать элемент отбора недоступным для изменения. Это рекомендуемый подход для большинства сценариев.
  2. RLS (Row-Level Security) обеспечивает самый высокий уровень контроля на уровне всей системы, ограничивая доступ к данным по организации везде, а не только на одной форме. Это решение для глобальных политик безопасности, но оно более сложное в реализации и поддержке.
  3. Фиксированный отбор в конфигураторе – это самый простой способ, но наименее гибкий, поскольку организация для отбора задается жестко и одинакова для всех пользователей. Подходит для универсальных, неизменяемых правил.

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

← На главную