Как ограничить редактирование документов по автору (ответственному) в 1С 8.3?

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

В типовых конфигурациях, таких как 1С:Бухгалтерия предприятия 3.0, часто возникает практическая бизнес-задача: с документом (например, «Перемещение товаров») работают кладовщики и менеджеры с разных складов. Требуется настроить права так, чтобы каждый пользователь мог создавать, изменять и перепроводить только свои документы, а чужие документы мог только просматривать. При этом администраторы или руководители отделов должны сохранять полный доступ ко всем документам независимо от автора.

Разберем, как правильно реализовать такое ограничение, проанализируем нюансы серверных проверок и рассмотрим готовые варианты кода.

Архитектурные требования и важные нюансы проверок

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

  1. Защита от подмены ответственного: если сравнивать только реквизит открытого объекта (Объект.Ответственный), пользователь может вручную поменять значение поля на себя и записать чужой документ. Для существующих объектов необходимо всегда сверять текущего пользователя со значением, записанным в базе данных — Объект.Ссылка.Ответственный.
  2. Исключение регламентных заданий и обменов: фоновые процессы, обмен данными и закрытие месяца могут аварийно завершиться, если сработает отказ в кодовой проверке. Обязательно проверяем признак Объект.ОбменДанными.Загрузка и запуск в привилегированном режиме.
  3. Отказ от явных имен пользователей в коде: нельзя прописывать логины («ИвановИИ», «ПетровАС») в программном коде. Правильный подход — использовать проверку ролей через РольДоступна() или вызывать методы БСП, например Пользователи.ЭтоПолноправныйПользователь().

Вариант 1. Универсальный серверный запрет через подписку на событие (рекомендуется)

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

Разберем по шагам создание механизма:

  1. Создаем общий серверный модуль (например, Свое_КонтрольДоступаСервер).
  2. Создаем объект метаданных Подписка на событие (например, Свое_ПередЗаписьюДокументовКонтрольОтветственного).
  3. В свойстве Источник выбираем составной тип из необходимых документов (например, ДокументОбъект.ПеремещениеТоваров).
  4. В свойстве Событие выбираем ПередЗаписью, а в качестве обработчика указываем экспортную процедуру из созданного общего модуля.

Посмотрим на пример процедуры обработчика:


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

Вариант 2. Интерфейсный запрет в форме документа

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

В расширении конфигурации перехватим событие формы ПриЧтенииНаСервере или пропишем код в модуле формы документа:


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    
    Если Не РольДоступна("ПолныеПрава") Тогда
        Если ЗначениеЗаполнено(Объект.Ответственный) И Объект.Ответственный <> ПараметрыСеанса.ТекущийПользователь Тогда
            ЭтаФорма.ТолькоПросмотр = Истина;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Свойство ЭтаФорма.ТолькоПросмотр = Истина блокирует интерактивное изменение полей, командной панели и табличных частей, предотвращая случайные попытки редактирования.

Вариант 3. Блокировка редактирования элементов справочников по роли

Проанализируем сопутствующую задачу: как запретить создание и редактирование элементов определенных справочников для конкретных пользователей, оставив им только чтение.

Разберем по шагам реализацию через отдельную роль:

  1. Создаем пустую роль с понятным наименованием, например ЗапретНаРедактированиеСправочника.
  2. Создаем подписку на событие ПриЗаписи для нужных справочников.
  3. В обработчике проверяем доступность роли у текущего сеанса:

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

Сочетание подписки на событие на сервере и установки режима ТолькоПросмотр на клиенте обеспечивает надежный контроль доступа к данным без утяжеления системы сложными механизмами RLS.

← На главную