Как разрешить только добавление элементов справочника без права на их последующее изменение

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

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

Различие прав «Добавление» и «Изменение» в платформе 1С

Для начала проанализируем, как платформа 1С разделяет эти действия на уровне метаданных. В объекте «Роль» для каждого справочника предусмотрены два отдельных права:

  1. Добавление (Insert): это право проверяется платформой только один раз — в момент первой физической записи объекта в базу данных.
  2. Изменение (Update): это право проверяется при каждой попытке записи объекта, который уже существует в базе данных (у которого уже сформирована ссылка).

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

Способ 1. Использование механизма RLS (Record Level Security)

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

В настройках роли для нужного справочника выполним следующие действия:

  1. Установим право «Добавление» без ограничений.
  2. Для права «Изменение» добавим условие RLS.
  3. В тексте ограничения пропишем условие ГДЕ ЛОЖЬ.

Важный нюанс: Если мы просто напишем ГДЕ ЛОЖЬ на право изменения, пользователь сможет создать новый элемент, заполнить его и нажать «Записать». Однако, если он захочет внести правки в этот же элемент через секунду после записи (не закрывая формы), система выдаст ошибку нарушения прав доступа. Это происходит потому, что после первой записи объект перестал быть «новым» для платформы, и любая последующая запись требует права на «Изменение».

Способ 2. Программная проверка в модуле объекта (через расширение)

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

Разберем пример кода, который следует разместить в модуле объекта справочника в расширении:


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

В данном примере метод ЭтоНовый() возвращает Истина, пока объект еще не записан в базу. Как только запись произошла, при следующей попытке метод вернет Ложь, и сработает отказ в записи.

Способ 3. Управление доступностью формы (Интерактивный метод)

Иногда пользователю нужно дать возможность исправлять ошибки только до момента закрытия формы. В этом случае мы можем управлять доступностью элементов формы. Проанализируем, как это реализовать в модуле формы справочника.

Рассмотрим алгоритм в процедуре ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	// Если это не новый элемент, открываем форму только для просмотра
	Если ЗначениеЗаполнено(Объект.Ссылка) Тогда
		ТолькоПросмотр = Истина;
	КонецЕсли;
	
КонецПроцедуры

Однако этого может быть недостаточно, если пользователь нажмет «Записать», форма останется открытой, и он сможет продолжить редактирование. Чтобы запретить это, добавим обработчик события ПослеЗаписиНаСервере:


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

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

Способ 4. Ограничение по времени (Логика "Окно редактирования")

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

Для реализации этого метода нам потребуется реквизит ДатаСоздания. Проанализируем пример кода в модуле объекта:


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

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

Резюме и рекомендации

Подводя итоги нашего анализа, можно выделить следующие рекомендации в зависимости от ситуации:

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

← На главную