Как программно разрешить запись документа в 1С при отсутствии прав доступа в роли

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

В практике разработки на платформе 1С:Предприятие 8 (особенно на обычных формах) иногда возникают специфические задачи, когда необходимо предоставить пользователю возможность сохранить изменения в документе, несмотря на то, что в его роли право на Запись или Редактирование ограничено. Чаще всего такие задачи встречаются в рамках сложных систем разграничения прав или как проверочные задания на собеседованиях для оценки знания механизмов платформы.

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

Разбор механизмов блокировки прав

Прежде чем переходить к коду, разберем, как 1С ограничивает доступ. Существует два уровня блокировки:

  1. Интерфейсный уровень: Платформа видит отсутствие прав и делает форму недоступной для ввода. Кнопки «Записать» и «ОК» становятся неактивными или скрываются.
  2. Объектный уровень: При попытке вызвать метод Записать() ядро платформы проверяет права текущего пользователя. Если прав нет, генерируется исключение «Нарушение прав доступа».

Для решения задачи нам придется «обмануть» систему на обоих уровнях.

Шаг 1: Снятие интерфейсного ограничения

Рассмотрим, как сделать элементы формы доступными для редактирования, если форма открылась в режиме «Только чтение». По условию задачи нам запрещено менять свойства в конфигураторе, поэтому будем использовать обработчик ПриОткрытии.

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


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

Шаг 2: Использование привилегированного режима

Теперь разберем самую сложную часть — обход объектной проверки прав. Метод УстановитьПривилегированныйРежим(Истина) позволяет выполнять операции с данными без проверки прав доступа. Однако в обычном приложении (Толстый клиент) этот метод работает с нюансами: он эффективно отключает проверку прав только в коде, который выполняется на стороне сервера (в привилегированных общих модулях).

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


Процедура ДействиеЗаписатьИЗакрытьПринудительно(Кнопка)
    
    // Проверим, модифицирован ли объект в форме
    Если Не ЭтаФорма.Модифицированность Тогда
        ЭтаФорма.Закрыть();
        Возврат;
    КонецЕсли;

    // Вызываем запись через попытку, чтобы обработать возможные ошибки бизнес-логики
    Попытка
        ЗаписатьДокументБезПроверкиПрав(ЭтотОбъект);
        ЭтаФорма.Модифицированность = Ложь;
        ЭтаФорма.Закрыть();
    Исключение
        Сообщить("Ошибка при сохранении: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

Шаг 3: Реализация записи в модуле

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

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


Процедура ЗаписатьДокументБезПроверкиПрав(ДокОбъект)
    
    // Включаем режим, если платформа позволяет сделать это здесь
    УстановитьПривилегированныйРежим(Истина);
    
    // Использование ОбменДанными.Загрузка позволяет обойти часть проверок 
    // в подписках на события и процедурах "ПередЗаписью"
    ДокОбъект.ОбменДанными.Загрузка = Истина;
    
    // Прямая попытка записи объекта
    ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
    
    УстановитьПривилегированныйРежим(Ложь);
    
КонецПроцедуры

Важные нюансы и риски

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

Рассмотрим альтернативный вариант, если стандартная кнопка ОК намертво заблокирована платформой. Мы можем скрыть её и программно создать новую кнопку в той же панели действий:


// В процедуре ПриОткрытии
НоваяКнопка = ЭлементыФормы.ОсновныеДействияФормы.Кнопки.Добавить("МояКнопкаОК", ТипКнопкиКоманднойПанели.Действие, "ОК (принудительно)", Новый Действие("ДействиеЗаписатьИЗакрытьПринудительно"));
ЭлементыФормы.ОсновныеДействияФормы.Кнопки.ОК.Доступность = Ложь; // Пытаемся скрыть штатную

Подведем итог: решение задачи «записи без прав» в 1С требует комбинации методов манипуляции интерфейсом (ЭлементыФормы) и управления контекстом выполнения (УстановитьПривилегированныйРежим). Несмотря на техническую реализуемость, в реальных проектах лучше прислушаться к советам опытных разработчиков и пересмотреть архитектуру прав доступа, предоставив пользователю необходимые разрешения штатным способом через Роли.

← На главную