Как ограничить редактирование реквизита на форме в 1С:Enterprise для обычных пользователей?

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

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

В этой статье мы подробно разберем ситуацию, проанализируем различные подходы и выберем наиболее оптимальные, безопасные и современные варианты решения этой задачи с точки зрения стандартов разработки «1С».

Метод 1. Ограничение доступности программно в модуле формы

Это самый простой и быстрый способ, который часто применяется на практике. Идея заключается в том, чтобы при создании формы программно проверить, обладает ли текущий пользователь правами администратора (или специализированной ролью), и в зависимости от этого заблокировать элемент управления на форме.

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


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

Важный нюанс юзабилити (UX): Обратите внимание, что вместо свойства Доступность = Ложь мы используем ТолькоПросмотр = Истина. Выясним причину этого выбора:

  1. При установке свойства Доступность = Ложь элемент формы становится блеклым и серым, текст в нем трудно читается, его невозможно выделить или скопировать. Это ухудшает удобство работы пользователей с интерфейсом.
  2. Свойство ТолькоПросмотр = Истина сохраняет элемент ярким и читаемым. Пользователь может беспрепятственно выделить текст (например, скопировать артикул или уникальный идентификатор) и проанализировать его, но физически изменить данные на форме он не сможет.

Метод 2. Использование типового механизма БСП «Запрет редактирования реквизитов объектов»

Если вы работаете в современной конфигурации, разработанной на базе Библиотеки стандартных подсистем (БСП) (например, 1С:ERP, Комплексная автоматизация, Управление торговлей или Бухгалтерия предприятия), писать код «на коленке» не требуется. В БСП заложен готовый, красивый и стандартизированный функционал.

Разберем по шагам, как внедрить это решение:

Шаг 1. Настройка в модуле менеджера объекта. Откроем модуль менеджера нашего документа или справочника и найдем (или создадим) экспортную функцию ПолучитьБлокируемыеРеквизитыОбъекта(). Добавим туда наш реквизит:


Функция ПолучитьБлокируемыеРеквизитыОбъекта() Экспорт
    
    БлокируемыеРеквизиты = Новый Массив;
    БлокируемыеРеквизиты.Добавить("ИмяРеквизита");
    
    Возврат БлокируемыеРеквизиты;
    
КонецФункции

Шаг 2. Настройка в модуле формы. В модуле формы в обработчиках событий ПриСозданииНаСервере и ПослеЗаписиНаСервере вызовем стандартный метод БСП:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Блокируем реквизиты формы средствами БСП
    ЗапретРедактированияРеквизитовОбъектов.ЗаблокироватьРеквизиты(ЭтотОбъект);
    
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
    
    // Повторно инициализируем блокировку после записи документа
    ЗапретРедактированияРеквизитовОбъектов.ЗаблокироватьРеквизиты(ЭтотОбъект);
    
КонецПроцедуры

При таком подходе обычные пользователи увидят заблокированное поле. Администраторы же или пользователи со специальной ролью «Редактирование реквизитов объектов» увидят в меню «Еще» удобную кнопку «Разрешить редактирование реквизитов». При ее нажатии БСП предупредит о последствиях изменения ключевых данных и разблокирует поле для редактирования.

Метод 3. Разграничение прав на уровне реквизита в Конфигураторе

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

Рассмотрим, как это настроить в конфигураторе:

  1. Перейдем в дерево метаданных и найдем интересующую нас роль (например, роль для обычных пользователей).
  2. В окне настройки роли найдем наш документ или справочник.
  3. Развернем дерево подчиненных объектов до списка Реквизиты.
  4. Найдем наш конкретный реквизит.
  5. Снимем флажок с права «Редактирование», оставив флажок на праве «Просмотр».
  6. Для роли администратора (или Полных прав) убедимся, что оба флажка активны.

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

Метод 4. Обеспечение безопасности на уровне базы данных (Модуль объекта)

Рассмотрим важнейший нюанс безопасности, который часто упускают из виду начинающие разработчики. Ограничение доступности реквизита на форме защищает исключительно интерфейс, но не сами данные в СУБД!

Продвинутый пользователь или внешний программист сможет обойти ограничения формы следующими путями:

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


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

При использовании БСП вместо вызова РольДоступна() безопаснее использовать метод общего модуля: УправлениеДоступом.ОбладаетРолью("ПолныеПрава").

Развенчание мифов: Функциональные опции и RLS

Проанализируем некоторые заблуждения, высказанные участниками обсуждения:

Миф 1. Использование RLS для одного реквизита. Механизм RLS (Row-Level Security) предназначен для ограничения доступа к целым строкам таблиц БД по определенным условиям (например, по организациям или контрагентам). Использование RLS для ограничения одного поля в документе — избыточное решение, которое гарантированно приведет к падению производительности СУБД (особенно на крупных базах под управлением SQL Server).

Миф 2. Использование Функциональных опций (ФО) для ролей. Некоторые разработчики пытаются привязать Функциональные опции к текущему пользователю для управления элементами интерфейса. Это грубый антипаттерн (anti-pattern). Назначение функциональных опций — глобальное включение или отключение разделов учета (например, "Вести учет по характеристикам") на основе констант. Использование их для динамического разграничения прав пользователей создает неоправданную нагрузку на платформу, так как требует постоянного пересчета параметров ФО при сеансе каждого пользователя.

Резюме

Мы подробно разобрали задачу ограничения прав на редактирование реквизита. Лучшая практика разработки в системе «1С:Предприятие» диктует нам комплексный подход: используйте штатные настройки прав на реквизиты в ролях конфигуратора или механизмы БСП для удобного отображения в интерфейсе, а также обязательно внедряйте проверку в модуле объекта ПередЗаписью для обеспечения стопроцентной безопасности ваших данных.

← На главную